From 966ce43331236e07968832c1e66c0ccee93364e3 Mon Sep 17 00:00:00 2001 From: timothypidashev Date: Thu, 15 Jul 2021 11:03:59 -0700 Subject: [PATCH] upload config --- venv/.vercel/README.txt | 11 + venv/.vercel/project.json | 1 + venv/__pycache__/index.cpython-38.pyc | Bin 531 -> 0 bytes venv/__pycache__/index.cpython-39.pyc | Bin 0 -> 1000 bytes venv/bin/activate | 18 +- venv/bin/activate.csh | 16 +- venv/bin/activate.fish | 37 +- venv/bin/easy_install | 2 +- .../{easy_install-3.8 => easy_install-3.9} | 2 +- venv/bin/flask | 8 + venv/bin/pip | 2 +- venv/bin/pip3 | 2 +- venv/bin/{pip3.8 => pip3.9} | 2 +- venv/bin/python3.9 | 1 + venv/index.py | 5 - .../__pycache__/easy_install.cpython-38.pyc | Bin 281 -> 0 bytes .../site-packages/pip-20.0.2.dist-info/RECORD | 246 -- .../pip/__pycache__/__main__.cpython-38.pyc | Bin 422 -> 0 bytes .../__pycache__/build_env.cpython-38.pyc | Bin 7483 -> 0 bytes .../__pycache__/cache.cpython-38.pyc | Bin 8700 -> 0 bytes .../__pycache__/configuration.cpython-38.pyc | Bin 10645 -> 0 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 12482 -> 0 bytes .../__pycache__/legacy_resolve.cpython-38.pyc | Bin 9898 -> 0 bytes .../__pycache__/locations.cpython-38.pyc | Bin 4492 -> 0 bytes .../_internal/__pycache__/main.cpython-38.pyc | Bin 615 -> 0 bytes .../__pycache__/pep425tags.cpython-38.pyc | Bin 3584 -> 0 bytes .../__pycache__/pyproject.cpython-38.pyc | Bin 3732 -> 0 bytes .../self_outdated_check.cpython-38.pyc | Bin 5493 -> 0 bytes .../__pycache__/wheel_builder.cpython-38.pyc | Bin 6699 -> 0 bytes .../cli/__pycache__/__init__.cpython-38.pyc | Bin 236 -> 0 bytes .../__pycache__/autocompletion.cpython-38.pyc | Bin 4953 -> 0 bytes .../__pycache__/base_command.cpython-38.pyc | Bin 5847 -> 0 bytes .../cli/__pycache__/cmdoptions.cpython-38.pyc | Bin 20328 -> 0 bytes .../command_context.cpython-38.pyc | Bin 1311 -> 0 bytes .../cli/__pycache__/main.cpython-38.pyc | Bin 1406 -> 0 bytes .../__pycache__/main_parser.cpython-38.pyc | Bin 2159 -> 0 bytes .../cli/__pycache__/parser.cpython-38.pyc | Bin 8977 -> 0 bytes .../__pycache__/req_command.cpython-38.pyc | Bin 8289 -> 0 bytes .../__pycache__/status_codes.cpython-38.pyc | Bin 365 -> 0 bytes .../commands/__pycache__/check.cpython-38.pyc | Bin 1312 -> 0 bytes .../__pycache__/completion.cpython-38.pyc | Bin 3013 -> 0 bytes .../__pycache__/configuration.cpython-38.pyc | Bin 6575 -> 0 bytes .../commands/__pycache__/debug.cpython-38.pyc | Bin 4089 -> 0 bytes .../__pycache__/download.cpython-38.pyc | Bin 3921 -> 0 bytes .../__pycache__/freeze.cpython-38.pyc | Bin 2929 -> 0 bytes .../commands/__pycache__/hash.cpython-38.pyc | Bin 1990 -> 0 bytes .../commands/__pycache__/help.cpython-38.pyc | Bin 1186 -> 0 bytes .../__pycache__/install.cpython-38.pyc | Bin 16661 -> 0 bytes .../commands/__pycache__/list.cpython-38.pyc | Bin 9042 -> 0 bytes .../__pycache__/search.cpython-38.pyc | Bin 4484 -> 0 bytes .../commands/__pycache__/show.cpython-38.pyc | Bin 6325 -> 0 bytes .../__pycache__/uninstall.cpython-38.pyc | Bin 2694 -> 0 bytes .../commands/__pycache__/wheel.cpython-38.pyc | Bin 5246 -> 0 bytes .../pip/_internal/commands/debug.py | 142 - .../pip/_internal/commands/download.py | 147 - .../pip/_internal/commands/wheel.py | 197 -- .../__pycache__/wheel.cpython-38.pyc | Bin 1560 -> 0 bytes .../index/__pycache__/__init__.cpython-38.pyc | Bin 190 -> 0 bytes .../__pycache__/collector.cpython-38.pyc | Bin 14156 -> 0 bytes .../__pycache__/package_finder.cpython-38.pyc | Bin 25749 -> 0 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 224 -> 0 bytes .../__pycache__/candidate.cpython-38.pyc | Bin 1421 -> 0 bytes .../__pycache__/format_control.cpython-38.pyc | Bin 2416 -> 0 bytes .../models/__pycache__/index.cpython-38.pyc | Bin 1146 -> 0 bytes .../models/__pycache__/link.cpython-38.pyc | Bin 6659 -> 0 bytes .../models/__pycache__/scheme.cpython-38.pyc | Bin 862 -> 0 bytes .../__pycache__/search_scope.cpython-38.pyc | Bin 3253 -> 0 bytes .../selection_prefs.cpython-38.pyc | Bin 1596 -> 0 bytes .../__pycache__/target_python.cpython-38.pyc | Bin 3219 -> 0 bytes .../models/__pycache__/wheel.cpython-38.pyc | Bin 3182 -> 0 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 212 -> 0 bytes .../network/__pycache__/auth.cpython-38.pyc | Bin 6978 -> 0 bytes .../network/__pycache__/cache.cpython-38.pyc | Bin 2691 -> 0 bytes .../__pycache__/download.cpython-38.pyc | Bin 4370 -> 0 bytes .../__pycache__/session.cpython-38.pyc | Bin 8851 -> 0 bytes .../network/__pycache__/utils.cpython-38.pyc | Bin 706 -> 0 bytes .../network/__pycache__/xmlrpc.cpython-38.pyc | Bin 1574 -> 0 bytes .../pip/_internal/network/utils.py | 48 - .../__pycache__/__init__.cpython-38.pyc | Bin 160 -> 0 bytes .../__pycache__/check.cpython-38.pyc | Bin 3656 -> 0 bytes .../__pycache__/freeze.cpython-38.pyc | Bin 5803 -> 0 bytes .../__pycache__/prepare.cpython-38.pyc | Bin 11162 -> 0 bytes .../build/__pycache__/__init__.cpython-38.pyc | Bin 166 -> 0 bytes .../build/__pycache__/metadata.cpython-38.pyc | Bin 1208 -> 0 bytes .../metadata_legacy.cpython-38.pyc | Bin 3268 -> 0 bytes .../build/__pycache__/wheel.cpython-38.pyc | Bin 1306 -> 0 bytes .../__pycache__/wheel_legacy.cpython-38.pyc | Bin 2567 -> 0 bytes .../operations/build/metadata_legacy.py | 122 - .../__pycache__/__init__.cpython-38.pyc | Bin 224 -> 0 bytes .../install/__pycache__/legacy.cpython-38.pyc | Bin 3048 -> 0 bytes .../install/__pycache__/wheel.cpython-38.pyc | Bin 14582 -> 0 bytes .../_internal/operations/install/legacy.py | 129 - .../pip/_internal/operations/install/wheel.py | 615 ---- .../pip/_internal/operations/prepare.py | 591 ---- .../req/__pycache__/__init__.cpython-38.pyc | Bin 2194 -> 0 bytes .../__pycache__/constructors.cpython-38.pyc | Bin 10363 -> 0 bytes .../req/__pycache__/req_file.cpython-38.pyc | Bin 12702 -> 0 bytes .../__pycache__/req_install.cpython-38.pyc | Bin 21338 -> 0 bytes .../req/__pycache__/req_set.cpython-38.pyc | Bin 6021 -> 0 bytes .../__pycache__/req_tracker.cpython-38.pyc | Bin 4041 -> 0 bytes .../__pycache__/req_uninstall.cpython-38.pyc | Bin 17427 -> 0 bytes .../utils/__pycache__/__init__.cpython-38.pyc | Bin 155 -> 0 bytes .../utils/__pycache__/appdirs.cpython-38.pyc | Bin 1351 -> 0 bytes .../utils/__pycache__/compat.cpython-38.pyc | Bin 6120 -> 0 bytes .../__pycache__/distutils_args.cpython-38.pyc | Bin 1139 -> 0 bytes .../utils/__pycache__/encoding.cpython-38.pyc | Bin 1247 -> 0 bytes .../__pycache__/filesystem.cpython-38.pyc | Bin 4035 -> 0 bytes .../__pycache__/filetypes.cpython-38.pyc | Bin 556 -> 0 bytes .../utils/__pycache__/hashes.cpython-38.pyc | Bin 4144 -> 0 bytes .../inject_securetransport.cpython-38.pyc | Bin 932 -> 0 bytes .../__pycache__/marker_files.cpython-38.pyc | Bin 928 -> 0 bytes .../utils/__pycache__/misc.cpython-38.pyc | Bin 23778 -> 0 bytes .../utils/__pycache__/models.cpython-38.pyc | Bin 1924 -> 0 bytes .../setuptools_build.cpython-38.pyc | Bin 2927 -> 0 bytes .../__pycache__/subprocess.cpython-38.pyc | Bin 5598 -> 0 bytes .../utils/__pycache__/temp_dir.cpython-38.pyc | Bin 6711 -> 0 bytes .../utils/__pycache__/ui.cpython-38.pyc | Bin 11802 -> 0 bytes .../__pycache__/unpacking.cpython-38.pyc | Bin 6075 -> 0 bytes .../utils/__pycache__/urls.cpython-38.pyc | Bin 1465 -> 0 bytes .../__pycache__/virtualenv.cpython-38.pyc | Bin 3280 -> 0 bytes .../pip/_internal/utils/marker_files.py | 25 - .../vcs/__pycache__/__init__.cpython-38.pyc | Bin 448 -> 0 bytes .../vcs/__pycache__/bazaar.cpython-38.pyc | Bin 3747 -> 0 bytes .../vcs/__pycache__/git.cpython-38.pyc | Bin 9559 -> 0 bytes .../vcs/__pycache__/mercurial.cpython-38.pyc | Bin 4888 -> 0 bytes .../vcs/__pycache__/subversion.cpython-38.pyc | Bin 8487 -> 0 bytes .../__pycache__/versioncontrol.cpython-38.pyc | Bin 19216 -> 0 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 3039 -> 0 bytes .../pkg_resources-0.0.0.dist-info/AUTHORS.txt | 562 --- .../__pycache__/py31compat.cpython-38.pyc | Bin 600 -> 0 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 157 -> 0 bytes .../__pycache__/__about__.cpython-38.pyc | Bin 707 -> 0 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 545 -> 0 bytes .../__pycache__/markers.cpython-38.pyc | Bin 8919 -> 0 bytes .../setuptools-44.0.0.dist-info/AUTHORS.txt | 562 --- .../__pycache__/__init__.cpython-38.pyc | Bin 7768 -> 0 bytes .../_deprecation_warning.cpython-38.pyc | Bin 516 -> 0 bytes .../__pycache__/glob.cpython-38.pyc | Bin 3733 -> 0 bytes .../__pycache__/installer.cpython-38.pyc | Bin 4102 -> 0 bytes .../__pycache__/package_index.cpython-38.pyc | Bin 32970 -> 0 bytes .../__pycache__/py31compat.cpython-38.pyc | Bin 1191 -> 0 bytes .../__pycache__/py34compat.cpython-38.pyc | Bin 450 -> 0 bytes .../__pycache__/sandbox.cpython-38.pyc | Bin 15536 -> 0 bytes .../__pycache__/site-patch.cpython-38.pyc | Bin 1474 -> 0 bytes .../__pycache__/ssl_support.cpython-38.pyc | Bin 6855 -> 0 bytes .../__pycache__/unicode_utils.cpython-38.pyc | Bin 1151 -> 0 bytes .../__pycache__/version.cpython-38.pyc | Bin 292 -> 0 bytes .../__pycache__/wheel.cpython-38.pyc | Bin 7383 -> 0 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 154 -> 0 bytes .../__pycache__/__about__.cpython-38.pyc | Bin 704 -> 0 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 542 -> 0 bytes .../__pycache__/markers.cpython-38.pyc | Bin 8927 -> 0 bytes .../packaging/__pycache__/tags.cpython-38.pyc | Bin 10811 -> 0 bytes .../__pycache__/utils.cpython-38.pyc | Bin 1435 -> 0 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 712 -> 0 bytes .../__pycache__/bdist_wininst.cpython-38.pyc | Bin 954 -> 0 bytes .../__pycache__/build_ext.cpython-38.pyc | Bin 9895 -> 0 bytes .../command/__pycache__/rotate.cpython-38.pyc | Bin 2520 -> 0 bytes .../command/__pycache__/sdist.cpython-38.pyc | Bin 7859 -> 0 bytes .../command/__pycache__/setopt.cpython-38.pyc | Bin 4537 -> 0 bytes .../Flask-2.0.1.dist-info}/INSTALLER | 0 .../Flask-2.0.1.dist-info/LICENSE.rst | 28 + .../Flask-2.0.1.dist-info/METADATA | 124 + .../Flask-2.0.1.dist-info/RECORD | 52 + .../Flask-2.0.1.dist-info/REQUESTED} | 0 .../site-packages/Flask-2.0.1.dist-info/WHEEL | 5 + .../Flask-2.0.1.dist-info/entry_points.txt | 3 + .../Flask-2.0.1.dist-info/top_level.txt | 1 + .../Jinja2-3.0.1.dist-info}/INSTALLER | 0 .../Jinja2-3.0.1.dist-info/LICENSE.rst | 28 + .../Jinja2-3.0.1.dist-info/METADATA | 112 + .../Jinja2-3.0.1.dist-info/RECORD | 58 + .../Jinja2-3.0.1.dist-info/WHEEL | 5 + .../Jinja2-3.0.1.dist-info/entry_points.txt | 3 + .../Jinja2-3.0.1.dist-info/top_level.txt | 1 + .../MarkupSafe-2.0.1.dist-info}/INSTALLER | 0 .../MarkupSafe-2.0.1.dist-info/LICENSE.rst | 28 + .../MarkupSafe-2.0.1.dist-info/METADATA | 100 + .../MarkupSafe-2.0.1.dist-info/RECORD | 14 + .../MarkupSafe-2.0.1.dist-info/WHEEL | 5 + .../MarkupSafe-2.0.1.dist-info/top_level.txt | 1 + .../Werkzeug-2.0.1.dist-info/INSTALLER} | 0 .../Werkzeug-2.0.1.dist-info/LICENSE.rst | 28 + .../Werkzeug-2.0.1.dist-info/METADATA | 128 + .../Werkzeug-2.0.1.dist-info/RECORD | 111 + .../Werkzeug-2.0.1.dist-info/WHEEL | 5 + .../Werkzeug-2.0.1.dist-info/top_level.txt | 1 + .../__pycache__/easy_install.cpython-39.pyc | Bin 0 -> 328 bytes .../click-8.0.1.dist-info/INSTALLER | 1 + .../click-8.0.1.dist-info/LICENSE.rst | 28 + .../click-8.0.1.dist-info/METADATA | 110 + .../click-8.0.1.dist-info/RECORD | 41 + .../site-packages/click-8.0.1.dist-info/WHEEL | 5 + .../click-8.0.1.dist-info/top_level.txt | 1 + .../python3.9/site-packages/click/__init__.py | 75 + .../click/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2706 bytes .../click/__pycache__/_compat.cpython-39.pyc | Bin 0 -> 16055 bytes .../__pycache__/_termui_impl.cpython-39.pyc | Bin 0 -> 15981 bytes .../__pycache__/_textwrap.cpython-39.pyc | Bin 0 -> 1548 bytes .../__pycache__/_unicodefun.cpython-39.pyc | Bin 0 -> 2343 bytes .../__pycache__/_winconsole.cpython-39.pyc | Bin 0 -> 7799 bytes .../click/__pycache__/core.cpython-39.pyc | Bin 0 -> 88348 bytes .../__pycache__/decorators.cpython-39.pyc | Bin 0 -> 14310 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 10147 bytes .../__pycache__/formatting.cpython-39.pyc | Bin 0 -> 9427 bytes .../click/__pycache__/globals.cpython-39.pyc | Bin 0 -> 2424 bytes .../click/__pycache__/parser.cpython-39.pyc | Bin 0 -> 13581 bytes .../shell_completion.cpython-39.pyc | Bin 0 -> 16660 bytes .../click/__pycache__/termui.cpython-39.pyc | Bin 0 -> 26540 bytes .../click/__pycache__/testing.cpython-39.pyc | Bin 0 -> 15131 bytes .../click/__pycache__/types.cpython-39.pyc | Bin 0 -> 32921 bytes .../click/__pycache__/utils.cpython-39.pyc | Bin 0 -> 17785 bytes .../python3.9/site-packages/click/_compat.py | 627 ++++ .../site-packages/click/_termui_impl.py | 717 ++++ .../site-packages/click/_textwrap.py | 49 + .../site-packages/click/_unicodefun.py | 100 + .../site-packages/click/_winconsole.py | 279 ++ .../lib/python3.9/site-packages/click/core.py | 2957 ++++++++++++++++ .../site-packages/click/decorators.py | 437 +++ .../site-packages/click/exceptions.py | 287 ++ .../site-packages/click/formatting.py | 301 ++ .../python3.9/site-packages/click/globals.py | 69 + .../python3.9/site-packages/click/parser.py | 529 +++ .../site-packages/click/py.typed} | 0 .../site-packages/click/shell_completion.py | 574 ++++ .../python3.9/site-packages/click/termui.py | 807 +++++ .../python3.9/site-packages/click/testing.py | 479 +++ .../python3.9/site-packages/click/types.py | 1052 ++++++ .../python3.9/site-packages/click/utils.py | 579 ++++ .../site-packages/easy_install.py | 0 .../python3.9/site-packages/flask/__init__.py | 46 + .../python3.9/site-packages/flask/__main__.py | 3 + .../flask/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1897 bytes .../flask/__pycache__/__main__.cpython-39.pyc | Bin 0 -> 228 bytes .../flask/__pycache__/app.cpython-39.pyc | Bin 0 -> 63588 bytes .../__pycache__/blueprints.cpython-39.pyc | Bin 0 -> 21752 bytes .../flask/__pycache__/cli.cpython-39.pyc | Bin 0 -> 27072 bytes .../flask/__pycache__/config.cpython-39.pyc | Bin 0 -> 11509 bytes .../flask/__pycache__/ctx.cpython-39.pyc | Bin 0 -> 15555 bytes .../__pycache__/debughelpers.cpython-39.pyc | Bin 0 -> 6473 bytes .../flask/__pycache__/globals.cpython-39.pyc | Bin 0 -> 1847 bytes .../flask/__pycache__/helpers.cpython-39.pyc | Bin 0 -> 27329 bytes .../flask/__pycache__/logging.cpython-39.pyc | Bin 0 -> 2464 bytes .../flask/__pycache__/scaffold.cpython-39.pyc | Bin 0 -> 24692 bytes .../flask/__pycache__/sessions.cpython-39.pyc | Bin 0 -> 13111 bytes .../flask/__pycache__/signals.cpython-39.pyc | Bin 0 -> 2378 bytes .../__pycache__/templating.cpython-39.pyc | Bin 0 -> 5565 bytes .../flask/__pycache__/testing.cpython-39.pyc | Bin 0 -> 9032 bytes .../flask/__pycache__/typing.cpython-39.pyc | Bin 0 -> 1312 bytes .../flask/__pycache__/views.cpython-39.pyc | Bin 0 -> 4922 bytes .../flask/__pycache__/wrappers.cpython-39.pyc | Bin 0 -> 5037 bytes venv/lib/python3.9/site-packages/flask/app.py | 2088 +++++++++++ .../site-packages/flask/blueprints.py | 603 ++++ venv/lib/python3.9/site-packages/flask/cli.py | 994 ++++++ .../python3.9/site-packages/flask/config.py | 291 ++ venv/lib/python3.9/site-packages/flask/ctx.py | 480 +++ .../site-packages/flask/debughelpers.py | 171 + .../python3.9/site-packages/flask/globals.py | 59 + .../python3.9/site-packages/flask/helpers.py | 836 +++++ .../site-packages/flask/json/__init__.py | 350 ++ .../json/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 11350 bytes .../flask/json/__pycache__/tag.cpython-39.pyc | Bin 0 -> 11479 bytes .../python3.9/site-packages/flask/json/tag.py | 312 ++ .../python3.9/site-packages/flask/logging.py | 74 + .../site-packages/flask/py.typed} | 0 .../python3.9/site-packages/flask/scaffold.py | 864 +++++ .../python3.9/site-packages/flask/sessions.py | 404 +++ .../python3.9/site-packages/flask/signals.py | 56 + .../site-packages/flask/templating.py | 165 + .../python3.9/site-packages/flask/testing.py | 280 ++ .../python3.9/site-packages/flask/typing.py | 46 + .../python3.9/site-packages/flask/views.py | 157 + .../python3.9/site-packages/flask/wrappers.py | 167 + .../itsdangerous-2.0.1.dist-info/INSTALLER | 1 + .../itsdangerous-2.0.1.dist-info/LICENSE.rst | 28 + .../itsdangerous-2.0.1.dist-info/METADATA | 96 + .../itsdangerous-2.0.1.dist-info/RECORD | 25 + .../itsdangerous-2.0.1.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../site-packages/itsdangerous/__init__.py | 22 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1023 bytes .../__pycache__/_json.cpython-39.pyc | Bin 0 -> 1557 bytes .../__pycache__/encoding.cpython-39.pyc | Bin 0 -> 1869 bytes .../__pycache__/exc.cpython-39.pyc | Bin 0 -> 3450 bytes .../__pycache__/jws.cpython-39.pyc | Bin 0 -> 7597 bytes .../__pycache__/serializer.cpython-39.pyc | Bin 0 -> 9752 bytes .../__pycache__/signer.cpython-39.pyc | Bin 0 -> 8449 bytes .../__pycache__/timed.cpython-39.pyc | Bin 0 -> 6370 bytes .../__pycache__/url_safe.cpython-39.pyc | Bin 0 -> 2718 bytes .../site-packages/itsdangerous/_json.py | 34 + .../site-packages/itsdangerous/encoding.py | 54 + .../site-packages/itsdangerous/exc.py | 107 + .../site-packages/itsdangerous/jws.py | 259 ++ .../site-packages/itsdangerous/py.typed} | 0 .../site-packages/itsdangerous/serializer.py | 295 ++ .../site-packages/itsdangerous/signer.py | 257 ++ .../site-packages/itsdangerous/timed.py | 227 ++ .../site-packages/itsdangerous/url_safe.py | 80 + .../site-packages/jinja2/__init__.py | 45 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1922 bytes .../__pycache__/_identifier.cpython-39.pyc | Bin 0 -> 1909 bytes .../__pycache__/async_utils.cpython-39.pyc | Bin 0 -> 2322 bytes .../jinja2/__pycache__/bccache.cpython-39.pyc | Bin 0 -> 13303 bytes .../__pycache__/compiler.cpython-39.pyc | Bin 0 -> 54199 bytes .../__pycache__/constants.cpython-39.pyc | Bin 0 -> 1553 bytes .../jinja2/__pycache__/debug.cpython-39.pyc | Bin 0 -> 5546 bytes .../__pycache__/defaults.cpython-39.pyc | Bin 0 -> 1353 bytes .../__pycache__/environment.cpython-39.pyc | Bin 0 -> 53459 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 5594 bytes .../jinja2/__pycache__/ext.cpython-39.pyc | Bin 0 -> 26360 bytes .../jinja2/__pycache__/filters.cpython-39.pyc | Bin 0 -> 49997 bytes .../__pycache__/idtracking.cpython-39.pyc | Bin 0 -> 11115 bytes .../jinja2/__pycache__/lexer.cpython-39.pyc | Bin 0 -> 20322 bytes .../jinja2/__pycache__/loaders.cpython-39.pyc | Bin 0 -> 20164 bytes .../jinja2/__pycache__/meta.cpython-39.pyc | Bin 0 -> 3811 bytes .../__pycache__/nativetypes.cpython-39.pyc | Bin 0 -> 4800 bytes .../jinja2/__pycache__/nodes.cpython-39.pyc | Bin 0 -> 40829 bytes .../__pycache__/optimizer.cpython-39.pyc | Bin 0 -> 1942 bytes .../jinja2/__pycache__/parser.cpython-39.pyc | Bin 0 -> 27602 bytes .../jinja2/__pycache__/runtime.cpython-39.pyc | Bin 0 -> 33123 bytes .../jinja2/__pycache__/sandbox.cpython-39.pyc | Bin 0 -> 11933 bytes .../jinja2/__pycache__/tests.cpython-39.pyc | Bin 0 -> 6585 bytes .../jinja2/__pycache__/utils.cpython-39.pyc | Bin 0 -> 27457 bytes .../jinja2/__pycache__/visitor.cpython-39.pyc | Bin 0 -> 3907 bytes .../site-packages/jinja2/_identifier.py | 6 + .../site-packages/jinja2/async_utils.py | 68 + .../python3.9/site-packages/jinja2/bccache.py | 364 ++ .../site-packages/jinja2/compiler.py | 1954 +++++++++++ .../site-packages/jinja2/constants.py | 20 + .../python3.9/site-packages/jinja2/debug.py | 279 ++ .../site-packages/jinja2/defaults.py | 48 + .../site-packages/jinja2/environment.py | 1674 +++++++++ .../site-packages/jinja2/exceptions.py | 166 + .../lib/python3.9/site-packages/jinja2/ext.py | 879 +++++ .../python3.9/site-packages/jinja2/filters.py | 1824 ++++++++++ .../site-packages/jinja2/idtracking.py | 318 ++ .../python3.9/site-packages/jinja2/lexer.py | 869 +++++ .../python3.9/site-packages/jinja2/loaders.py | 642 ++++ .../python3.9/site-packages/jinja2/meta.py | 111 + .../site-packages/jinja2/nativetypes.py | 118 + .../python3.9/site-packages/jinja2/nodes.py | 1205 +++++++ .../site-packages/jinja2/optimizer.py | 47 + .../python3.9/site-packages/jinja2/parser.py | 1040 ++++++ .../site-packages/jinja2/py.typed} | 0 .../python3.9/site-packages/jinja2/runtime.py | 1103 ++++++ .../python3.9/site-packages/jinja2/sandbox.py | 428 +++ .../python3.9/site-packages/jinja2/tests.py | 255 ++ .../python3.9/site-packages/jinja2/utils.py | 854 +++++ .../python3.9/site-packages/jinja2/visitor.py | 92 + .../site-packages/markupsafe/__init__.py | 288 ++ .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 10698 bytes .../__pycache__/_native.cpython-39.pyc | Bin 0 -> 2345 bytes .../site-packages/markupsafe/_native.py | 75 + .../site-packages/markupsafe/_speedups.c | 339 ++ .../_speedups.cpython-39-x86_64-linux-gnu.so | Bin 0 -> 53224 bytes .../site-packages/markupsafe/_speedups.pyi | 9 + .../site-packages/markupsafe/py.typed | 0 .../pip-20.3.4.dist-info/INSTALLER | 1 + .../pip-20.3.4.dist-info}/LICENSE.txt | 2 +- .../pip-20.3.4.dist-info}/METADATA | 34 +- .../site-packages/pip-20.3.4.dist-info/RECORD | 284 ++ .../pip-20.3.4.dist-info/REQUESTED | 0 .../site-packages/pip-20.3.4.dist-info}/WHEEL | 0 .../pip-20.3.4.dist-info}/entry_points.txt | 2 +- .../pip-20.3.4.dist-info/top_level.txt | 1 + .../site-packages/pip/__init__.py | 2 +- .../site-packages/pip/__main__.py | 7 + .../pip/__pycache__/__init__.cpython-39.pyc} | Bin 629 -> 676 bytes .../pip/__pycache__/__main__.cpython-39.pyc | Bin 0 -> 520 bytes .../site-packages/pip/_internal/__init__.py | 3 +- .../__pycache__/__init__.cpython-39.pyc} | Bin 678 -> 725 bytes .../__pycache__/build_env.cpython-39.pyc | Bin 0 -> 7560 bytes .../__pycache__/cache.cpython-39.pyc | Bin 0 -> 9117 bytes .../__pycache__/configuration.cpython-39.pyc | Bin 0 -> 10860 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 14949 bytes .../__pycache__/locations.cpython-39.pyc | Bin 0 -> 4583 bytes .../_internal/__pycache__/main.cpython-39.pyc | Bin 0 -> 662 bytes .../__pycache__/pyproject.cpython-39.pyc | Bin 0 -> 3765 bytes .../self_outdated_check.cpython-39.pyc | Bin 0 -> 4596 bytes .../__pycache__/wheel_builder.cpython-39.pyc | Bin 0 -> 8638 bytes .../site-packages/pip/_internal/build_env.py | 57 +- .../site-packages/pip/_internal/cache.py | 67 +- .../pip/_internal/cli/__init__.py | 0 .../cli/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 283 bytes .../__pycache__/autocompletion.cpython-39.pyc | Bin 0 -> 4962 bytes .../__pycache__/base_command.cpython-39.pyc | Bin 0 -> 6870 bytes .../cli/__pycache__/cmdoptions.cpython-39.pyc | Bin 0 -> 20799 bytes .../command_context.cpython-39.pyc | Bin 0 -> 1363 bytes .../cli/__pycache__/main.cpython-39.pyc | Bin 0 -> 1467 bytes .../__pycache__/main_parser.cpython-39.pyc | Bin 0 -> 2254 bytes .../cli/__pycache__/parser.cpython-39.pyc | Bin 0 -> 9356 bytes .../__pycache__/progress_bars.cpython-39.pyc | Bin 0 -> 7718 bytes .../__pycache__/req_command.cpython-39.pyc | Bin 0 -> 10569 bytes .../cli/__pycache__/spinners.cpython-39.pyc | Bin 0 -> 4812 bytes .../__pycache__/status_codes.cpython-39.pyc | Bin 0 -> 412 bytes .../pip/_internal/cli/autocompletion.py | 0 .../pip/_internal/cli/base_command.py | 92 +- .../pip/_internal/cli/cmdoptions.py | 178 +- .../pip/_internal/cli/command_context.py | 2 +- .../site-packages/pip/_internal/cli/main.py | 2 +- .../pip/_internal/cli/main_parser.py | 13 +- .../site-packages/pip/_internal/cli/parser.py | 74 +- .../pip/_internal/cli/progress_bars.py} | 240 +- .../pip/_internal/cli/req_command.py | 205 +- .../pip/_internal/cli/spinners.py | 173 + .../pip/_internal/cli/status_codes.py | 0 .../pip/_internal/commands/__init__.py | 9 + .../__pycache__/__init__.cpython-39.pyc} | Bin 2852 -> 2983 bytes .../commands/__pycache__/cache.cpython-39.pyc | Bin 0 -> 5882 bytes .../commands/__pycache__/check.cpython-39.pyc | Bin 0 -> 1599 bytes .../__pycache__/completion.cpython-39.pyc | Bin 0 -> 3205 bytes .../__pycache__/configuration.cpython-39.pyc | Bin 0 -> 8155 bytes .../commands/__pycache__/debug.cpython-39.pyc | Bin 0 -> 7479 bytes .../__pycache__/download.cpython-39.pyc | Bin 0 -> 3987 bytes .../__pycache__/freeze.cpython-39.pyc | Bin 0 -> 3322 bytes .../commands/__pycache__/hash.cpython-39.pyc | Bin 0 -> 2166 bytes .../commands/__pycache__/help.cpython-39.pyc | Bin 0 -> 1392 bytes .../__pycache__/install.cpython-39.pyc | Bin 0 -> 17339 bytes .../commands/__pycache__/list.cpython-39.pyc | Bin 0 -> 9100 bytes .../__pycache__/search.cpython-39.pyc | Bin 0 -> 5114 bytes .../commands/__pycache__/show.cpython-39.pyc | Bin 0 -> 6441 bytes .../__pycache__/uninstall.cpython-39.pyc | Bin 0 -> 2977 bytes .../commands/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 5203 bytes .../pip/_internal/commands/cache.py | 234 ++ .../pip/_internal/commands/check.py | 14 +- .../pip/_internal/commands/completion.py | 54 +- .../pip/_internal/commands/configuration.py | 107 +- .../pip/_internal/commands/debug.py | 251 ++ .../pip/_internal/commands/download.py | 143 + .../pip/_internal/commands/freeze.py | 39 +- .../pip/_internal/commands/hash.py | 21 +- .../pip/_internal/commands/help.py | 17 +- .../pip/_internal/commands/install.py | 606 ++-- .../pip/_internal/commands/list.py | 106 +- .../pip/_internal/commands/search.py | 50 +- .../pip/_internal/commands/show.py | 22 +- .../pip/_internal/commands/uninstall.py | 31 +- .../pip/_internal/commands/wheel.py | 198 ++ .../pip/_internal/configuration.py | 119 +- .../pip/_internal/distributions/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc} | Bin 812 -> 859 bytes .../__pycache__/base.cpython-39.pyc} | Bin 1928 -> 1975 bytes .../__pycache__/installed.cpython-39.pyc} | Bin 1208 -> 1255 bytes .../__pycache__/sdist.cpython-39.pyc} | Bin 3471 -> 3534 bytes .../__pycache__/wheel.cpython-39.pyc | Bin 0 -> 1599 bytes .../pip/_internal/distributions/base.py | 3 +- .../pip/_internal/distributions/installed.py | 1 + .../pip/_internal/distributions/sdist.py | 1 + .../pip/_internal/distributions/wheel.py | 1 + .../site-packages/pip/_internal/exceptions.py | 119 +- .../pip/_internal/index/__init__.py | 0 .../index/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 237 bytes .../__pycache__/collector.cpython-39.pyc | Bin 0 -> 17762 bytes .../__pycache__/package_finder.cpython-39.pyc | Bin 0 -> 26090 bytes .../pip/_internal/index/collector.py | 235 +- .../pip/_internal/index/package_finder.py | 66 +- .../site-packages/pip/_internal/locations.py | 21 +- .../site-packages/pip/_internal/main.py | 2 +- .../pip/_internal/models/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 271 bytes .../__pycache__/candidate.cpython-39.pyc | Bin 0 -> 1498 bytes .../__pycache__/direct_url.cpython-39.pyc | Bin 0 -> 6522 bytes .../__pycache__/format_control.cpython-39.pyc | Bin 0 -> 2756 bytes .../models/__pycache__/index.cpython-39.pyc | Bin 0 -> 1237 bytes .../models/__pycache__/link.cpython-39.pyc | Bin 0 -> 7167 bytes .../models/__pycache__/scheme.cpython-39.pyc | Bin 0 -> 959 bytes .../__pycache__/search_scope.cpython-39.pyc | Bin 0 -> 3452 bytes .../selection_prefs.cpython-39.pyc | Bin 0 -> 1669 bytes .../__pycache__/target_python.cpython-39.pyc | Bin 0 -> 3375 bytes .../models/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 3223 bytes .../pip/_internal/models/candidate.py | 3 + .../pip/_internal/models/direct_url.py | 243 ++ .../pip/_internal/models/format_control.py | 20 +- .../pip/_internal/models/index.py | 3 + .../pip/_internal/models/link.py | 29 +- .../pip/_internal/models/scheme.py | 6 + .../pip/_internal/models/search_scope.py | 29 +- .../pip/_internal/models/selection_prefs.py | 5 +- .../pip/_internal/models/target_python.py | 40 +- .../pip/_internal/models/wheel.py | 2 +- .../pip/_internal/network/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 259 bytes .../network/__pycache__/auth.cpython-39.pyc | Bin 0 -> 7111 bytes .../network/__pycache__/cache.cpython-39.pyc | Bin 0 -> 2835 bytes .../__pycache__/download.cpython-39.pyc | Bin 0 -> 5286 bytes .../__pycache__/lazy_wheel.cpython-39.pyc | Bin 0 -> 8075 bytes .../__pycache__/session.cpython-39.pyc | Bin 0 -> 9520 bytes .../network/__pycache__/utils.cpython-39.pyc | Bin 0 -> 1412 bytes .../network/__pycache__/xmlrpc.cpython-39.pyc | Bin 0 -> 1874 bytes .../pip/_internal/network/auth.py | 30 +- .../pip/_internal/network/cache.py | 6 +- .../pip/_internal/network/download.py | 112 +- .../pip/_internal/network/lazy_wheel.py | 231 ++ .../pip/_internal/network/session.py | 53 +- .../pip/_internal/network/utils.py | 97 + .../pip/_internal/network/xmlrpc.py | 21 +- .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 207 bytes .../__pycache__/check.cpython-39.pyc | Bin 0 -> 3629 bytes .../__pycache__/freeze.cpython-39.pyc | Bin 0 -> 5949 bytes .../__pycache__/prepare.cpython-39.pyc | Bin 0 -> 13675 bytes .../_internal/operations/build/__init__.py | 0 .../build/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 213 bytes .../build/__pycache__/metadata.cpython-39.pyc | Bin 0 -> 1234 bytes .../metadata_legacy.cpython-39.pyc | Bin 0 -> 2010 bytes .../build/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 1351 bytes .../__pycache__/wheel_legacy.cpython-39.pyc | Bin 0 -> 2633 bytes .../_internal/operations/build/metadata.py | 4 +- .../operations/build/metadata_legacy.py | 77 + .../pip/_internal/operations/build/wheel.py | 3 +- .../operations/build/wheel_legacy.py | 8 +- .../pip/_internal/operations/check.py | 26 +- .../pip/_internal/operations/freeze.py | 74 +- .../_internal/operations/install/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 271 bytes .../editable_legacy.cpython-39.pyc} | Bin 1302 -> 1389 bytes .../install/__pycache__/legacy.cpython-39.pyc | Bin 0 -> 3279 bytes .../install/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 21263 bytes .../operations/install/editable_legacy.py | 0 .../_internal/operations/install/legacy.py | 130 + .../pip/_internal/operations/install/wheel.py | 846 +++++ .../pip/_internal/operations/prepare.py | 608 ++++ .../site-packages/pip/_internal/pyproject.py | 2 +- .../pip/_internal/req/__init__.py | 59 +- .../req/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2508 bytes .../__pycache__/constructors.cpython-39.pyc | Bin 0 -> 11038 bytes .../req/__pycache__/req_file.cpython-39.pyc | Bin 0 -> 12724 bytes .../__pycache__/req_install.cpython-39.pyc | Bin 0 -> 21475 bytes .../req/__pycache__/req_set.cpython-39.pyc | Bin 0 -> 5827 bytes .../__pycache__/req_tracker.cpython-39.pyc | Bin 0 -> 4249 bytes .../__pycache__/req_uninstall.cpython-39.pyc | Bin 0 -> 17577 bytes .../pip/_internal/req/constructors.py | 156 +- .../pip/_internal/req/req_file.py | 366 +- .../pip/_internal/req/req_install.py | 363 +- .../pip/_internal/req/req_set.py | 49 +- .../pip/_internal/req/req_tracker.py | 11 +- .../pip/_internal/req/req_uninstall.py | 27 +- .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 207 bytes .../__pycache__/base.cpython-39.pyc | Bin 0 -> 1039 bytes .../pip/_internal/resolution/base.py | 21 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 214 bytes .../__pycache__/resolver.cpython-39.pyc | Bin 0 -> 11594 bytes .../_internal/resolution/legacy/resolver.py} | 135 +- .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 218 bytes .../__pycache__/base.cpython-39.pyc | Bin 0 -> 5797 bytes .../__pycache__/candidates.cpython-39.pyc | Bin 0 -> 18022 bytes .../__pycache__/factory.cpython-39.pyc | Bin 0 -> 11567 bytes .../found_candidates.cpython-39.pyc | Bin 0 -> 3476 bytes .../__pycache__/provider.cpython-39.pyc | Bin 0 -> 6339 bytes .../__pycache__/reporter.cpython-39.pyc | Bin 0 -> 3225 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 0 -> 7063 bytes .../__pycache__/resolver.cpython-39.pyc | Bin 0 -> 7912 bytes .../_internal/resolution/resolvelib/base.py | 156 + .../resolution/resolvelib/candidates.py | 604 ++++ .../resolution/resolvelib/factory.py | 504 +++ .../resolution/resolvelib/found_candidates.py | 101 + .../resolution/resolvelib/provider.py | 174 + .../resolution/resolvelib/reporter.py | 84 + .../resolution/resolvelib/requirements.py | 201 ++ .../resolution/resolvelib/resolver.py | 297 ++ .../pip/_internal/self_outdated_check.py | 59 +- .../pip/_internal/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 202 bytes .../utils/__pycache__/appdirs.cpython-39.pyc | Bin 0 -> 1392 bytes .../utils/__pycache__/compat.cpython-39.pyc | Bin 0 -> 6717 bytes .../compatibility_tags.cpython-39.pyc | Bin 0 -> 3951 bytes .../utils/__pycache__/datetime.cpython-39.pyc | Bin 0 -> 523 bytes .../__pycache__/deprecation.cpython-39.pyc} | Bin 2826 -> 2849 bytes .../direct_url_helpers.cpython-39.pyc | Bin 0 -> 2670 bytes .../__pycache__/distutils_args.cpython-39.pyc | Bin 0 -> 1142 bytes .../utils/__pycache__/encoding.cpython-39.pyc | Bin 0 -> 1322 bytes .../__pycache__/entrypoints.cpython-39.pyc} | Bin 1299 -> 1346 bytes .../__pycache__/filesystem.cpython-39.pyc | Bin 0 -> 5683 bytes .../__pycache__/filetypes.cpython-39.pyc | Bin 0 -> 891 bytes .../utils/__pycache__/glibc.cpython-39.pyc} | Bin 1708 -> 1749 bytes .../utils/__pycache__/hashes.cpython-39.pyc | Bin 0 -> 5269 bytes .../inject_securetransport.cpython-39.pyc | Bin 0 -> 975 bytes .../utils/__pycache__/logging.cpython-39.pyc} | Bin 9159 -> 9242 bytes .../utils/__pycache__/misc.cpython-39.pyc | Bin 0 -> 25527 bytes .../utils/__pycache__/models.cpython-39.pyc | Bin 0 -> 2002 bytes .../__pycache__/packaging.cpython-39.pyc} | Bin 2608 -> 2655 bytes .../utils/__pycache__/parallel.cpython-39.pyc | Bin 0 -> 3220 bytes .../__pycache__/pkg_resources.cpython-39.pyc} | Bin 1822 -> 1871 bytes .../setuptools_build.cpython-39.pyc | Bin 0 -> 2948 bytes .../__pycache__/subprocess.cpython-39.pyc | Bin 0 -> 6085 bytes .../utils/__pycache__/temp_dir.cpython-39.pyc | Bin 0 -> 7230 bytes .../utils/__pycache__/typing.cpython-39.pyc} | Bin 1437 -> 1484 bytes .../__pycache__/unpacking.cpython-39.pyc | Bin 0 -> 6646 bytes .../utils/__pycache__/urls.cpython-39.pyc | Bin 0 -> 1546 bytes .../__pycache__/virtualenv.cpython-39.pyc | Bin 0 -> 3379 bytes .../utils/__pycache__/wheel.cpython-39.pyc} | Bin 6325 -> 6358 bytes .../pip/_internal/utils/appdirs.py | 12 +- .../pip/_internal/utils/compat.py | 40 +- .../_internal/utils/compatibility_tags.py} | 41 +- .../pip/_internal/utils/datetime.py | 14 + .../pip/_internal/utils/deprecation.py | 0 .../pip/_internal/utils/direct_url_helpers.py | 126 + .../pip/_internal/utils/distutils_args.py | 0 .../pip/_internal/utils/encoding.py | 9 +- .../pip/_internal/utils/entrypoints.py | 2 +- .../pip/_internal/utils/filesystem.py | 69 +- .../pip/_internal/utils/filetypes.py | 10 + .../pip/_internal/utils/glibc.py | 0 .../pip/_internal/utils/hashes.py | 58 +- .../_internal/utils/inject_securetransport.py | 0 .../pip/_internal/utils/logging.py | 5 +- .../site-packages/pip/_internal/utils/misc.py | 187 +- .../pip/_internal/utils/models.py | 2 + .../pip/_internal/utils/packaging.py | 3 +- .../pip/_internal/utils/parallel.py | 107 + .../pip/_internal/utils/pkg_resources.py | 0 .../pip/_internal/utils/setuptools_build.py | 6 +- .../pip/_internal/utils/subprocess.py | 99 +- .../pip/_internal/utils/temp_dir.py | 54 +- .../pip/_internal/utils/typing.py | 0 .../pip/_internal/utils/unpacking.py | 37 +- .../site-packages/pip/_internal/utils/urls.py | 7 +- .../pip/_internal/utils/virtualenv.py | 12 +- .../pip/_internal/utils/wheel.py | 8 +- .../pip/_internal/vcs/__init__.py | 0 .../vcs/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 495 bytes .../vcs/__pycache__/bazaar.cpython-39.pyc | Bin 0 -> 3817 bytes .../vcs/__pycache__/git.cpython-39.pyc | Bin 0 -> 10630 bytes .../vcs/__pycache__/mercurial.cpython-39.pyc | Bin 0 -> 5192 bytes .../vcs/__pycache__/subversion.cpython-39.pyc | Bin 0 -> 8617 bytes .../__pycache__/versioncontrol.cpython-39.pyc | Bin 0 -> 19705 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 7 +- .../site-packages/pip/_internal/vcs/git.py | 107 +- .../pip/_internal/vcs/mercurial.py | 43 +- .../pip/_internal/vcs/subversion.py | 17 +- .../pip/_internal/vcs/versioncontrol.py | 77 +- .../pip/_internal/wheel_builder.py | 104 +- .../site-packages/pip/_vendor/__init__.py | 8 +- .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 3322 bytes .../site-packages/pip/_vendor/vendor.txt | 24 + .../pkg_resources-0.0.0.dist-info/AUTHORS.txt | 590 ++++ .../pkg_resources-0.0.0.dist-info/INSTALLER | 1 + .../LICENSE.txt | 2 +- .../pkg_resources-0.0.0.dist-info/METADATA | 0 .../pkg_resources-0.0.0.dist-info/RECORD | 37 +- .../pkg_resources-0.0.0.dist-info/REQUESTED | 0 .../pkg_resources-0.0.0.dist-info/WHEEL | 0 .../site-packages/pkg_resources/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc} | Bin 100356 -> 100384 bytes .../__pycache__/py31compat.cpython-39.pyc | Bin 0 -> 649 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 204 bytes .../__pycache__/appdirs.cpython-39.pyc} | Bin 20510 -> 20521 bytes .../__pycache__/pyparsing.cpython-39.pyc} | Bin 201631 -> 201357 bytes .../_vendor/__pycache__/six.cpython-39.pyc} | Bin 24427 -> 24487 bytes .../pkg_resources/_vendor/appdirs.py | 0 .../_vendor/packaging/__about__.py | 0 .../_vendor/packaging/__init__.py | 0 .../__pycache__/__about__.cpython-39.pyc | Bin 0 -> 728 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 566 bytes .../__pycache__/_compat.cpython-39.pyc} | Bin 981 -> 1028 bytes .../__pycache__/_structures.cpython-39.pyc} | Bin 2763 -> 2810 bytes .../__pycache__/markers.cpython-39.pyc | Bin 0 -> 8938 bytes .../__pycache__/requirements.cpython-39.pyc} | Bin 3878 -> 3925 bytes .../__pycache__/specifiers.cpython-39.pyc} | Bin 19787 -> 19814 bytes .../__pycache__/utils.cpython-39.pyc} | Bin 466 -> 513 bytes .../__pycache__/version.cpython-39.pyc} | Bin 10634 -> 10649 bytes .../_vendor/packaging/_compat.py | 0 .../_vendor/packaging/_structures.py | 0 .../_vendor/packaging/markers.py | 0 .../_vendor/packaging/requirements.py | 0 .../_vendor/packaging/specifiers.py | 0 .../pkg_resources/_vendor/packaging/utils.py | 0 .../_vendor/packaging/version.py | 0 .../pkg_resources/_vendor/pyparsing.py | 0 .../pkg_resources/_vendor/six.py | 0 .../pkg_resources/extern/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc} | Bin 2406 -> 2455 bytes .../site-packages/pkg_resources/py31compat.py | 0 .../setuptools-44.1.1.dist-info/AUTHORS.txt | 590 ++++ .../setuptools-44.1.1.dist-info/INSTALLER | 1 + .../setuptools-44.1.1.dist-info}/LICENSE.txt | 2 +- .../setuptools-44.1.1.dist-info}/METADATA | 2 +- .../setuptools-44.1.1.dist-info}/RECORD | 187 +- .../setuptools-44.1.1.dist-info/REQUESTED | 0 .../setuptools-44.1.1.dist-info}/WHEEL | 0 .../dependency_links.txt | 0 .../entry_points.txt | 0 .../top_level.txt | 0 .../setuptools-44.1.1.dist-info}/zip-safe | 0 .../site-packages/setuptools/__init__.py | 25 +- .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 8645 bytes .../_deprecation_warning.cpython-39.pyc | Bin 0 -> 563 bytes .../__pycache__/_imp.cpython-39.pyc} | Bin 1890 -> 1933 bytes .../__pycache__/archive_util.cpython-39.pyc} | Bin 5128 -> 5235 bytes .../__pycache__/build_meta.cpython-39.pyc} | Bin 8495 -> 8650 bytes .../__pycache__/config.cpython-39.pyc} | Bin 17896 -> 17956 bytes .../__pycache__/dep_util.cpython-39.pyc} | Bin 819 -> 866 bytes .../__pycache__/depends.cpython-39.pyc} | Bin 5216 -> 5284 bytes .../__pycache__/dist.cpython-39.pyc} | Bin 42326 -> 42490 bytes .../__pycache__/errors.cpython-39.pyc} | Bin 816 -> 863 bytes .../__pycache__/extension.cpython-39.pyc} | Bin 1961 -> 2012 bytes .../__pycache__/glob.cpython-39.pyc | Bin 0 -> 3770 bytes .../__pycache__/installer.cpython-39.pyc | Bin 0 -> 4117 bytes .../__pycache__/launch.cpython-39.pyc} | Bin 824 -> 871 bytes .../__pycache__/lib2to3_ex.cpython-39.pyc} | Bin 2411 -> 2464 bytes .../__pycache__/monkey.cpython-39.pyc} | Bin 4644 -> 4685 bytes .../__pycache__/msvc.cpython-39.pyc} | Bin 39631 -> 39673 bytes .../__pycache__/namespaces.cpython-39.pyc} | Bin 3616 -> 3683 bytes .../__pycache__/package_index.cpython-39.pyc | Bin 0 -> 33121 bytes .../__pycache__/py27compat.cpython-39.pyc} | Bin 1749 -> 1796 bytes .../__pycache__/py31compat.cpython-39.pyc | Bin 0 -> 1238 bytes .../__pycache__/py33compat.cpython-39.pyc} | Bin 1408 -> 1453 bytes .../__pycache__/py34compat.cpython-39.pyc | Bin 0 -> 493 bytes .../__pycache__/sandbox.cpython-39.pyc | Bin 0 -> 15923 bytes .../__pycache__/site-patch.cpython-39.pyc | Bin 0 -> 1523 bytes .../__pycache__/ssl_support.cpython-39.pyc | Bin 0 -> 6891 bytes .../__pycache__/unicode_utils.cpython-39.pyc | Bin 0 -> 1192 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 337 bytes .../__pycache__/wheel.cpython-39.pyc | Bin 0 -> 7476 bytes .../windows_support.cpython-39.pyc} | Bin 989 -> 1036 bytes .../setuptools/_deprecation_warning.py | 0 .../site-packages/setuptools/_imp.py | 0 .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 201 bytes .../__pycache__/ordered_set.cpython-39.pyc} | Bin 16412 -> 16395 bytes .../__pycache__/pyparsing.cpython-39.pyc} | Bin 201634 -> 201354 bytes .../_vendor/__pycache__/six.cpython-39.pyc} | Bin 24430 -> 24484 bytes .../setuptools/_vendor/ordered_set.py | 0 .../setuptools/_vendor/packaging/__about__.py | 0 .../setuptools/_vendor/packaging/__init__.py | 0 .../__pycache__/__about__.cpython-39.pyc | Bin 0 -> 725 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 563 bytes .../__pycache__/_compat.cpython-39.pyc} | Bin 978 -> 1025 bytes .../__pycache__/_structures.cpython-39.pyc} | Bin 2760 -> 2807 bytes .../__pycache__/markers.cpython-39.pyc | Bin 0 -> 8946 bytes .../__pycache__/requirements.cpython-39.pyc} | Bin 3995 -> 4038 bytes .../__pycache__/specifiers.cpython-39.pyc} | Bin 19734 -> 19759 bytes .../packaging/__pycache__/tags.cpython-39.pyc | Bin 0 -> 10837 bytes .../__pycache__/utils.cpython-39.pyc | Bin 0 -> 1472 bytes .../__pycache__/version.cpython-39.pyc} | Bin 12065 -> 12092 bytes .../setuptools/_vendor/packaging/_compat.py | 0 .../_vendor/packaging/_structures.py | 0 .../setuptools/_vendor/packaging/markers.py | 0 .../_vendor/packaging/requirements.py | 0 .../_vendor/packaging/specifiers.py | 0 .../setuptools/_vendor/packaging/tags.py | 0 .../setuptools/_vendor/packaging/utils.py | 0 .../setuptools/_vendor/packaging/version.py | 0 .../setuptools/_vendor/pyparsing.py | 0 .../site-packages/setuptools/_vendor/six.py | 0 .../site-packages/setuptools/archive_util.py | 0 .../site-packages/setuptools/build_meta.py | 7 + .../site-packages/setuptools/cli-32.exe | Bin .../site-packages/setuptools/cli-64.exe | Bin .../site-packages/setuptools/cli.exe | Bin .../setuptools/command/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 681 bytes .../command/__pycache__/alias.cpython-39.pyc} | Bin 2392 -> 2439 bytes .../__pycache__/bdist_egg.cpython-39.pyc} | Bin 14182 -> 14227 bytes .../__pycache__/bdist_rpm.cpython-39.pyc} | Bin 1784 -> 1829 bytes .../__pycache__/bdist_wininst.cpython-39.pyc | Bin 0 -> 1005 bytes .../__pycache__/build_clib.cpython-39.pyc} | Bin 2437 -> 2484 bytes .../__pycache__/build_ext.cpython-39.pyc | Bin 0 -> 9874 bytes .../__pycache__/build_py.cpython-39.pyc} | Bin 8641 -> 8705 bytes .../__pycache__/develop.cpython-39.pyc} | Bin 6501 -> 6584 bytes .../__pycache__/dist_info.cpython-39.pyc} | Bin 1361 -> 1408 bytes .../__pycache__/easy_install.cpython-39.pyc} | Bin 66694 -> 67018 bytes .../__pycache__/egg_info.cpython-39.pyc} | Bin 21773 -> 21835 bytes .../__pycache__/install.cpython-39.pyc} | Bin 4016 -> 4049 bytes .../install_egg_info.cpython-39.pyc} | Bin 2900 -> 2937 bytes .../__pycache__/install_lib.cpython-39.pyc} | Bin 5083 -> 5102 bytes .../install_scripts.cpython-39.pyc} | Bin 2273 -> 2316 bytes .../__pycache__/py36compat.cpython-39.pyc} | Bin 4610 -> 4657 bytes .../__pycache__/register.cpython-39.pyc} | Bin 811 -> 858 bytes .../command/__pycache__/rotate.cpython-39.pyc | Bin 0 -> 2553 bytes .../__pycache__/saveopts.cpython-39.pyc} | Bin 889 -> 936 bytes .../command/__pycache__/sdist.cpython-39.pyc | Bin 0 -> 7946 bytes .../command/__pycache__/setopt.cpython-39.pyc | Bin 0 -> 4588 bytes .../command/__pycache__/test.cpython-39.pyc} | Bin 8475 -> 8686 bytes .../__pycache__/upload.cpython-39.pyc} | Bin 784 -> 831 bytes .../__pycache__/upload_docs.cpython-39.pyc} | Bin 6140 -> 6225 bytes .../site-packages/setuptools/command/alias.py | 0 .../setuptools/command/bdist_egg.py | 0 .../setuptools/command/bdist_rpm.py | 0 .../setuptools/command/bdist_wininst.py | 0 .../setuptools/command/build_clib.py | 0 .../setuptools/command/build_ext.py | 2 +- .../setuptools/command/build_py.py | 0 .../setuptools/command/develop.py | 2 +- .../setuptools/command/dist_info.py | 0 .../setuptools/command/easy_install.py | 2 +- .../setuptools/command/egg_info.py | 2 +- .../setuptools/command/install.py | 0 .../setuptools/command/install_egg_info.py | 0 .../setuptools/command/install_lib.py | 0 .../setuptools/command/install_scripts.py | 0 .../setuptools/command/launcher manifest.xml | 0 .../setuptools/command/py36compat.py | 0 .../setuptools/command/register.py | 0 .../setuptools/command/rotate.py | 0 .../setuptools/command/saveopts.py | 0 .../site-packages/setuptools/command/sdist.py | 2 +- .../setuptools/command/setopt.py | 0 .../site-packages/setuptools/command/test.py | 4 +- .../setuptools/command/upload.py | 0 .../setuptools/command/upload_docs.py | 4 +- .../site-packages/setuptools/config.py | 0 .../site-packages/setuptools/dep_util.py | 0 .../site-packages/setuptools/depends.py | 0 .../site-packages/setuptools/dist.py | 12 +- .../site-packages/setuptools/errors.py | 0 .../site-packages/setuptools/extension.py | 0 .../setuptools/extern/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc} | Bin 2420 -> 2469 bytes .../site-packages/setuptools/glob.py | 0 .../site-packages/setuptools/gui-32.exe | Bin .../site-packages/setuptools/gui-64.exe | Bin .../site-packages/setuptools/gui.exe | Bin .../site-packages/setuptools/installer.py | 0 .../site-packages/setuptools/launch.py | 0 .../site-packages/setuptools/lib2to3_ex.py | 0 .../site-packages/setuptools/monkey.py | 0 .../site-packages/setuptools/msvc.py | 0 .../site-packages/setuptools/namespaces.py | 0 .../site-packages/setuptools/package_index.py | 0 .../site-packages/setuptools/py27compat.py | 0 .../site-packages/setuptools/py31compat.py | 0 .../site-packages/setuptools/py33compat.py | 0 .../site-packages/setuptools/py34compat.py | 0 .../site-packages/setuptools/sandbox.py | 0 .../setuptools/script (dev).tmpl | 0 .../site-packages/setuptools/script.tmpl | 0 .../site-packages/setuptools/site-patch.py | 0 .../site-packages/setuptools/ssl_support.py | 0 .../site-packages/setuptools/unicode_utils.py | 0 .../site-packages/setuptools/version.py | 0 .../site-packages/setuptools/wheel.py | 0 .../setuptools/windows_support.py | 0 .../site-packages/werkzeug/__init__.py | 6 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 365 bytes .../__pycache__/_internal.cpython-39.pyc | Bin 0 -> 18475 bytes .../__pycache__/_reloader.cpython-39.pyc | Bin 0 -> 11986 bytes .../__pycache__/datastructures.cpython-39.pyc | Bin 0 -> 106457 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 30250 bytes .../__pycache__/filesystem.cpython-39.pyc | Bin 0 -> 2100 bytes .../__pycache__/formparser.cpython-39.pyc | Bin 0 -> 14034 bytes .../werkzeug/__pycache__/http.cpython-39.pyc | Bin 0 -> 38068 bytes .../werkzeug/__pycache__/local.cpython-39.pyc | Bin 0 -> 22295 bytes .../__pycache__/routing.cpython-39.pyc | Bin 0 -> 73087 bytes .../__pycache__/security.cpython-39.pyc | Bin 0 -> 8186 bytes .../__pycache__/serving.cpython-39.pyc | Bin 0 -> 30738 bytes .../werkzeug/__pycache__/test.cpython-39.pyc | Bin 0 -> 39095 bytes .../__pycache__/testapp.cpython-39.pyc | Bin 0 -> 9629 bytes .../werkzeug/__pycache__/urls.cpython-39.pyc | Bin 0 -> 36645 bytes .../__pycache__/user_agent.cpython-39.pyc | Bin 0 -> 1846 bytes .../__pycache__/useragents.cpython-39.pyc | Bin 0 -> 6888 bytes .../werkzeug/__pycache__/utils.cpython-39.pyc | Bin 0 -> 32813 bytes .../werkzeug/__pycache__/wsgi.cpython-39.pyc | Bin 0 -> 30229 bytes .../site-packages/werkzeug/_internal.py | 626 ++++ .../site-packages/werkzeug/_reloader.py | 430 +++ .../site-packages/werkzeug/datastructures.py | 3051 +++++++++++++++++ .../site-packages/werkzeug/datastructures.pyi | 906 +++++ .../site-packages/werkzeug/debug/__init__.py | 501 +++ .../debug/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 13009 bytes .../debug/__pycache__/console.cpython-39.pyc | Bin 0 -> 7952 bytes .../debug/__pycache__/repr.cpython-39.pyc | Bin 0 -> 8881 bytes .../debug/__pycache__/tbtools.cpython-39.pyc | Bin 0 -> 18045 bytes .../site-packages/werkzeug/debug/console.py | 211 ++ .../site-packages/werkzeug/debug/repr.py | 284 ++ .../werkzeug/debug/shared/FONT_LICENSE | 96 + .../werkzeug/debug/shared/ICON_LICENSE.md | 6 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 359 ++ .../werkzeug/debug/shared/less.png | Bin 0 -> 191 bytes .../werkzeug/debug/shared/more.png | Bin 0 -> 200 bytes .../werkzeug/debug/shared/source.png | Bin 0 -> 818 bytes .../werkzeug/debug/shared/style.css | 163 + .../werkzeug/debug/shared/ubuntu.ttf | Bin 0 -> 70220 bytes .../site-packages/werkzeug/debug/tbtools.py | 595 ++++ .../site-packages/werkzeug/exceptions.py | 943 +++++ .../site-packages/werkzeug/filesystem.py | 55 + .../site-packages/werkzeug/formparser.py | 495 +++ .../python3.9/site-packages/werkzeug/http.py | 1388 ++++++++ .../python3.9/site-packages/werkzeug/local.py | 666 ++++ .../werkzeug/middleware/__init__.py | 22 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 710 bytes .../__pycache__/dispatcher.cpython-39.pyc | Bin 0 -> 2769 bytes .../__pycache__/http_proxy.cpython-39.pyc | Bin 0 -> 6814 bytes .../__pycache__/lint.cpython-39.pyc | Bin 0 -> 12711 bytes .../__pycache__/profiler.cpython-39.pyc | Bin 0 -> 4962 bytes .../__pycache__/proxy_fix.cpython-39.pyc | Bin 0 -> 6191 bytes .../__pycache__/shared_data.cpython-39.pyc | Bin 0 -> 9865 bytes .../werkzeug/middleware/dispatcher.py | 78 + .../werkzeug/middleware/http_proxy.py | 230 ++ .../site-packages/werkzeug/middleware/lint.py | 420 +++ .../werkzeug/middleware/profiler.py | 139 + .../werkzeug/middleware/proxy_fix.py | 187 + .../werkzeug/middleware/shared_data.py | 320 ++ .../python3.9/site-packages/werkzeug/py.typed | 0 .../site-packages/werkzeug/routing.py | 2332 +++++++++++++ .../site-packages/werkzeug/sansio/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 198 bytes .../__pycache__/multipart.cpython-39.pyc | Bin 0 -> 6549 bytes .../sansio/__pycache__/request.cpython-39.pyc | Bin 0 -> 17194 bytes .../__pycache__/response.cpython-39.pyc | Bin 0 -> 21123 bytes .../sansio/__pycache__/utils.cpython-39.pyc | Bin 0 -> 3902 bytes .../werkzeug/sansio/multipart.py | 260 ++ .../site-packages/werkzeug/sansio/request.py | 548 +++ .../site-packages/werkzeug/sansio/response.py | 656 ++++ .../site-packages/werkzeug/sansio/utils.py | 142 + .../site-packages/werkzeug/security.py | 247 ++ .../site-packages/werkzeug/serving.py | 1079 ++++++ .../python3.9/site-packages/werkzeug/test.py | 1324 +++++++ .../site-packages/werkzeug/testapp.py | 240 ++ .../python3.9/site-packages/werkzeug/urls.py | 1211 +++++++ .../site-packages/werkzeug/user_agent.py | 47 + .../site-packages/werkzeug/useragents.py | 215 ++ .../python3.9/site-packages/werkzeug/utils.py | 1091 ++++++ .../werkzeug/wrappers/__init__.py | 16 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 921 bytes .../__pycache__/accept.cpython-39.pyc | Bin 0 -> 827 bytes .../wrappers/__pycache__/auth.cpython-39.pyc | Bin 0 -> 1305 bytes .../__pycache__/base_request.cpython-39.pyc | Bin 0 -> 1780 bytes .../__pycache__/base_response.cpython-39.pyc | Bin 0 -> 1791 bytes .../common_descriptors.cpython-39.pyc | Bin 0 -> 1382 bytes .../wrappers/__pycache__/cors.cpython-39.pyc | Bin 0 -> 1290 bytes .../wrappers/__pycache__/etag.cpython-39.pyc | Bin 0 -> 1290 bytes .../wrappers/__pycache__/json.cpython-39.pyc | Bin 0 -> 819 bytes .../__pycache__/request.cpython-39.pyc | Bin 0 -> 21308 bytes .../__pycache__/response.cpython-39.pyc | Bin 0 -> 29702 bytes .../__pycache__/user_agent.cpython-39.pyc | Bin 0 -> 840 bytes .../site-packages/werkzeug/wrappers/accept.py | 14 + .../site-packages/werkzeug/wrappers/auth.py | 26 + .../werkzeug/wrappers/base_request.py | 36 + .../werkzeug/wrappers/base_response.py | 36 + .../werkzeug/wrappers/common_descriptors.py | 26 + .../site-packages/werkzeug/wrappers/cors.py | 26 + .../site-packages/werkzeug/wrappers/etag.py | 26 + .../site-packages/werkzeug/wrappers/json.py | 13 + .../werkzeug/wrappers/request.py | 660 ++++ .../werkzeug/wrappers/response.py | 890 +++++ .../werkzeug/wrappers/user_agent.py | 14 + .../python3.9/site-packages/werkzeug/wsgi.py | 982 ++++++ venv/pyvenv.cfg | 2 +- venv/requirements.txt | 1 + .../CacheControl-0.12.6-py2.py3-none-any.whl | Bin 28023 -> 23441 bytes .../appdirs-1.4.3-py2.py3-none-any.whl | Bin 18776 -> 0 bytes .../appdirs-1.4.4-py2.py3-none-any.whl | Bin 0 -> 14285 bytes .../certifi-2019.11.28-py2.py3-none-any.whl | Bin 164552 -> 0 bytes .../certifi-2020.6.20-py2.py3-none-any.whl | Bin 0 -> 161344 bytes ...whl => chardet-4.0.0-py2.py3-none-any.whl} | Bin 141487 -> 174749 bytes .../colorama-0.4.3-py2.py3-none-any.whl | Bin 25094 -> 0 bytes .../colorama-0.4.4-py2.py3-none-any.whl | Bin 0 -> 20722 bytes .../contextlib2-0.6.0-py2.py3-none-any.whl | Bin 17188 -> 0 bytes ...ntextlib2-0.6.0.post1-py2.py3-none-any.whl | Bin 0 -> 12692 bytes ...whl => distlib-0.3.1-py2.py3-none-any.whl} | Bin 152027 -> 147633 bytes .../distro-1.4.0-py2.py3-none-any.whl | Bin 23898 -> 0 bytes .../distro-1.5.0-py2.py3-none-any.whl | Bin 0 -> 19426 bytes .../html5lib-1.0.1-py2.py3-none-any.whl | Bin 120020 -> 0 bytes .../html5lib-1.1-py2.py3-none-any.whl | Bin 0 -> 116071 bytes .../idna-2.10-py2.py3-none-any.whl | Bin 0 -> 63344 bytes .../idna-2.8-py2.py3-none-any.whl | Bin 66836 -> 0 bytes .../ipaddr-2.2.0-py2.py3-none-any.whl | Bin 24287 -> 19706 bytes .../lockfile-0.12.2-py2.py3-none-any.whl | Bin 21972 -> 0 bytes .../msgpack-0.6.2-py2.py3-none-any.whl | Bin 92927 -> 0 bytes .../msgpack-1.0.0-py2.py3-none-any.whl | Bin 0 -> 75866 bytes .../packaging-20.3-py2.py3-none-any.whl | Bin 42242 -> 0 bytes .../packaging-20.9-py2.py3-none-any.whl | Bin 0 -> 41435 bytes .../pep517-0.8.2-py2.py3-none-any.whl | Bin 26686 -> 0 bytes .../pep517-0.9.1-py2.py3-none-any.whl | Bin 0 -> 22249 bytes .../pip-20.0.2-py2.py3-none-any.whl | Bin 262434 -> 0 bytes .../pip-20.3.4-py2.py3-none-any.whl | Bin 0 -> 311145 bytes .../pkg_resources-0.0.0-py2.py3-none-any.whl | Bin 127312 -> 122731 bytes .../progress-1.5-py2.py3-none-any.whl | Bin 17547 -> 12965 bytes .../pyparsing-2.4.6-py2.py3-none-any.whl | Bin 77093 -> 0 bytes .../pyparsing-2.4.7-py2.py3-none-any.whl | Bin 0 -> 72626 bytes .../requests-2.22.0-py2.py3-none-any.whl | Bin 67470 -> 0 bytes .../requests-2.25.1-py2.py3-none-any.whl | Bin 0 -> 62975 bytes .../resolvelib-0.5.4-py2.py3-none-any.whl | Bin 0 -> 17707 bytes .../retrying-1.3.3-py2.py3-none-any.whl | Bin 16358 -> 11776 bytes ...=> setuptools-44.1.1-py2.py3-none-any.whl} | Bin 477446 -> 473123 bytes .../six-1.14.0-py2.py3-none-any.whl | Bin 20256 -> 0 bytes .../six-1.16.0-py2.py3-none-any.whl | Bin 0 -> 15791 bytes .../toml-0.10.0-py2.py3-none-any.whl | Bin 24106 -> 0 bytes .../toml-0.10.1-py2.py3-none-any.whl | Bin 0 -> 21108 bytes .../urllib3-1.25.8-py2.py3-none-any.whl | Bin 127041 -> 0 bytes .../urllib3-1.26.5-py2.py3-none-any.whl | Bin 0 -> 134200 bytes .../webencodings-0.5.1-py2.py3-none-any.whl | Bin 20484 -> 15904 bytes .../wheel-0.34.2-py2.py3-none-any.whl | Bin 35611 -> 31030 bytes venv/vercel.json | 15 + 989 files changed, 70951 insertions(+), 5649 deletions(-) create mode 100644 venv/.vercel/README.txt create mode 100644 venv/.vercel/project.json delete mode 100644 venv/__pycache__/index.cpython-38.pyc create mode 100644 venv/__pycache__/index.cpython-39.pyc rename venv/bin/{easy_install-3.8 => easy_install-3.9} (76%) create mode 100755 venv/bin/flask rename venv/bin/{pip3.8 => pip3.9} (75%) create mode 120000 venv/bin/python3.9 delete mode 100644 venv/lib/python3.8/site-packages/__pycache__/easy_install.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip-20.0.2.dist-info/RECORD delete mode 100644 venv/lib/python3.8/site-packages/pip/__pycache__/__main__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/build_env.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/cache.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/configuration.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/exceptions.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/legacy_resolve.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/locations.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/main.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/pep425tags.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/pyproject.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/parser.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/check.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/completion.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/debug.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/download.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/hash.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/help.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/install.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/list.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/search.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/show.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/debug.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/download.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/commands/wheel.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/index/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/index/__pycache__/collector.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/candidate.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/format_control.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/index.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/link.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/scheme.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/target_python.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/wheel.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/auth.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/cache.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/download.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/session.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/utils.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/network/utils.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/check.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/build/metadata_legacy.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/install/legacy.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/install/wheel.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/operations/prepare.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/constructors.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_file.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_install.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_set.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/compat.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/marker_files.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/misc.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/models.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/ui.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/urls.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/marker_files.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/git.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/AUTHORS.txt delete mode 100644 venv/lib/python3.8/site-packages/pkg_resources/__pycache__/py31compat.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/AUTHORS.txt delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/glob.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/installer.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/package_index.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/py31compat.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/py34compat.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/sandbox.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/site-patch.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/ssl_support.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/unicode_utils.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/version.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/wheel.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/command/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/command/__pycache__/build_ext.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/command/__pycache__/rotate.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/command/__pycache__/sdist.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/command/__pycache__/setopt.cpython-38.pyc rename venv/lib/{python3.8/site-packages/pip-20.0.2.dist-info => python3.9/site-packages/Flask-2.0.1.dist-info}/INSTALLER (100%) create mode 100644 venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/LICENSE.rst create mode 100644 venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/METADATA create mode 100644 venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/RECORD rename venv/lib/{python3.8/site-packages/pip/_internal/operations/__init__.py => python3.9/site-packages/Flask-2.0.1.dist-info/REQUESTED} (100%) create mode 100644 venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/WHEEL create mode 100644 venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/entry_points.txt create mode 100644 venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/top_level.txt rename venv/lib/{python3.8/site-packages/pkg_resources-0.0.0.dist-info => python3.9/site-packages/Jinja2-3.0.1.dist-info}/INSTALLER (100%) create mode 100644 venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/LICENSE.rst create mode 100644 venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/METADATA create mode 100644 venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/RECORD create mode 100644 venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/WHEEL create mode 100644 venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/entry_points.txt create mode 100644 venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/top_level.txt rename venv/lib/{python3.8/site-packages/setuptools-44.0.0.dist-info => python3.9/site-packages/MarkupSafe-2.0.1.dist-info}/INSTALLER (100%) create mode 100644 venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/LICENSE.rst create mode 100644 venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/METADATA create mode 100644 venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/RECORD create mode 100644 venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/WHEEL create mode 100644 venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/top_level.txt rename venv/lib/{python3.8/site-packages/pip-20.0.2.dist-info/top_level.txt => python3.9/site-packages/Werkzeug-2.0.1.dist-info/INSTALLER} (100%) create mode 100644 venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/LICENSE.rst create mode 100644 venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/METADATA create mode 100644 venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/RECORD create mode 100644 venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/WHEEL create mode 100644 venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.9/site-packages/__pycache__/easy_install.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click-8.0.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.9/site-packages/click-8.0.1.dist-info/LICENSE.rst create mode 100644 venv/lib/python3.9/site-packages/click-8.0.1.dist-info/METADATA create mode 100644 venv/lib/python3.9/site-packages/click-8.0.1.dist-info/RECORD create mode 100644 venv/lib/python3.9/site-packages/click-8.0.1.dist-info/WHEEL create mode 100644 venv/lib/python3.9/site-packages/click-8.0.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.9/site-packages/click/__init__.py create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/_compat.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/_termui_impl.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/_textwrap.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/_unicodefun.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/_winconsole.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/core.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/decorators.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/exceptions.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/formatting.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/globals.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/parser.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/shell_completion.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/termui.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/testing.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/types.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/__pycache__/utils.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/click/_compat.py create mode 100644 venv/lib/python3.9/site-packages/click/_termui_impl.py create mode 100644 venv/lib/python3.9/site-packages/click/_textwrap.py create mode 100644 venv/lib/python3.9/site-packages/click/_unicodefun.py create mode 100644 venv/lib/python3.9/site-packages/click/_winconsole.py create mode 100644 venv/lib/python3.9/site-packages/click/core.py create mode 100644 venv/lib/python3.9/site-packages/click/decorators.py create mode 100644 venv/lib/python3.9/site-packages/click/exceptions.py create mode 100644 venv/lib/python3.9/site-packages/click/formatting.py create mode 100644 venv/lib/python3.9/site-packages/click/globals.py create mode 100644 venv/lib/python3.9/site-packages/click/parser.py rename venv/lib/{python3.8/site-packages/pip/_internal/operations/build/__init__.py => python3.9/site-packages/click/py.typed} (100%) create mode 100644 venv/lib/python3.9/site-packages/click/shell_completion.py create mode 100644 venv/lib/python3.9/site-packages/click/termui.py create mode 100644 venv/lib/python3.9/site-packages/click/testing.py create mode 100644 venv/lib/python3.9/site-packages/click/types.py create mode 100644 venv/lib/python3.9/site-packages/click/utils.py rename venv/lib/{python3.8 => python3.9}/site-packages/easy_install.py (100%) create mode 100644 venv/lib/python3.9/site-packages/flask/__init__.py create mode 100644 venv/lib/python3.9/site-packages/flask/__main__.py create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/__main__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/app.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/blueprints.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/cli.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/config.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/ctx.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/debughelpers.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/globals.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/helpers.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/logging.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/scaffold.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/sessions.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/signals.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/templating.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/testing.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/typing.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/views.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/__pycache__/wrappers.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/app.py create mode 100644 venv/lib/python3.9/site-packages/flask/blueprints.py create mode 100644 venv/lib/python3.9/site-packages/flask/cli.py create mode 100644 venv/lib/python3.9/site-packages/flask/config.py create mode 100644 venv/lib/python3.9/site-packages/flask/ctx.py create mode 100644 venv/lib/python3.9/site-packages/flask/debughelpers.py create mode 100644 venv/lib/python3.9/site-packages/flask/globals.py create mode 100644 venv/lib/python3.9/site-packages/flask/helpers.py create mode 100644 venv/lib/python3.9/site-packages/flask/json/__init__.py create mode 100644 venv/lib/python3.9/site-packages/flask/json/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/json/__pycache__/tag.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/flask/json/tag.py create mode 100644 venv/lib/python3.9/site-packages/flask/logging.py rename venv/lib/{python3.8/site-packages/pip/_internal/utils/__init__.py => python3.9/site-packages/flask/py.typed} (100%) create mode 100644 venv/lib/python3.9/site-packages/flask/scaffold.py create mode 100644 venv/lib/python3.9/site-packages/flask/sessions.py create mode 100644 venv/lib/python3.9/site-packages/flask/signals.py create mode 100644 venv/lib/python3.9/site-packages/flask/templating.py create mode 100644 venv/lib/python3.9/site-packages/flask/testing.py create mode 100644 venv/lib/python3.9/site-packages/flask/typing.py create mode 100644 venv/lib/python3.9/site-packages/flask/views.py create mode 100644 venv/lib/python3.9/site-packages/flask/wrappers.py create mode 100644 venv/lib/python3.9/site-packages/itsdangerous-2.0.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.9/site-packages/itsdangerous-2.0.1.dist-info/LICENSE.rst create mode 100644 venv/lib/python3.9/site-packages/itsdangerous-2.0.1.dist-info/METADATA create mode 100644 venv/lib/python3.9/site-packages/itsdangerous-2.0.1.dist-info/RECORD create mode 100644 venv/lib/python3.9/site-packages/itsdangerous-2.0.1.dist-info/WHEEL create mode 100644 venv/lib/python3.9/site-packages/itsdangerous-2.0.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/__init__.py create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/__pycache__/_json.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/__pycache__/encoding.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/__pycache__/exc.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/__pycache__/jws.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/__pycache__/serializer.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/__pycache__/signer.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/__pycache__/timed.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/__pycache__/url_safe.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/_json.py create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/encoding.py create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/exc.py create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/jws.py rename venv/lib/{python3.8/site-packages/pkg_resources/_vendor/__init__.py => python3.9/site-packages/itsdangerous/py.typed} (100%) create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/serializer.py create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/signer.py create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/timed.py create mode 100644 venv/lib/python3.9/site-packages/itsdangerous/url_safe.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/__init__.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/_identifier.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/async_utils.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/bccache.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/compiler.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/constants.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/debug.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/defaults.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/environment.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/exceptions.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/ext.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/filters.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/idtracking.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/lexer.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/loaders.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/meta.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/nativetypes.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/nodes.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/optimizer.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/parser.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/runtime.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/sandbox.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/tests.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/utils.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/__pycache__/visitor.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/jinja2/_identifier.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/async_utils.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/bccache.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/compiler.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/constants.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/debug.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/defaults.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/environment.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/exceptions.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/ext.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/filters.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/idtracking.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/lexer.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/loaders.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/meta.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/nativetypes.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/nodes.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/optimizer.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/parser.py rename venv/lib/{python3.8/site-packages/setuptools/_vendor/__init__.py => python3.9/site-packages/jinja2/py.typed} (100%) create mode 100644 venv/lib/python3.9/site-packages/jinja2/runtime.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/sandbox.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/tests.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/utils.py create mode 100644 venv/lib/python3.9/site-packages/jinja2/visitor.py create mode 100644 venv/lib/python3.9/site-packages/markupsafe/__init__.py create mode 100644 venv/lib/python3.9/site-packages/markupsafe/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/markupsafe/__pycache__/_native.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/markupsafe/_native.py create mode 100644 venv/lib/python3.9/site-packages/markupsafe/_speedups.c create mode 100755 venv/lib/python3.9/site-packages/markupsafe/_speedups.cpython-39-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.9/site-packages/markupsafe/_speedups.pyi create mode 100644 venv/lib/python3.9/site-packages/markupsafe/py.typed create mode 100644 venv/lib/python3.9/site-packages/pip-20.3.4.dist-info/INSTALLER rename venv/lib/{python3.8/site-packages/pip-20.0.2.dist-info => python3.9/site-packages/pip-20.3.4.dist-info}/LICENSE.txt (94%) rename venv/lib/{python3.8/site-packages/pip-20.0.2.dist-info => python3.9/site-packages/pip-20.3.4.dist-info}/METADATA (61%) create mode 100644 venv/lib/python3.9/site-packages/pip-20.3.4.dist-info/RECORD create mode 100644 venv/lib/python3.9/site-packages/pip-20.3.4.dist-info/REQUESTED rename venv/lib/{python3.8/site-packages/pip-20.0.2.dist-info => python3.9/site-packages/pip-20.3.4.dist-info}/WHEEL (100%) rename venv/lib/{python3.8/site-packages/pip-20.0.2.dist-info => python3.9/site-packages/pip-20.3.4.dist-info}/entry_points.txt (70%) create mode 100644 venv/lib/python3.9/site-packages/pip-20.3.4.dist-info/top_level.txt rename venv/lib/{python3.8 => python3.9}/site-packages/pip/__init__.py (94%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/__main__.py (69%) rename venv/lib/{python3.8/site-packages/pip/__pycache__/__init__.cpython-38.pyc => python3.9/site-packages/pip/__pycache__/__init__.cpython-39.pyc} (62%) create mode 100644 venv/lib/python3.9/site-packages/pip/__pycache__/__main__.cpython-39.pyc rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/__init__.py (88%) rename venv/lib/{python3.8/site-packages/pip/_internal/__pycache__/__init__.cpython-38.pyc => python3.9/site-packages/pip/_internal/__pycache__/__init__.cpython-39.pyc} (54%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/__pycache__/build_env.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/__pycache__/cache.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/__pycache__/configuration.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/__pycache__/exceptions.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/__pycache__/locations.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/__pycache__/main.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/__pycache__/pyproject.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-39.pyc rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/build_env.py (83%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/cache.py (88%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/cli/__init__.py (100%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/main.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/parser.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-39.pyc rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/cli/autocompletion.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/cli/base_command.py (72%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/cli/cmdoptions.py (86%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/cli/command_context.py (94%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/cli/main.py (98%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/cli/main_parser.py (89%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/cli/parser.py (78%) rename venv/lib/{python3.8/site-packages/pip/_internal/utils/ui.py => python3.9/site-packages/pip/_internal/cli/progress_bars.py} (51%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/cli/req_command.py (61%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/cli/spinners.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/cli/status_codes.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/commands/__init__.py (90%) rename venv/lib/{python3.8/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-38.pyc => python3.9/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-39.pyc} (61%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/cache.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/check.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/completion.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/debug.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/download.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/hash.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/help.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/install.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/list.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/search.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/show.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/cache.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/commands/check.py (82%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/commands/completion.py (63%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/commands/configuration.py (65%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/debug.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/download.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/commands/freeze.py (77%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/commands/hash.py (75%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/commands/help.py (69%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/commands/install.py (51%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/commands/list.py (78%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/commands/search.py (75%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/commands/show.py (92%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/commands/uninstall.py (76%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/commands/wheel.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/configuration.py (85%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/distributions/__init__.py (100%) rename venv/lib/{python3.8/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc => python3.9/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-39.pyc} (65%) rename venv/lib/{python3.8/site-packages/pip/_internal/distributions/__pycache__/base.cpython-38.pyc => python3.9/site-packages/pip/_internal/distributions/__pycache__/base.cpython-39.pyc} (61%) rename venv/lib/{python3.8/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-38.pyc => python3.9/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-39.pyc} (50%) rename venv/lib/{python3.8/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-38.pyc => python3.9/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-39.pyc} (56%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-39.pyc rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/distributions/base.py (99%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/distributions/installed.py (99%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/distributions/sdist.py (99%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/distributions/wheel.py (99%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/exceptions.py (71%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/index/__init__.py (100%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/index/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/index/__pycache__/collector.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-39.pyc rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/index/collector.py (70%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/index/package_finder.py (95%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/locations.py (94%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/main.py (91%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/models/__init__.py (100%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/candidate.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/format_control.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/index.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/link.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/scheme.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/target_python.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/models/__pycache__/wheel.cpython-39.pyc rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/models/candidate.py (96%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/models/direct_url.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/models/format_control.py (85%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/models/index.py (91%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/models/link.py (87%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/models/scheme.py (87%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/models/search_scope.py (78%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/models/selection_prefs.py (93%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/models/target_python.py (74%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/models/wheel.py (97%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/network/__init__.py (100%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/auth.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/cache.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/download.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/session.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/utils.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-39.pyc rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/network/auth.py (92%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/network/cache.py (94%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/network/download.py (64%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/network/lazy_wheel.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/network/session.py (91%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/network/utils.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/network/xmlrpc.py (73%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/__init__.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/check.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/build/__init__.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-39.pyc rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/operations/build/metadata.py (96%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/build/metadata_legacy.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/operations/build/wheel.py (95%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/operations/build/wheel_legacy.py (93%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/operations/check.py (88%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/operations/freeze.py (85%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/operations/install/__init__.py (100%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-38.pyc => python3.9/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-39.pyc} (63%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-39.pyc rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/operations/install/editable_legacy.py (100%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/install/legacy.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/operations/prepare.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/pyproject.py (99%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/req/__init__.py (54%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/constructors.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_file.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_install.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_set.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-39.pyc rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/req/constructors.py (72%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/req/req_file.py (72%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/req/req_install.py (72%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/req/req_set.py (83%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/req/req_tracker.py (96%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/req/req_uninstall.py (97%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/__init__.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/__pycache__/base.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/base.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pip/_internal/legacy_resolve.py => python3.9/site-packages/pip/_internal/resolution/legacy/resolver.py} (77%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/reporter.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/resolver.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/self_outdated_check.py (79%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__init__.py create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/compat.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-38.pyc => python3.9/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-39.pyc} (66%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-38.pyc => python3.9/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-39.pyc} (80%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-38.pyc => python3.9/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-39.pyc} (52%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pip/_internal/utils/__pycache__/logging.cpython-38.pyc => python3.9/site-packages/pip/_internal/utils/__pycache__/logging.cpython-39.pyc} (51%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/misc.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/models.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-38.pyc => python3.9/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-39.pyc} (61%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/parallel.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pip/_internal/utils/__pycache__/pkg_resources.cpython-38.pyc => python3.9/site-packages/pip/_internal/utils/__pycache__/pkg_resources.cpython-39.pyc} (67%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pip/_internal/utils/__pycache__/typing.cpython-38.pyc => python3.9/site-packages/pip/_internal/utils/__pycache__/typing.cpython-39.pyc} (79%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/urls.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-38.pyc => python3.9/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-39.pyc} (51%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/appdirs.py (80%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/compat.py (89%) rename venv/lib/{python3.8/site-packages/pip/_internal/pep425tags.py => python3.9/site-packages/pip/_internal/utils/compatibility_tags.py} (87%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/datetime.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/deprecation.py (100%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/direct_url_helpers.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/distutils_args.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/encoding.py (83%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/entrypoints.py (96%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/filesystem.py (69%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/filetypes.py (67%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/glibc.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/hashes.py (68%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/inject_securetransport.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/logging.py (98%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/misc.py (84%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/models.py (95%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/packaging.py (99%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/utils/parallel.py rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/pkg_resources.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/setuptools_build.py (97%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/subprocess.py (78%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/temp_dir.py (81%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/typing.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/unpacking.py (91%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/urls.py (90%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/virtualenv.py (90%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/utils/wheel.py (96%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/vcs/__init__.py (100%) create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/git.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-39.pyc rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/vcs/bazaar.py (95%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/vcs/git.py (83%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/vcs/mercurial.py (82%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/vcs/subversion.py (96%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/vcs/versioncontrol.py (90%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_internal/wheel_builder.py (72%) rename venv/lib/{python3.8 => python3.9}/site-packages/pip/_vendor/__init__.py (94%) create mode 100644 venv/lib/python3.9/site-packages/pip/_vendor/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pip/_vendor/vendor.txt create mode 100644 venv/lib/python3.9/site-packages/pkg_resources-0.0.0.dist-info/AUTHORS.txt create mode 100644 venv/lib/python3.9/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER rename venv/lib/{python3.8/site-packages/setuptools-44.0.0.dist-info => python3.9/site-packages/pkg_resources-0.0.0.dist-info}/LICENSE.txt (94%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources-0.0.0.dist-info/METADATA (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources-0.0.0.dist-info/RECORD (64%) create mode 100644 venv/lib/python3.9/site-packages/pkg_resources-0.0.0.dist-info/REQUESTED rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources-0.0.0.dist-info/WHEEL (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/__init__.py (100%) rename venv/lib/{python3.8/site-packages/pkg_resources/__pycache__/__init__.cpython-38.pyc => python3.9/site-packages/pkg_resources/__pycache__/__init__.cpython-39.pyc} (70%) create mode 100644 venv/lib/python3.9/site-packages/pkg_resources/__pycache__/py31compat.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 venv/lib/python3.9/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-38.pyc => python3.9/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-39.pyc} (75%) rename venv/lib/{python3.8/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-38.pyc => python3.9/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-39.pyc} (76%) rename venv/lib/{python3.8/site-packages/setuptools/_vendor/__pycache__/six.cpython-38.pyc => python3.9/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-39.pyc} (50%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/_vendor/appdirs.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/_vendor/packaging/__about__.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/_vendor/packaging/__init__.py (100%) create mode 100644 venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-38.pyc => python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-39.pyc} (70%) rename venv/lib/{python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-38.pyc => python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-39.pyc} (77%) create mode 100644 venv/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-39.pyc rename venv/lib/{python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-38.pyc => python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-39.pyc} (79%) rename venv/lib/{python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc => python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc} (85%) rename venv/lib/{python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-38.pyc => python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-39.pyc} (54%) rename venv/lib/{python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-38.pyc => python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-39.pyc} (78%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/_vendor/packaging/_compat.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/_vendor/packaging/_structures.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/_vendor/packaging/markers.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/_vendor/packaging/requirements.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/_vendor/packaging/specifiers.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/_vendor/packaging/utils.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/_vendor/packaging/version.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/_vendor/pyparsing.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/_vendor/six.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/extern/__init__.py (100%) rename venv/lib/{python3.8/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-38.pyc => python3.9/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-39.pyc} (79%) rename venv/lib/{python3.8 => python3.9}/site-packages/pkg_resources/py31compat.py (100%) create mode 100644 venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/AUTHORS.txt create mode 100644 venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/INSTALLER rename venv/lib/{python3.8/site-packages/pkg_resources-0.0.0.dist-info => python3.9/site-packages/setuptools-44.1.1.dist-info}/LICENSE.txt (94%) rename venv/lib/{python3.8/site-packages/setuptools-44.0.0.dist-info => python3.9/site-packages/setuptools-44.1.1.dist-info}/METADATA (99%) rename venv/lib/{python3.8/site-packages/setuptools-44.0.0.dist-info => python3.9/site-packages/setuptools-44.1.1.dist-info}/RECORD (51%) create mode 100644 venv/lib/python3.9/site-packages/setuptools-44.1.1.dist-info/REQUESTED rename venv/lib/{python3.8/site-packages/setuptools-44.0.0.dist-info => python3.9/site-packages/setuptools-44.1.1.dist-info}/WHEEL (100%) rename venv/lib/{python3.8/site-packages/setuptools-44.0.0.dist-info => python3.9/site-packages/setuptools-44.1.1.dist-info}/dependency_links.txt (100%) rename venv/lib/{python3.8/site-packages/setuptools-44.0.0.dist-info => python3.9/site-packages/setuptools-44.1.1.dist-info}/entry_points.txt (100%) rename venv/lib/{python3.8/site-packages/setuptools-44.0.0.dist-info => python3.9/site-packages/setuptools-44.1.1.dist-info}/top_level.txt (100%) rename venv/lib/{python3.8/site-packages/setuptools-44.0.0.dist-info => python3.9/site-packages/setuptools-44.1.1.dist-info}/zip-safe (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/__init__.py (91%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/_imp.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/_imp.cpython-39.pyc} (76%) rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/archive_util.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/archive_util.cpython-39.pyc} (54%) rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/build_meta.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/build_meta.cpython-39.pyc} (52%) rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/config.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/config.cpython-39.pyc} (64%) rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/dep_util.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/dep_util.cpython-39.pyc} (62%) rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/depends.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/depends.cpython-39.pyc} (59%) rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/dist.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/dist.cpython-39.pyc} (66%) rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/errors.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/errors.cpython-39.pyc} (61%) rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/extension.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/extension.cpython-39.pyc} (71%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/glob.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/installer.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/launch.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/launch.cpython-39.pyc} (74%) rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-39.pyc} (66%) rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/monkey.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/monkey.cpython-39.pyc} (83%) rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/msvc.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/msvc.cpython-39.pyc} (67%) rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/namespaces.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/namespaces.cpython-39.pyc} (84%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/package_index.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/py27compat.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/py27compat.cpython-39.pyc} (69%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/py31compat.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/py33compat.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/py33compat.cpython-39.pyc} (54%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/py34compat.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/sandbox.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/site-patch.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/ssl_support.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/unicode_utils.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/version.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/setuptools/__pycache__/wheel.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/__pycache__/windows_support.cpython-38.pyc => python3.9/site-packages/setuptools/__pycache__/windows_support.cpython-39.pyc} (60%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_deprecation_warning.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_imp.py (100%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/_vendor/__init__.py create mode 100644 venv/lib/python3.9/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-38.pyc => python3.9/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-39.pyc} (70%) rename venv/lib/{python3.8/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-38.pyc => python3.9/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-39.pyc} (76%) rename venv/lib/{python3.8/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-38.pyc => python3.9/site-packages/setuptools/_vendor/__pycache__/six.cpython-39.pyc} (50%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/ordered_set.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/packaging/__about__.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/packaging/__init__.py (100%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-38.pyc => python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-39.pyc} (70%) rename venv/lib/{python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-38.pyc => python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-39.pyc} (77%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-38.pyc => python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-39.pyc} (78%) rename venv/lib/{python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc => python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc} (85%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-38.pyc => python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-39.pyc} (71%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/packaging/_compat.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/packaging/_structures.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/packaging/markers.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/packaging/requirements.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/packaging/specifiers.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/packaging/tags.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/packaging/utils.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/packaging/version.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/pyparsing.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/_vendor/six.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/archive_util.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/build_meta.py (97%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/cli-32.exe (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/cli-64.exe (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/cli.exe (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/__init__.py (100%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/command/__pycache__/__init__.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/alias.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/alias.cpython-39.pyc} (81%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-39.pyc} (64%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-39.pyc} (74%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/build_clib.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/build_clib.cpython-39.pyc} (87%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/command/__pycache__/build_ext.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/build_py.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/build_py.cpython-39.pyc} (84%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/develop.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/develop.cpython-39.pyc} (64%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/dist_info.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/dist_info.cpython-39.pyc} (79%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/easy_install.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/easy_install.cpython-39.pyc} (53%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/egg_info.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/egg_info.cpython-39.pyc} (67%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/install.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/install.cpython-39.pyc} (64%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-39.pyc} (60%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/install_lib.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/install_lib.cpython-39.pyc} (73%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/install_scripts.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/install_scripts.cpython-39.pyc} (82%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/py36compat.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/py36compat.cpython-39.pyc} (91%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/register.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/register.cpython-39.pyc} (75%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/command/__pycache__/rotate.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/saveopts.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/saveopts.cpython-39.pyc} (76%) create mode 100644 venv/lib/python3.9/site-packages/setuptools/command/__pycache__/sdist.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/setuptools/command/__pycache__/setopt.cpython-39.pyc rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/test.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/test.cpython-39.pyc} (58%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/upload.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/upload.cpython-39.pyc} (75%) rename venv/lib/{python3.8/site-packages/setuptools/command/__pycache__/upload_docs.cpython-38.pyc => python3.9/site-packages/setuptools/command/__pycache__/upload_docs.cpython-39.pyc} (60%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/alias.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/bdist_egg.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/bdist_rpm.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/bdist_wininst.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/build_clib.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/build_ext.py (99%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/build_py.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/develop.py (99%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/dist_info.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/easy_install.py (99%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/egg_info.py (99%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/install.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/install_egg_info.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/install_lib.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/install_scripts.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/launcher manifest.xml (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/py36compat.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/register.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/rotate.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/saveopts.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/sdist.py (99%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/setopt.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/test.py (98%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/upload.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/command/upload_docs.py (98%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/config.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/dep_util.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/depends.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/dist.py (99%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/errors.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/extension.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/extern/__init__.py (100%) rename venv/lib/{python3.8/site-packages/setuptools/extern/__pycache__/__init__.cpython-38.pyc => python3.9/site-packages/setuptools/extern/__pycache__/__init__.cpython-39.pyc} (80%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/glob.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/gui-32.exe (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/gui-64.exe (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/gui.exe (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/installer.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/launch.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/lib2to3_ex.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/monkey.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/msvc.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/namespaces.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/package_index.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/py27compat.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/py31compat.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/py33compat.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/py34compat.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/sandbox.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/script (dev).tmpl (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/script.tmpl (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/site-patch.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/ssl_support.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/unicode_utils.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/version.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/wheel.py (100%) rename venv/lib/{python3.8 => python3.9}/site-packages/setuptools/windows_support.py (100%) create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__init__.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/_internal.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/_reloader.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/datastructures.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/exceptions.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/filesystem.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/formparser.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/http.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/local.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/routing.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/security.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/serving.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/test.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/testapp.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/urls.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/user_agent.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/useragents.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/utils.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/__pycache__/wsgi.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/_internal.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/_reloader.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/datastructures.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/datastructures.pyi create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/__init__.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/__pycache__/console.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/__pycache__/repr.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/console.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/repr.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/shared/FONT_LICENSE create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/shared/ICON_LICENSE.md create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/shared/console.png create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/shared/less.png create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/shared/more.png create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/shared/source.png create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/shared/style.css create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/shared/ubuntu.ttf create mode 100644 venv/lib/python3.9/site-packages/werkzeug/debug/tbtools.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/exceptions.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/filesystem.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/formparser.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/http.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/local.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/__init__.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/lint.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/dispatcher.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/http_proxy.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/lint.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/profiler.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/proxy_fix.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/middleware/shared_data.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/py.typed create mode 100644 venv/lib/python3.9/site-packages/werkzeug/routing.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/sansio/__init__.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/request.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/response.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/utils.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/sansio/multipart.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/sansio/request.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/sansio/response.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/sansio/utils.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/security.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/serving.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/test.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/testapp.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/urls.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/user_agent.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/useragents.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/utils.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__init__.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/accept.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/auth.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/base_request.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/base_response.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/common_descriptors.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/cors.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/etag.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/json.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/request.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/response.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/user_agent.cpython-39.pyc create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/accept.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/auth.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/base_request.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/base_response.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/common_descriptors.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/cors.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/etag.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/json.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/request.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/response.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wrappers/user_agent.py create mode 100644 venv/lib/python3.9/site-packages/werkzeug/wsgi.py create mode 100644 venv/requirements.txt delete mode 100644 venv/share/python-wheels/appdirs-1.4.3-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/appdirs-1.4.4-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/certifi-2019.11.28-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/certifi-2020.6.20-py2.py3-none-any.whl rename venv/share/python-wheels/{chardet-3.0.4-py2.py3-none-any.whl => chardet-4.0.0-py2.py3-none-any.whl} (50%) delete mode 100644 venv/share/python-wheels/colorama-0.4.3-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/colorama-0.4.4-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/contextlib2-0.6.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/contextlib2-0.6.0.post1-py2.py3-none-any.whl rename venv/share/python-wheels/{distlib-0.3.0-py2.py3-none-any.whl => distlib-0.3.1-py2.py3-none-any.whl} (59%) delete mode 100644 venv/share/python-wheels/distro-1.4.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/distro-1.5.0-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/html5lib-1.0.1-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/html5lib-1.1-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/idna-2.10-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/idna-2.8-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/lockfile-0.12.2-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/msgpack-0.6.2-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/msgpack-1.0.0-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/packaging-20.3-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/packaging-20.9-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/pep517-0.8.2-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/pep517-0.9.1-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/pip-20.0.2-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/pip-20.3.4-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/pyparsing-2.4.6-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/pyparsing-2.4.7-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/requests-2.22.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/requests-2.25.1-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/resolvelib-0.5.4-py2.py3-none-any.whl rename venv/share/python-wheels/{setuptools-44.0.0-py2.py3-none-any.whl => setuptools-44.1.1-py2.py3-none-any.whl} (85%) delete mode 100644 venv/share/python-wheels/six-1.14.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/six-1.16.0-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/toml-0.10.0-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/toml-0.10.1-py2.py3-none-any.whl delete mode 100644 venv/share/python-wheels/urllib3-1.25.8-py2.py3-none-any.whl create mode 100644 venv/share/python-wheels/urllib3-1.26.5-py2.py3-none-any.whl create mode 100644 venv/vercel.json diff --git a/venv/.vercel/README.txt b/venv/.vercel/README.txt new file mode 100644 index 0000000..525d8ce --- /dev/null +++ b/venv/.vercel/README.txt @@ -0,0 +1,11 @@ +> Why do I have a folder named ".vercel" in my project? +The ".vercel" folder is created when you link a directory to a Vercel project. + +> What does the "project.json" file contain? +The "project.json" file contains: +- The ID of the Vercel project that you linked ("projectId") +- The ID of the user or team your Vercel project is owned by ("orgId") + +> Should I commit the ".vercel" folder? +No, you should not share the ".vercel" folder with anyone. +Upon creation, it will be automatically added to your ".gitignore" file. diff --git a/venv/.vercel/project.json b/venv/.vercel/project.json new file mode 100644 index 0000000..4ae7116 --- /dev/null +++ b/venv/.vercel/project.json @@ -0,0 +1 @@ +{"orgId":"RXDy9fsHHUMdP3Y9CCzxaa7w","projectId":"prj_fhKjryWYHXc2me4RvhUk0RTMRgSR"} \ No newline at end of file diff --git a/venv/__pycache__/index.cpython-38.pyc b/venv/__pycache__/index.cpython-38.pyc deleted file mode 100644 index 3eafaacd7f4e4f49f2b005cccb06981c74d06381..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 531 zcmY*Vu};G<5WRDpCM^YaCM2dTgoUj_NJxmOf))ho5+dwEAc=z$P+QRnR@7f;#l$ap zWnw^LX5yTMa?+jep5vEy?`(Co1r)RU@5?VbKkTp^4h{R1WrvCYfhlA-Km>`BJ>$TU z&YTOjK;a1f0))6V;u6vjUX3(_--n?2NemF6aSzkDy!*lM$^y%QG#pTtoQgnt#JZF9 zBbCX`)`_S8cq-$C2!zw)ycYNe|1G|94Yc&v0aRB58ZN0~o{NiO7QyBHgOLo}Wx zXHfh#uT1ljtiLL6P^QuT{wXryg|P{FUTO$ z%)67Oh^u(}wp6)6O)K+E2^lcMRUvc3wTwl;23|IfhDj<7ujHuuTS&X~TjP+j6>3T= z6xbU2sN2+a1JAfaYoWGUjUPpMoXIG%FAC#oYf`;k{rM7YZClOlcSz7fD)+48rCqn} J_>PY)%3rvfZV3PY diff --git a/venv/__pycache__/index.cpython-39.pyc b/venv/__pycache__/index.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..563b03cefaa03e721f164729696a9152b6c0d8b5 GIT binary patch literal 1000 zcma)5F>ezw6n^&kl1oUMwn8j0biE~pJwioAz!X(d9?UgCE{A7RU=kI&=ccR;E1GeME@8cf?;HO{ITZD^!9F@T!L6SM- zWJCxkqUa?VMJl>tl3o)TN%jR0i31WN(vZ!7Gy;+!(vt0fGz0Pok&f&JBnikCB0aes zke1vzf^_#6@a1U`9P`Od z&q^@>H4TjG1{WvDwwc83SAK6z_Mge^1Yt${sWv?bbzEX`bxh& zyMS}JBG+(1&dCR$XkUi?G9qvUFQDo_2NL>6j1sYw4c9FxtmuEPbm53W+p%0rl~Tua zsS3x85;CQuX1*Fvv$=B2sx$llYelH?DQc;_CxC8|gqR-AhH2ZyQ*UGAb-QFdE<~=z xV}}`~i;XvGFp}}lYkXnG7ap=}EWyda7|8(jE#~T_{|PF8VVx+664GW5#~ /dev/null fi if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then @@ -37,7 +37,7 @@ deactivate () { # unset irrelevant variables deactivate nondestructive -VIRTUAL_ENV="/root/Timmy/Portfolio/venv" +VIRTUAL_ENV="/home/timothypidashev/Desktop/Github/Portfolio/venv" export VIRTUAL_ENV _OLD_VIRTUAL_PATH="$PATH" @@ -54,17 +54,7 @@ fi if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then _OLD_VIRTUAL_PS1="${PS1:-}" - if [ "x(venv) " != x ] ; then - PS1="(venv) ${PS1:-}" - else - if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then - # special case for Aspen magic directories - # see https://aspen.io/ - PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" - else - PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" - fi - fi + PS1="(venv) ${PS1:-}" export PS1 fi @@ -72,5 +62,5 @@ fi # 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 + hash -r 2> /dev/null fi diff --git a/venv/bin/activate.csh b/venv/bin/activate.csh index 45fa7b7..0664f16 100644 --- a/venv/bin/activate.csh +++ b/venv/bin/activate.csh @@ -8,7 +8,7 @@ alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PA # Unset irrelevant variables. deactivate nondestructive -setenv VIRTUAL_ENV "/root/Timmy/Portfolio/venv" +setenv VIRTUAL_ENV "/home/timothypidashev/Desktop/Github/Portfolio/venv" set _OLD_VIRTUAL_PATH="$PATH" setenv PATH "$VIRTUAL_ENV/bin:$PATH" @@ -17,19 +17,7 @@ setenv PATH "$VIRTUAL_ENV/bin:$PATH" set _OLD_VIRTUAL_PROMPT="$prompt" if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then - if ("venv" != "") then - set env_name = "venv" - else - if (`basename "VIRTUAL_ENV"` == "__") then - # special case for Aspen magic directories - # see https://aspen.io/ - set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` - else - set env_name = `basename "$VIRTUAL_ENV"` - endif - endif - set prompt = "[$env_name] $prompt" - unset env_name + set prompt = "(venv) $prompt" endif alias pydoc python -m pydoc diff --git a/venv/bin/activate.fish b/venv/bin/activate.fish index 6f58608..af07f91 100644 --- a/venv/bin/activate.fish +++ b/venv/bin/activate.fish @@ -1,7 +1,7 @@ -# This file must be used with ". bin/activate.fish" *from fish* (http://fishshell.org) -# you cannot run it directly +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/); you cannot run it directly. -function deactivate -d "Exit virtualenv and return to normal shell environment" +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 @@ -21,20 +21,20 @@ function deactivate -d "Exit virtualenv and return to normal shell environment" set -e VIRTUAL_ENV if test "$argv[1]" != "nondestructive" - # Self destruct! + # Self-destruct! functions -e deactivate end end -# unset irrelevant variables +# Unset irrelevant variables. deactivate nondestructive -set -gx VIRTUAL_ENV "/root/Timmy/Portfolio/venv" +set -gx VIRTUAL_ENV "/home/timothypidashev/Desktop/Github/Portfolio/venv" set -gx _OLD_VIRTUAL_PATH $PATH set -gx PATH "$VIRTUAL_ENV/bin" $PATH -# unset PYTHONHOME if set +# Unset PYTHONHOME if set. if set -q PYTHONHOME set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME set -e PYTHONHOME @@ -43,31 +43,20 @@ 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 + # 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. + # With the original prompt function renamed, we can override with our own. function fish_prompt - # Save the return status of the last command + # Save the return status of the last command. set -l old_status $status - # Prompt override? - if test -n "(venv) " - printf "%s%s" "(venv) " (set_color normal) - else - # ...Otherwise, prepend env - set -l _checkbase (basename "$VIRTUAL_ENV") - if test $_checkbase = "__" - # special case for Aspen magic directories - # see https://aspen.io/ - printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) - else - printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) - end - end + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) "(venv) " (set_color normal) # Restore the return status of the previous command. echo "exit $old_status" | . + # Output the original/"old" prompt. _old_fish_prompt end diff --git a/venv/bin/easy_install b/venv/bin/easy_install index 0b4de29..5bcfd00 100755 --- a/venv/bin/easy_install +++ b/venv/bin/easy_install @@ -1,4 +1,4 @@ -#!/root/Timmy/Portfolio/venv/bin/python3 +#!/home/timothypidashev/Desktop/Github/Portfolio/venv/bin/python3 # -*- coding: utf-8 -*- import re import sys diff --git a/venv/bin/easy_install-3.8 b/venv/bin/easy_install-3.9 similarity index 76% rename from venv/bin/easy_install-3.8 rename to venv/bin/easy_install-3.9 index 0b4de29..5bcfd00 100755 --- a/venv/bin/easy_install-3.8 +++ b/venv/bin/easy_install-3.9 @@ -1,4 +1,4 @@ -#!/root/Timmy/Portfolio/venv/bin/python3 +#!/home/timothypidashev/Desktop/Github/Portfolio/venv/bin/python3 # -*- coding: utf-8 -*- import re import sys diff --git a/venv/bin/flask b/venv/bin/flask new file mode 100755 index 0000000..3dd4ec7 --- /dev/null +++ b/venv/bin/flask @@ -0,0 +1,8 @@ +#!/home/timothypidashev/Desktop/Github/Portfolio/venv/bin/python3 +# -*- coding: utf-8 -*- +import re +import sys +from flask.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip b/venv/bin/pip index 9b7c2d4..90c8b2d 100755 --- a/venv/bin/pip +++ b/venv/bin/pip @@ -1,4 +1,4 @@ -#!/root/Timmy/Portfolio/venv/bin/python3 +#!/home/timothypidashev/Desktop/Github/Portfolio/venv/bin/python3 # -*- coding: utf-8 -*- import re import sys diff --git a/venv/bin/pip3 b/venv/bin/pip3 index 9b7c2d4..90c8b2d 100755 --- a/venv/bin/pip3 +++ b/venv/bin/pip3 @@ -1,4 +1,4 @@ -#!/root/Timmy/Portfolio/venv/bin/python3 +#!/home/timothypidashev/Desktop/Github/Portfolio/venv/bin/python3 # -*- coding: utf-8 -*- import re import sys diff --git a/venv/bin/pip3.8 b/venv/bin/pip3.9 similarity index 75% rename from venv/bin/pip3.8 rename to venv/bin/pip3.9 index 9b7c2d4..90c8b2d 100755 --- a/venv/bin/pip3.8 +++ b/venv/bin/pip3.9 @@ -1,4 +1,4 @@ -#!/root/Timmy/Portfolio/venv/bin/python3 +#!/home/timothypidashev/Desktop/Github/Portfolio/venv/bin/python3 # -*- coding: utf-8 -*- import re import sys diff --git a/venv/bin/python3.9 b/venv/bin/python3.9 new file mode 120000 index 0000000..b8a0adb --- /dev/null +++ b/venv/bin/python3.9 @@ -0,0 +1 @@ +python3 \ No newline at end of file diff --git a/venv/index.py b/venv/index.py index ca6e4bf..6a0f115 100644 --- a/venv/index.py +++ b/venv/index.py @@ -8,8 +8,3 @@ app = Flask(__name__) def home(): return "Home Page Route" -@app.route("/api") -def api(): - with open("data.json", mode="r") as my_file: - text = my_file.read() - return text diff --git a/venv/lib/python3.8/site-packages/__pycache__/easy_install.cpython-38.pyc b/venv/lib/python3.8/site-packages/__pycache__/easy_install.cpython-38.pyc deleted file mode 100644 index 0023f62633347ab966bb0b84d51ef8060beec069..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 281 zcmYj}y-LME5QXcl`;vP8XaA4+pSgrOM={ zpgm4FPGR)kr1~FFBSB&Kqee-LHx_rPe&hSJ8Et675UR-q)vZxiPd%ck&d-KE#1Nb9 X|2k~u{K9%Y8NB2KNed|xIX~b(7T-+x diff --git a/venv/lib/python3.8/site-packages/pip-20.0.2.dist-info/RECORD b/venv/lib/python3.8/site-packages/pip-20.0.2.dist-info/RECORD deleted file mode 100644 index d827547..0000000 --- a/venv/lib/python3.8/site-packages/pip-20.0.2.dist-info/RECORD +++ /dev/null @@ -1,246 +0,0 @@ -../../../bin/pip,sha256=l8VlFL3OA4W-3oO2OCK_spt6K5EliRh0o1Z-UAyxf88,243 -../../../bin/pip3,sha256=l8VlFL3OA4W-3oO2OCK_spt6K5EliRh0o1Z-UAyxf88,243 -../../../bin/pip3.8,sha256=l8VlFL3OA4W-3oO2OCK_spt6K5EliRh0o1Z-UAyxf88,243 -pip-20.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pip-20.0.2.dist-info/LICENSE.txt,sha256=W6Ifuwlk-TatfRU2LR7W1JMcyMj5_y1NkRkOEJvnRDE,1090 -pip-20.0.2.dist-info/METADATA,sha256=MSgjT2JTt8usp4Hopp5AGEmc-7sKR2Jd7HTMJqCoRhw,3352 -pip-20.0.2.dist-info/RECORD,, -pip-20.0.2.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110 -pip-20.0.2.dist-info/entry_points.txt,sha256=HtfDOwpUlr9s73jqLQ6wF9V0_0qvUXJwCBz7Vwx0Ue0,125 -pip-20.0.2.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pip/__init__.py,sha256=U1AM82iShMaw90K6Yq0Q2-AZ1EsOcqQLQRB-rxwFtII,455 -pip/__main__.py,sha256=NM95x7KuQr-lwPoTjAC0d_QzLJsJjpmAoxZg0mP8s98,632 -pip/__pycache__/__init__.cpython-38.pyc,, -pip/__pycache__/__main__.cpython-38.pyc,, -pip/_internal/__init__.py,sha256=j5fiII6yCeZjpW7_7wAVRMM4DwE-gyARGVU4yAADDeE,517 -pip/_internal/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/__pycache__/build_env.cpython-38.pyc,, -pip/_internal/__pycache__/cache.cpython-38.pyc,, -pip/_internal/__pycache__/configuration.cpython-38.pyc,, -pip/_internal/__pycache__/exceptions.cpython-38.pyc,, -pip/_internal/__pycache__/legacy_resolve.cpython-38.pyc,, -pip/_internal/__pycache__/locations.cpython-38.pyc,, -pip/_internal/__pycache__/main.cpython-38.pyc,, -pip/_internal/__pycache__/pep425tags.cpython-38.pyc,, -pip/_internal/__pycache__/pyproject.cpython-38.pyc,, -pip/_internal/__pycache__/self_outdated_check.cpython-38.pyc,, -pip/_internal/__pycache__/wheel_builder.cpython-38.pyc,, -pip/_internal/build_env.py,sha256=--aNgzIdYrCOclHMwoAdpclCpfdFE_jooRuCy5gczwg,7532 -pip/_internal/cache.py,sha256=16GrnDRLBQNlfKWIuIF6Sa-EFS78kez_w1WEjT3ykTI,11605 -pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132 -pip/_internal/cli/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc,, -pip/_internal/cli/__pycache__/base_command.cpython-38.pyc,, -pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc,, -pip/_internal/cli/__pycache__/command_context.cpython-38.pyc,, -pip/_internal/cli/__pycache__/main.cpython-38.pyc,, -pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc,, -pip/_internal/cli/__pycache__/parser.cpython-38.pyc,, -pip/_internal/cli/__pycache__/req_command.cpython-38.pyc,, -pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc,, -pip/_internal/cli/autocompletion.py,sha256=ekGNtcDI0p7rFVc-7s4T9Tbss4Jgb7vsB649XJIblRg,6547 -pip/_internal/cli/base_command.py,sha256=v6yl5XNRqye8BT9ep8wvpMu6lylP_Hu6D95r_HqbpbQ,7948 -pip/_internal/cli/cmdoptions.py,sha256=f1TVHuu_fR3lLlMo6b367H_GsWFv26tLI9cAS-kZfE0,28114 -pip/_internal/cli/command_context.py,sha256=ygMVoTy2jpNilKT-6416gFSQpaBtrKRBbVbi2fy__EU,975 -pip/_internal/cli/main.py,sha256=8iq3bHe5lxJTB2EvKOqZ38NS0MmoS79_S1kgj4QuH8A,2610 -pip/_internal/cli/main_parser.py,sha256=W9OWeryh7ZkqELohaFh0Ko9sB98ZkSeDmnYbOZ1imBc,2819 -pip/_internal/cli/parser.py,sha256=O9djTuYQuSfObiY-NU6p4MJCfWsRUnDpE2YGA_fwols,9487 -pip/_internal/cli/req_command.py,sha256=pAUAglpTn0mUA6lRs7KN71yOm1KDabD0ySVTQTqWTSA,12463 -pip/_internal/cli/status_codes.py,sha256=F6uDG6Gj7RNKQJUDnd87QKqI16Us-t-B0wPF_4QMpWc,156 -pip/_internal/commands/__init__.py,sha256=uTSj58QlrSKeXqCUSdL-eAf_APzx5BHy1ABxb0j5ZNE,3714 -pip/_internal/commands/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/commands/__pycache__/check.cpython-38.pyc,, -pip/_internal/commands/__pycache__/completion.cpython-38.pyc,, -pip/_internal/commands/__pycache__/configuration.cpython-38.pyc,, -pip/_internal/commands/__pycache__/debug.cpython-38.pyc,, -pip/_internal/commands/__pycache__/download.cpython-38.pyc,, -pip/_internal/commands/__pycache__/freeze.cpython-38.pyc,, -pip/_internal/commands/__pycache__/hash.cpython-38.pyc,, -pip/_internal/commands/__pycache__/help.cpython-38.pyc,, -pip/_internal/commands/__pycache__/install.cpython-38.pyc,, -pip/_internal/commands/__pycache__/list.cpython-38.pyc,, -pip/_internal/commands/__pycache__/search.cpython-38.pyc,, -pip/_internal/commands/__pycache__/show.cpython-38.pyc,, -pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc,, -pip/_internal/commands/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/commands/check.py,sha256=mgLNYT3bd6Kmynwh4zzcBmVlFZ-urMo40jTgk6U405E,1505 -pip/_internal/commands/completion.py,sha256=UFQvq0Q4_B96z1bvnQyMOq82aPSu05RejbLmqeTZjC0,2975 -pip/_internal/commands/configuration.py,sha256=6riioZjMhsNSEct7dE-X8SobGodk3WERKJvuyjBje4Q,7226 -pip/_internal/commands/debug.py,sha256=a8llax2hRkxgK-tvwdJgaCaZCYPIx0fDvrlMDoYr8bQ,4209 -pip/_internal/commands/download.py,sha256=zX_0-IeFb4C8dxSmGHxk-6H5kehtyTSsdWpjNpAhSww,5007 -pip/_internal/commands/freeze.py,sha256=QS-4ib8jbKJ2wrDaDbTuyaB3Y_iJ5CQC2gAVHuAv9QU,3481 -pip/_internal/commands/hash.py,sha256=47teimfAPhpkaVbSDaafck51BT3XXYuL83lAqc5lOcE,1735 -pip/_internal/commands/help.py,sha256=Nhecq--ydFn80Gm1Zvbf9943EcRJfO0TnXUhsF0RO7s,1181 -pip/_internal/commands/install.py,sha256=T4P3J1rw7CQrZX4OUamtcoWMkTrJBfUe6gWpTfZW1bQ,27286 -pip/_internal/commands/list.py,sha256=2l0JiqHxjxDHNTCb2HZOjwwdo4duS1R0MsqZb6HSMKk,10660 -pip/_internal/commands/search.py,sha256=7Il8nKZ9mM7qF5jlnBoPvSIFY9f-0-5IbYoX3miTuZY,5148 -pip/_internal/commands/show.py,sha256=Vzsj2oX0JBl94MPyF3LV8YoMcigl8B2UsMM8zp0pH2s,6792 -pip/_internal/commands/uninstall.py,sha256=8mldFbrQecSoWDZRqxBgJkrlvx6Y9Iy7cs-2BIgtXt4,2983 -pip/_internal/commands/wheel.py,sha256=TMU5ZhjLo7BIZQApGPsYfoCsbGTnvP-N9jkgPJXhj1Y,7170 -pip/_internal/configuration.py,sha256=MgKrLFBJBkF3t2VJM4tvlnEspfSuS4scp_LhHWh53nY,14222 -pip/_internal/distributions/__init__.py,sha256=ECBUW5Gtu9TjJwyFLvim-i6kUMYVuikNh9I5asL6tbA,959 -pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/distributions/__pycache__/base.cpython-38.pyc,, -pip/_internal/distributions/__pycache__/installed.cpython-38.pyc,, -pip/_internal/distributions/__pycache__/sdist.cpython-38.pyc,, -pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/distributions/base.py,sha256=ruprpM_L2T2HNi3KLUHlbHimZ1sWVw-3Q0Lb8O7TDAI,1425 -pip/_internal/distributions/installed.py,sha256=YqlkBKr6TVP1MAYS6SG8ojud21wVOYLMZ8jMLJe9MSU,760 -pip/_internal/distributions/sdist.py,sha256=D4XTMlCwgPlK69l62GLYkNSVTVe99fR5iAcVt2EbGok,4086 -pip/_internal/distributions/wheel.py,sha256=95uD-TfaYoq3KiKBdzk9YMN4RRqJ28LNoSTS2K46gek,1294 -pip/_internal/exceptions.py,sha256=6YRuwXAK6F1iyUWKIkCIpWWN2khkAn1sZOgrFA9S8Ro,10247 -pip/_internal/index/__init__.py,sha256=vpt-JeTZefh8a-FC22ZeBSXFVbuBcXSGiILhQZJaNpQ,30 -pip/_internal/index/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/index/__pycache__/collector.cpython-38.pyc,, -pip/_internal/index/__pycache__/package_finder.cpython-38.pyc,, -pip/_internal/index/collector.py,sha256=YS7Ix4oylU7ZbPTPFugh-244GSRqMvdHsGUG6nmz2gE,17892 -pip/_internal/index/package_finder.py,sha256=2Rg75AOpLj8BN1jyL8EI-Iw-Hv6ibJkrYVARCht3bX8,37542 -pip/_internal/legacy_resolve.py,sha256=L7R72I7CjVgJlPTggmA1j4b-H8NmxNu_dKVhrpGXGps,16277 -pip/_internal/locations.py,sha256=VifFEqhc7FWFV8QGoEM3CpECRY8Doq7kTytytxsEgx0,6734 -pip/_internal/main.py,sha256=IVBnUQ-FG7DK6617uEXRB5_QJqspAsBFmTmTesYkbdQ,437 -pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63 -pip/_internal/models/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/models/__pycache__/candidate.cpython-38.pyc,, -pip/_internal/models/__pycache__/format_control.cpython-38.pyc,, -pip/_internal/models/__pycache__/index.cpython-38.pyc,, -pip/_internal/models/__pycache__/link.cpython-38.pyc,, -pip/_internal/models/__pycache__/scheme.cpython-38.pyc,, -pip/_internal/models/__pycache__/search_scope.cpython-38.pyc,, -pip/_internal/models/__pycache__/selection_prefs.cpython-38.pyc,, -pip/_internal/models/__pycache__/target_python.cpython-38.pyc,, -pip/_internal/models/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/models/candidate.py,sha256=Y58Bcm6oXUj0iS-yhmerlGo5CQJI2p0Ww9h6hR9zQDw,1150 -pip/_internal/models/format_control.py,sha256=ICzVjjGwfZYdX-eLLKHjMHLutEJlAGpfj09OG_eMqac,2673 -pip/_internal/models/index.py,sha256=K59A8-hVhBM20Xkahr4dTwP7OjkJyEqXH11UwHFVgqM,1060 -pip/_internal/models/link.py,sha256=y0H2ZOk0P6d1lfGUL2Pl09xFgZcRt5HwN2LElMifOpI,6827 -pip/_internal/models/scheme.py,sha256=vvhBrrno7eVDXcdKHiZWwxhPHf4VG5uSCEkC0QDR2RU,679 -pip/_internal/models/search_scope.py,sha256=2LXbU4wV8LwqdtXQXNXFYKv-IxiDI_QwSz9ZgbwtAfk,3898 -pip/_internal/models/selection_prefs.py,sha256=rPeif2KKjhTPXeMoQYffjqh10oWpXhdkxRDaPT1HO8k,1908 -pip/_internal/models/target_python.py,sha256=c-cFi6zCuo5HYbXNS3rVVpKRaHVh5yQlYEjEW23SidQ,3799 -pip/_internal/models/wheel.py,sha256=6KLuLKH5b0C5goWQXGSISRaq2UZtkHUEAU1y1Zsrwms,2766 -pip/_internal/network/__init__.py,sha256=jf6Tt5nV_7zkARBrKojIXItgejvoegVJVKUbhAa5Ioc,50 -pip/_internal/network/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/network/__pycache__/auth.cpython-38.pyc,, -pip/_internal/network/__pycache__/cache.cpython-38.pyc,, -pip/_internal/network/__pycache__/download.cpython-38.pyc,, -pip/_internal/network/__pycache__/session.cpython-38.pyc,, -pip/_internal/network/__pycache__/utils.cpython-38.pyc,, -pip/_internal/network/__pycache__/xmlrpc.cpython-38.pyc,, -pip/_internal/network/auth.py,sha256=K3G1ukKb3PiH8w_UnpXTz8qQsTULO-qdbfOE9zTo1fE,11119 -pip/_internal/network/cache.py,sha256=51CExcRkXWrgMZ7WsrZ6cmijKfViD5tVgKbBvJHO1IE,2394 -pip/_internal/network/download.py,sha256=3D9vdJmVwmCUMxzC-TaVI_GvVOpQna3BLEYNPCSx3Fc,6260 -pip/_internal/network/session.py,sha256=u1IXQfv21R1xv86ulyiB58-be4sYm90eFB0Wp8fVMYw,14702 -pip/_internal/network/utils.py,sha256=iiixo1OeaQ3niUWiBjg59PN6f1w7vvTww1vFriTD_IU,1959 -pip/_internal/network/xmlrpc.py,sha256=AL115M3vFJ8xiHVJneb8Hi0ZFeRvdPhblC89w25OG5s,1597 -pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_internal/operations/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/operations/__pycache__/check.cpython-38.pyc,, -pip/_internal/operations/__pycache__/freeze.cpython-38.pyc,, -pip/_internal/operations/__pycache__/prepare.cpython-38.pyc,, -pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc,, -pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-38.pyc,, -pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-38.pyc,, -pip/_internal/operations/build/metadata.py,sha256=yHMi5gHYXcXyHcvUPWHdO-UyOo3McFWljn_nHfM1O9c,1307 -pip/_internal/operations/build/metadata_legacy.py,sha256=4n6N7BTysqVmEpITzT2UVClyt0Peij_Im8Qm965IWB4,3957 -pip/_internal/operations/build/wheel.py,sha256=ntltdNP6D2Tpr4V0agssu6rE0F9LaBpJkYT6zSdhEbw,1469 -pip/_internal/operations/build/wheel_legacy.py,sha256=DYSxQKutwSZnmNvWkwsl2HzE2XQBxV0i0wTphjtUe90,3349 -pip/_internal/operations/check.py,sha256=a6uHG0daoWpmSPCdL7iYJaGQYZ-CRvPvTnCv2PnIIs0,5353 -pip/_internal/operations/freeze.py,sha256=td4BeRnW10EXFTZrx6VgygO3CrjqD5B9f0BGzjQm-Ew,10180 -pip/_internal/operations/install/__init__.py,sha256=mX7hyD2GNBO2mFGokDQ30r_GXv7Y_PLdtxcUv144e-s,51 -pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/operations/install/__pycache__/editable_legacy.cpython-38.pyc,, -pip/_internal/operations/install/__pycache__/legacy.cpython-38.pyc,, -pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/operations/install/editable_legacy.py,sha256=rJ_xs2qtDUjpY2-n6eYlVyZiNoKbOtZXZrYrcnIELt4,1488 -pip/_internal/operations/install/legacy.py,sha256=eBV8gHbO9sBlBc-4nuR3Sd2nikHgEcnC9khfeLiypio,4566 -pip/_internal/operations/install/wheel.py,sha256=xdCjH6uIUyg39Pf8tUaMFUN4a7eozJAFMb_wKcgQlsY,23012 -pip/_internal/operations/prepare.py,sha256=ro2teBlbBpkRJhBKraP9CoJgVLpueSk62ziWhRToXww,20942 -pip/_internal/pep425tags.py,sha256=SlIQokevkoKnXhoK3PZvXiDoj8hFKoJ7thDifDtga3k,5490 -pip/_internal/pyproject.py,sha256=VJKsrXORGiGoDPVKCQhuu4tWlQSTOhoiRlVLRNu4rx4,7400 -pip/_internal/req/__init__.py,sha256=UVaYPlHZVGRBQQPjvGC_6jJDQtewXm0ws-8Lxhg_TiY,2671 -pip/_internal/req/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/req/__pycache__/constructors.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_file.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_install.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_set.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_tracker.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc,, -pip/_internal/req/constructors.py,sha256=w5-kWWVCqlSqcIBitw86yq7XGMPpKrHDfQZSE2mJ_xc,14388 -pip/_internal/req/req_file.py,sha256=ECqRUicCw5Y08R1YynZAAp8dSKQhDXoc1Q-mY3a9b6I,18485 -pip/_internal/req/req_install.py,sha256=wjsIr4lDpbVSLqANKJI9mXwRVHaRxcnj8q30UiHoLRA,30442 -pip/_internal/req/req_set.py,sha256=GsrKmupRKhNMhjkofVfCEHEHfgEvYBxClaQH5xLBQHg,8066 -pip/_internal/req/req_tracker.py,sha256=27fvVG8Y2MJS1KpU2rBMnQyUEMHG4lkHT_bzbzQK-c0,4723 -pip/_internal/req/req_uninstall.py,sha256=DWnOsuyYGju6-sylyoCm7GtUNevn9qMAVhjAGLcdXUE,23609 -pip/_internal/self_outdated_check.py,sha256=3KO1pTJUuYaiV9X0t87I9PimkGL82HbhLWbocqKZpBU,8009 -pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_internal/utils/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc,, -pip/_internal/utils/__pycache__/compat.cpython-38.pyc,, -pip/_internal/utils/__pycache__/deprecation.cpython-38.pyc,, -pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc,, -pip/_internal/utils/__pycache__/encoding.cpython-38.pyc,, -pip/_internal/utils/__pycache__/entrypoints.cpython-38.pyc,, -pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc,, -pip/_internal/utils/__pycache__/filetypes.cpython-38.pyc,, -pip/_internal/utils/__pycache__/glibc.cpython-38.pyc,, -pip/_internal/utils/__pycache__/hashes.cpython-38.pyc,, -pip/_internal/utils/__pycache__/inject_securetransport.cpython-38.pyc,, -pip/_internal/utils/__pycache__/logging.cpython-38.pyc,, -pip/_internal/utils/__pycache__/marker_files.cpython-38.pyc,, -pip/_internal/utils/__pycache__/misc.cpython-38.pyc,, -pip/_internal/utils/__pycache__/models.cpython-38.pyc,, -pip/_internal/utils/__pycache__/packaging.cpython-38.pyc,, -pip/_internal/utils/__pycache__/pkg_resources.cpython-38.pyc,, -pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc,, -pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc,, -pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc,, -pip/_internal/utils/__pycache__/typing.cpython-38.pyc,, -pip/_internal/utils/__pycache__/ui.cpython-38.pyc,, -pip/_internal/utils/__pycache__/unpacking.cpython-38.pyc,, -pip/_internal/utils/__pycache__/urls.cpython-38.pyc,, -pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc,, -pip/_internal/utils/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/utils/appdirs.py,sha256=PVo_7-IQWHa9qNuNbWSFiF2QGqeLbSAR4eLcYYhQ9ek,1307 -pip/_internal/utils/compat.py,sha256=D7FKGLBdQwWH-dHIGaoWMawDZWBYApvtJVL1kFPJ930,8869 -pip/_internal/utils/deprecation.py,sha256=pBnNogoA4UGTxa_JDnPXBRRYpKMbExAhXpBwAwklOBs,3318 -pip/_internal/utils/distutils_args.py,sha256=a56mblNxk9BGifbpEETG61mmBrqhjtjRkJ4HYn-oOEE,1350 -pip/_internal/utils/encoding.py,sha256=hxZz0t3Whw3d4MHQEiofxalTlfKwxFdLc8fpeGfhKo8,1320 -pip/_internal/utils/entrypoints.py,sha256=vHcNpnksCv6mllihU6hfifdsKPEjwcaJ1aLIXEaynaU,1152 -pip/_internal/utils/filesystem.py,sha256=PXa3vMcz4mbEKtkD0joFI8pBwddLQxhfPFOkVH5xjfE,5255 -pip/_internal/utils/filetypes.py,sha256=R2FwzoeX7b-rZALOXx5cuO8VPPMhUQ4ne7wm3n3IcWA,571 -pip/_internal/utils/glibc.py,sha256=LOeNGgawCKS-4ke9fii78fwXD73dtNav3uxz1Bf-Ab8,3297 -pip/_internal/utils/hashes.py,sha256=my-wSnAWEDvl_8rQaOQcVIWjwh1-f_QiEvGy9TPf53U,3942 -pip/_internal/utils/inject_securetransport.py,sha256=M17ZlFVY66ApgeASVjKKLKNz0LAfk-SyU0HZ4ZB6MmI,810 -pip/_internal/utils/logging.py,sha256=aJL7NldPhS5KGFof6Qt3o3MG5cjm5TOoo7bGRu9_wsg,13033 -pip/_internal/utils/marker_files.py,sha256=CO5djQlrPIozJpJybViH_insoAaBGY1aqEt6-cC-iW0,741 -pip/_internal/utils/misc.py,sha256=uIb58Hiu_g2HRORo2aMcgnW_7R5d-5wUAuoW0fA2ZME,26085 -pip/_internal/utils/models.py,sha256=IA0hw_T4awQzui0kqfIEASm5yLtgZAB08ag59Nip5G8,1148 -pip/_internal/utils/packaging.py,sha256=VtiwcAAL7LBi7tGL2je7LeW4bE11KMHGCsJ1NZY5XtM,3035 -pip/_internal/utils/pkg_resources.py,sha256=ZX-k7V5q_aNWyDse92nN7orN1aCpRLsaxzpkBZ1XKzU,1254 -pip/_internal/utils/setuptools_build.py,sha256=DouaVolV9olDDFIIN9IszaL-FHdNaZt10ufOZFH9ZAU,5070 -pip/_internal/utils/subprocess.py,sha256=Ph3x5eHQBxFotyGhpZN8asSMBud-BBkmgaNfARG-di8,9922 -pip/_internal/utils/temp_dir.py,sha256=87Ib8aNic_hoSDEmUYJHTQIn5-prL2AYL5u_yZ3s4sI,7768 -pip/_internal/utils/typing.py,sha256=xkYwOeHlf4zsHXBDC4310HtEqwhQcYXFPq2h35Tcrl0,1401 -pip/_internal/utils/ui.py,sha256=0FNxXlGtbpPtTviv2oXS9t8bQG_NBdfUgP4GbubhS9U,13911 -pip/_internal/utils/unpacking.py,sha256=M944JTSiapBOSKLWu7lbawpVHSE7flfzZTEr3TAG7v8,9438 -pip/_internal/utils/urls.py,sha256=aNV9wq5ClUmrz6sG-al7hEWJ4ToitOy7l82CmFGFNW8,1481 -pip/_internal/utils/virtualenv.py,sha256=Q3S1WPlI7JWpGOT2jUVJ8l2chm_k7VPJ9cHA_cUluEU,3396 -pip/_internal/utils/wheel.py,sha256=grTRwZtMQwApwbbSPmRVLtac6FKy6SVKeCXNkWyyePA,7302 -pip/_internal/vcs/__init__.py,sha256=viJxJRqRE_mVScum85bgQIXAd6o0ozFt18VpC-qIJrM,617 -pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/git.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc,, -pip/_internal/vcs/bazaar.py,sha256=84q1-kj1_nJ9AMzMu8RmMp-riRZu81M7K9kowcYgi3U,3957 -pip/_internal/vcs/git.py,sha256=CdLz3DTsZsLMLPZpEuUwiS40npvDaVB1CNRzoXgcuJQ,14352 -pip/_internal/vcs/mercurial.py,sha256=2mg7BdYI_Fe00fF6omaNccFQLPHBsDBG5CAEzvqn5sA,5110 -pip/_internal/vcs/subversion.py,sha256=Fpwy71AmuqXnoKi6h1SrXRtPjEMn8fieuM1O4j01IBg,12292 -pip/_internal/vcs/versioncontrol.py,sha256=nqoaM1_rzx24WnHtihXA8RcPpnUae0sV2sR_LS_5HFA,22600 -pip/_internal/wheel_builder.py,sha256=gr9jE14W5ZuYblpldo-tpRuyG0e0AVmHLttImuAvXlE,9441 -pip/_vendor/__init__.py,sha256=-0H8nYPGWX7724kAmvYHNUE268FaYlWrNW518BygiUo,4979 -pip/_vendor/__pycache__/__init__.cpython-38.pyc,, diff --git a/venv/lib/python3.8/site-packages/pip/__pycache__/__main__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/__pycache__/__main__.cpython-38.pyc deleted file mode 100644 index 40a21db9927fb07f76924b47f19191ab53f51ed2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 422 zcmYjMyH3L}6t$hC4Sj(S;vYIRWnw~ziID}dWHD)dL)|)wWjks+^CRuZ$M6GQnb??_ z@Qpy?O1`h-bB_Hq9uG)}cm4IeV}yL*@IR6;+=XM;AqgU=A{EUk#hxjav#v&Y1hI%V z%-jQ8Cx_l|?jPxq<_Sb$mkI*Ok#)>iom7K-NC}KY5?CcfhcOIa$q|*=BboL-gCChv ze_AYTqgn@CR=P3n!Q(cr3R(M{&=7meMp%lM6aw G*#7{t{B{}u diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/build_env.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/build_env.cpython-38.pyc deleted file mode 100644 index c2b499ca08b4ad4f740d9dc0d1f5fd981ff865b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7483 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/cache.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/cache.cpython-38.pyc deleted file mode 100644 index 27ea91a7f2ed90ea6f5b991d98b79de596328b97..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8700 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 H;?n;BnZk8V diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/configuration.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/configuration.cpython-38.pyc deleted file mode 100644 index 0fd12092fc2672d1abe0e2da151f8ce71e4fc98a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10645 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 J+SipA{}--VG@$?h diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/locations.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/locations.cpython-38.pyc deleted file mode 100644 index 51088698569fbcffa77c19671eeeb13b85b4dc03..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4492 zcmaJ_UvC@75x+Ygk4K84Wc`=zI2XBXqQoK-J5373DVkbJ>co)^D{kroitCBHluo)o z%-&MAoX&(Zl2>Jn966i~Tet>>}KDIy}i+k-$^Va7CsQa5eik4ERci`^q?(FRD z?96ZGcyD~Xrs4T}_us$RIIn5{q{ivTM&n2LrT@}3jcKmNbY_HlWVnV-bSW&kB~_cl zy6l!!+j1>cSKNxKZP!L^hSkV+Yie#e9E<91UC|ckakru9N;nZsx|52w!*kJ;JEiDq zI33NnGm5T-v(cP87tOo#sy!AiM2qgCuJJkXH>^_+&qo*B3(-aQV)TsrOmxY;r1-|e zXCudb4t!JnCDs_|?qxQ?CO^^K@33=h3iWrn-Txk&#>n%$+<#%9^_K@4o7poy*F}xj z`Y#SN_xZy*xB4%Ey7HkGUoz3G} z>N{Wbu?y~1_8fbLUHU|Kzt5J~v&;eY8Y^vT%a;#dzm>Fo86-mJgl_p_NaxaLwiI5xUtELBOF%^xm z%^N>ie}CP3Z~guznw6m_kk)2*}n;UDlKiph4@~QXl-?{H$_Ko+v zyZ1IWZf?Ajn{7XpU|SHqI1b`%uNN~ey!}APo*(jff7#5cO^uAZoJt&$mh4Y^wc>#bq;U1%o6EA#I3@Oq}jKbG0=6b za3wXTnrQR9x9t{5p-pmm$riVON%%x=8FetOrmi(+1flvC68LSf-T{TgVtfA)k}rC%&>(y zZ?|dE$sf`BuWOl=RgU!|JG1-70N}=~ zqiSaFmRN<^tooUOR+U+M)%1=uf2GT^w6f~4aa7B6A+oX%(qy%MCDXI=z&O@_rDult z6#bu~e+>P`s9*2?F01X@SbWRRkL#U&lssH+UWiTbPaSZD|P=0dJHsv z{W|R~(2mCB_?q_fxud#lWHmOP)#tTiBOA-=*R_xS!5TQn1gi}6Jqy4*myPu&1 zq92?1Oxc^9KGrb$OF6SU+nT z20EKr)Q-jrIaw(iXEV$q7#?6pYW^5(dG_$7(-7i23>XCi4$~(Ht1wY<334+SU40E) zBG>|B66a>@NBnSnWhG8ldMOtx?ap>SmMZJB_a-9%8eXkDX93&}BnhhCmo>=u0wKKzKXsF`k=g0O@vDLENLGyt2c6 zxM%vM+W3XMF*;t8DDfhRndOC6qLK< ziz9KsG8KQBo+USlBOvSc!x_BOqYs7Eg>O6R86}{%n0;lqDF(b+mjB=3fe}9OPdabijhW? zB$l*$5#q5*b>Iide!zHIMCt^A@u5@+4+V99-w#56E96eGYPzZ<>`2*7S6eMeN)b3I zsy7p{-MZEq8Y61PA2xSn6khg26>BA584jv-Yf8|n+Ns)~GLTiZ3o@0H+<}6)zs>1< zg2VIqK4|Q$*bi;=iUV6`N*tvmL6MFO-S32tEavozrZ59B(&NW1 z-0aA3nm|_Pg>I4t50@!P`?&Q#gK-kC3>k1MBRRv1q6~m zmx^z|P)+4P3bp=#;q(#;?L44E8@-QB#Y>sm0W|S}6moi$M@*wlYm$tSh^pEJbs-5rc&4<67uk4KZD{l62kWPzunPAU@?Q^0v`sY$ z$Sq{*0p&Te1FefC2BLrPduhQcgUxP0=e@Msi4a#F7&OfDF8vsSXJ p_H3;@1x}+>*J;E;*)SR?Ck;^M3%W^pM)5qZ{aF2BK;JuG{TELD0Wbgn diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/main.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/main.cpython-38.pyc deleted file mode 100644 index e06d25ba0258efc46705bc161b7bd997bd09c1db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 615 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 MZC9%rD}LYp2UO^l1poj5 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/pyproject.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/pyproject.cpython-38.pyc deleted file mode 100644 index 43e887e48f8ff91deebdb07ca6a6c39c967b7ab3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3732 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc deleted file mode 100644 index ee9c05acf7d93a7aed15b4bf83cc689660fa2f55..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20328 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 H>6^|UoPj-> diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main.cpython-38.pyc deleted file mode 100644 index 8b95804675088a329c90e42ad478e194a66c5cce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1406 zcmZuw&5s*36t_Jenan2HG`kJ$s;weH50OX$NN}hS0Wwoeo}FdcQpTF+_hJA1{Cm%j>-7-9_gnerH}8S= zhcT{y4j3Q9FMkF>QG_U_gyW1v1RLGqPUP6xja)l>k!NQ=@?my)B@3d!uJw2|3!~8L zKHth}QO)WVUe6j)!|DOw&YDrv>Q#OtYeg-LSWEl}SRvoZcB9?wW^@yL?yAk+SmWpx ztcfn6^XAz2KbEXgT28e_o{*z&I@I84g}AqoM}Ey_y4HfMs_ z`ttbjINty4VE>Ew=<#UuaP(=HXm^-OrGrPM$t>YxZ1TDMe3(s1_TiVmgIECVXMt!d zbc%rl^aHt#mPnD6vql&x_XWs#Q+W&Y0)I`GcuAh1{Bsv6|11<27%d%$zYV)9tALV) z(?)9y`>d_1r{Tt0ZBcBrC+K}RZ|Ph(Pth^T$x}3MsoJWpYNrkAtfAMq>P3X9=hxc^|N)&f&+LC$>Y|3sGF!dvYu$QnbrDx;U?`t$0+(b1!$ z2c7#;qxt=Zle`dVKIt&SD>ysn-?F?TnNr5fi*dr)JnZ#SC?HhB6ehURceNvDQoD(m zd?zY^uG?uYRl<3Eo`@U}VqQ!pfNk1axJDS>wJ#L~ulCMGs+cB))D@oQOtMnD?0KrR zzd2f0A(czjAMVGW42RmYJz!QCXzfvUGMxy|;JR6o=3U=rBy}*(Xq+b*+h~xb)DC+- z)|lzaWn2A%#GA15uLlE_m4h-Zd(*s3#%GN7fCT+ScVAy-a*gd16SfYz{hu|P zcPBSI-g-3%oH6@`q%B{x^J;jiQZ6_3-}|3PU(HH$jlkT%zci}mPUijT>V&D`rj$W! u%LOd#nXuv2R_B^{%WMfg%nCZ?>?70B@*W76)PQ$8NDW^N;sWF0-M;}CcYx;r diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc deleted file mode 100644 index 692de592a29227d7a8aace45c6824e0f94cf0368..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2159 zcmZWr&2Jnv6t_LIGqaQ3%|}D}AwZ)-TCGG9)I&KCBC52d6(v-(J#?TNCTnLqiRS~` z+ceSag_J82Hx3AGj!66^Nc;o7a_WsUNWimaQ-#zkzwvv1&mO<``+4?Jw;Lj8zgK^L z?aUzbhfz*90?NnG<&PjJiV?+>a2#X%Br$=f!=2oXU2NuD-pak$%l+85dW#2nJ8tJ; z99rGuGkGWO*s;&Mc`xqev+=Ce13s6}$MYDmc~Qe!ZN8A7i_hhY@gmHJbY@86H)w~3 zFHpQhyL1Mg=P7xB`n|)CZbULGhMYwePX{d8DMd6W3#r6tpkN|O3mUQKRcX8;^^`?< zniWx%3duzH5)Oy9`dEj9oR*c!AhJ*N!e&|QWW&#`;l6d%Z#}ALYF50-cG3}7@($zG z?Na2aQcOTlcTnaz>?RYM4U}FSGL^_I&v+`5lPTD#v)Q=a5~4I=v&OH=s^l3H686`D zHHdNu&I_MCzW+GcymM>w)8vasTU&RxK7o+d!%@YVcJF0U>4kw{sbYyaR?-|xckT0J z*MT|YNpoS~LEnTf6$n#Lg^mz)6b9-3)EXm2c2JGJ$75XMiF1rFQtlC|ane%W#8=*K zP~&4VCNSHs$uWj1wO}@+-Vjrt1}~7BnRJfPO>~6Mqp?HVlWy%C!)i&d#!$EL@cO2G zZE5Qxm>P*fo-L0pCZy)7j5hDx4I^lWm%`-=aucmjQ@Rm-Ij!51+u9rQay#YymTrw? zI%Ik_r8Id8g-RMH-3EL#71M5!=8#0Q+Cz;77;4A^Rl+Q#QXQ~%ImOLUFYQ><#GcCCqWvA{aIn6MB4~+a($6zGTr8^*;!TqOh%Jb z45bLnyg!AiFqed$&(l3N&2KUk<*3r#AuE_j`Ba@VRcHz@wYcUO!lYQYGR1PK-Q6-P z^bBQkATrClzN^~}o|C?q7yQY=HX&0`}j8MO=I0(5y91o8+b*fsrcF9>l! z0;h*V$8$pB{S&wy^1q^+qnSilX8Z;N!wSm)T%%(Q#V2D23Qxp_a(3MbAb!_kztMmd zzF~rLCV^p0?TEN`D87g&*&||CwQJ`H?o2ZV-h`G_uY8T)*sWbPv*(LnRi}23@VG_6 zvV?|s?A0ytbL~yKz_Zp8ybbKrquyk;_Kxup{ubVl!tXl*tN67)nX6snQ@gdlW9~_R zOBj4>*Kpyb86GZhIZtE)Sgtd94Xz}7f?@4N~wLG6-=^9yX<+Uw8L2e!2-~18ELC8%vGelw5nJ^ zg%65&*IES2%V(?~XxDCZ)fnNXY)~~Nyl$JhgmKAq0QYxd3Ediwn3USd<*>2Z1q|O# z;iL!ZhtTB}5Quo~p5x&j`~v4q9DoF@0A4~sPmlDR4h~8Gg7%YymV+b_YY-&f0};;y zLswrhbQKudkmAB?_SFW!mSL7~dg+YM^z(5lF=tj`&j+meM%h&9Gt(oLak-jjz#xNV zOK5%R|C=;E>Y#!TnK1tVv^Q1YPXH1fV}WC)oWn5b*JH*9v4kYuP{{VoeR`UP= diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/parser.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/parser.cpython-38.pyc deleted file mode 100644 index 7c20b2090b24e9df01b2822123e3ace45e01d737..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8977 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ŪC^Gu+!#Gzvs@#5ogZ!5?@RSQtr;UmM1=;_BVG?CD z(}qDLM{Q1j6^4)mkVJ7o&#s>%a%WeXFn;9q&|wLZWDpO5kRC6Y5Y%D*;LGXwMnoUG zRa!DLk%mS3XIgroo=hF{Z7h)6B84BrPk315{`p&Ydg_q;5PdIcTj`JE6xro-=$8t- z-l&|8|77}t+%$;>613#I;(tqhwD#D3lD$&LKg9!jC_fh>uVFe<$cSBb-gGW> zCBP%%#+ZW-A2wfLKzL|@O!y!RI;uCU><8*|8JQ=1Fd#XXC&2e6iHa^hkH!#viJOxF zKq2$eP{Cn?^ge;J#hT#ZXCQ(PP-MwxxAw`MixUdx)ha0A;~^*Je)i^mvC5K*uWR&m zUmC~u9+87j_5qS3YIqbvJ@*2!5+_S88NC&0?Od$#=E^OpocLVR%>Lwe-!SfX10Djw z$G03`9G_%umAOU|;iq&)=_!))IQH`7dwY()-{O*aObwnNoIs6yL3QW!ym3t?wJ4?9 z?&F&!QmUNfJ1>)G3lvhSPm(IX3*GNHnRG25w^(U#y!R(nT!cO%Xno>YRUF z_71;eH}M_23G_<)0xmmJ{0cB$IW=fJyput&M40^QGjbpA1(jRZb-)>L}=HXK`};Z})kl=?%!jF1^1VpPof{kfU? I#kt-80gh=M-v9sr diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-38.pyc deleted file mode 100644 index 461893f5cc0f45652417524015c3c0e558097e80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8289 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 A4gdfE diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc deleted file mode 100644 index 40623f8466ca0e9617794943b6e2b27947345ac1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 365 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/debug.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/debug.cpython-38.pyc deleted file mode 100644 index b8568002938e55922ff27d93908188b548e312ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4089 zcmZu!TW=f372erhE|(N3$&w}8vD<9i1PR-i4vMxYQp34OPSVy@6U$DMZG-KKGo)79 z3q3ouBbo#X$VJ+Rw&*{g9`jQ4F%SI<{R8vbr@Rz>E>O7NnWbbY_7XeSGiT47^PLOt zwcAY#&p(I%`R)B>%la2hPCqUtZ{schjfPvCrB=p5#%OG(c4(X42_4hBp=b=)y|k6J!?qdM)5UBlTry)nUCz#h=ghc~u4Jp>su?%a z^VwRs#w@WW|Bi1gr0dy*@IrPmyqH}IFBzIv`a*U&ybKy=c13*ah=t$gZNB)}3SZ<) zd>MVf&+!%XFY#4=9{tt#ExyLrA6tA~EF3!FceuT6buN63J6j#5m*SnWNJmOUNj5B` z+QM4x;jWMZgJv(|#ZVR zoQqsVX)(ZT$&e+(=z)+WxDkh6eEQ+1(Z&b2Hhv!6xwp0T)2;VAj&|P3543wbDV6qr zX+9jMAof0v(~&59HVHj{XzbzLz+0}PQPzxcHnS(zgdN#O#*VnDy*2h8P2UV2O~K!T zJOd%Mo8uaJ~Rd|Q&RJ-jCmtvB$R ztGtInbrrgTvX#T_Lt9=|&YnB9Ce~hU%5s-GQ>MH_>o3cosdIP24sB-r%KD-8k#)!V z1Q5p6Yg^;h@}TU(vZ=^mj+jjOrd~X|pe?zAk9K^ygigX$EM4D?%UCI?9Wam=Xq{-J zPYqq5W1CgIdX`s2iZuGGnl+H>3q}uML>N0I$xGNQ7tvUDlQo&geA~5sCP`U6M(gv3 zlyjn>e_+BHt`B7#vZ+0>XY9zDI_PcmF1M$(i7UI@nK={ph)rwUojJ;#IEQRfJF=&q zs?EHKN9u(->%6va$>DsT?YnZwy=i>{ub;5r+n2x@>aI`g%7?mtj5E%r_1VhQCoZZn z@edhsy8pXLUH*;xd(MRM#-G^fuYAKS&8@E~Fv*K(#_iy>%8d*{$7}GhAx;_sP@(H9A34+Lx1p{CCjXkvi zDhep}%;7LH2N;a07bmRz0e7}7?(!P<2F@R?FRVV}b?!g*Cv1~o=}z486W-Vch-NNt z&^g|m)exE(Jab`7v#unoj@w&>3d*7ACH(}KuP1q_U@Q}aMXG%ctENTF&qz-ZgVNV3 z-jZ-M0F*ylhWzXg*1jhZ5B_T3cekrhW|WC2XLsMwwNyM1>6a|LYzAedc4HM4u&YeC zhz4n~6Q`$qw|OH)G)8P2-u#q4MmqDDZTZ&tYA=p}$IBb2TsN@S&WV$OA~9HxoVo)j5G(C%K5W8;~(E$A02D)mYxd?wPPm-Zorc_JXyQ5HgE?walKy6J-8m7y#K!Hv0h-Mo7S0c3r8$v4Zl(I`s+y@&RmJz*33 z&%hgkn=?h=1L~Z4u=8eh&M-r+z^=FF&l*P-6&5B@8bEfMu*zr%JiG<2+K*t|L`9MI zQ4B;7rj+zueF^qETLI7}l?vJ$# z*-&jLdvR~+&?ITBG}ZFnx!DSD9v!bN%vTmpR$6LxF4cJ?cbHSH!AR|`@mF_ulQNiB z8v%wzo*o35h;tPHN)@aI@QiM-Sp+$v%ZTy-9eS9k-5?&RqQaXYCtHCyKw%dk6DS(1 zU4bK9s5nW>*8}YLh=T}q#~VHf=&&k z=mWn373ln2i_XF66#3eC_0=9=`6_fsQ6?}2nqIkc>!W+Ow(o978}CH#-rL%|eM>KH z+`Du8>3n<{7wDph&3Pfa!~-$AYl`L9I-PZsCw2W{EOW?esw7EOi=@D#>+`$n=F@xX zm1pm$*Rb~N{it+BbQSvi^De0UG0m(u|_4;3H&@NVlTs{wPl8JM}2yMGwohQ5g>e;>aK`q==-rKT6QU z01r$!kd%^idmb%%B2AAYhLQhg*fr_Egt8uHCU&4;a9tD!E#ItnUM5lcBQ*l+NK$H* z+r+m{e-_A+AJY;UFi+?}u1Nv_ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/download.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/download.cpython-38.pyc deleted file mode 100644 index 24423e07fc76d21b8e40bc8dff1a63af74840fa0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3921 zcmbVPOOM>f5pF()#qCA|cCTBGxB|d}%n_bn->Z~V@ zZQoY?PU56pzpMII;-)>nr}}o%PY3=$^_^sxuK8=}y1$-o_#2AXO*Ydle@i1wzqrP( zUuyo1pAzcQ-ZMgbtb1v+6fBCTG2>#= ze*DY(`(DBGBQVITcyh&mm`7o9H3F_t7RT(h2{{M(XrG6EEK2SNqFj&AW)fd z>V+^hPngHDXYyIoFT$TC4Tn0gTk-$e0_oabcF73+s|xBCnzB70Owmx+|2sLiJXt z{t7i%p@u8e+6uM4LT#*2n=91T3UzITy1t-}OsY{GGZ(YAym7QmZR$LCGy-w@^1Lxj(6C&aavS1em_a-A#nz)LzQ&xt@A(u8~)38cPY0g+uaNPLO z9oc~-Wt{hcl1>oBSzHEzbO40|2z(*kkg6VN$PwveF9K)=AceJr>@TH|kllkSPN>q* z&hmh=LdfA^k{^T#3PVhnT^Kk3lliIa!AVBRJQR_n)bs3@08w-SKqtho3659I*Hmq^p%!MNOtGkBHlcg^6aBTd1QsWjpI5>kJ1!mpzT-9`Yq z_iIgd128WHBZ9BV%lkWJTI>LTj;jn&h|%%MjIm@a4yGk9PCme~9oVIk@hnVsqUQ7y zJB#p`6sP}%GtCjkNQEMu3%vw9@oa0!hw3 z?Oam{)dk=&YLn{Ejd=%Vy2aPFH0FIc||0U?RZ70|Au|K!pRD29XTodobR}SSwD0W2hQHAqco>{!;T+ zP757o;^yzeBQ~LdZ6;s1b95m2gZ|XqC;W%Nh6>8e!jysX`s91k0M!(~Y3{)c>Fy@6 zC?S}Oz2BlVtYR$)$+P!f4?A9Eljh(Pd(c^Yb@tYN6-D5^X_X|WOI3jPt{B~t>+vDf zcu-~na)n94sO&Ntm*D}_9Sy48h-NH$0?;L}Vg!7PBg8A-1x=LCxPyvrVMW>EXwdE! zM{VWxb_?3tA!yzGUHtwQHa0ex9NdCN-YoK>0+?be1*%}Byrm##30Q;0=Ey-i1ONv+ zBZo~zyx1kVj`b}AG!${9woKY!3(l41Q66V_Xl>1iJyC9wTj`6WX$6$)_ri d6rwo0%}(uMa*7+!^dWd0y{|3qYZ`=<@gHk%eun@6 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-38.pyc deleted file mode 100644 index 48d9dc03d75ef92bcae49d5c88a6c168fc09344c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2929 zcmZWrOOM>f5$2m5?#w==l_J|R0Y?c2SY|c8~rm0rCg>np18$*&Ze&qc0!IG*x-7Gb06F@o=4B@D z*OlZo1BN%{ly*30LrB7kqqI4h31v4$qe4Mt+sL|RA_++$BrlHOugX2ee|00!j5!r` z%X2DnG;aN|mjm%W5Y$LaVt~8M#3oka5Ib?dG^QqTi2EW)JmL}mg^~DQ8jg_!u-O1i z)s`)7@1BJbJfF6*X=PMYLS~Fn5;a+VlFg_9R>bL(w&1j+l@!rbZ*&ssX;)eqrxAml zz)YBsMR_J@46D&f6tZ|qBLV&dVa*BU6Fs-v*Pkf5*YJ84{b}jfFUHoZZTd`paCj)5 ziwQW7a?SxmMsBXT0lhGQwgpZ69Xe@9b77oY$JWAJSYH8@7RIrC>=2V!#3s(nATE02 zrGF&}G&oR#09lue5GG`s?2uiu_Yz>YT{3t(O4ffV(Q1(Teg+7S$}OH5w+- z@8^Yx`nW(utLTVEt$-+&Et5q9E6JjyVlsA>L#U8oRF1i!d_t!g=qSIWGJBeF<;*E- zU{}*_7{}A1A~7qf6QM$+)1I~;|L&9SL+B7=5em?j6~qpr(|M84qtk*hG$bPgERl7; z?cQMc0qguYW_6x1<@TRY$ePns@|J$oJ^t0S2k6s+%Qj=QdI}3wPn`)@IiD>bk;#Mw%5$k7VX9{ zeU`J9(3p}!W=D)FNH)z$SDfzN!=4kZIII6eQ(l)VbZ|_^@rH6m+dzsAVWfgIEviDM zsS2P{rT`rXF+>U}00wtZX@G?yZ8AAm&T(B-DtPel59x1z{qbkYYch@=+r!eq<#Jj& z<8|ANZRH5crpn1UR8s5Y^lMWM(llq85NZ0g@#>d{vTP2a!p3cdo}nbx6*U$|Q^}jt zpQ7v#ER>X289PM$LoSHJ-pP~ZIll`Az5`7V=nQk$@=VLH%&Yg6H~1DOxW@U$^I^Pt zzwx|n^Yu9RpY>nQyBY)C?O!X$la&MWRhdUS0%+*p`_RPSpu=K!uG_hFW=kk}$M(Vo z+L5Mo&doCyIIj5N0!owgu{6oxVz4kZ6@qL7+7Q|Z+9tFuXxq?s7S00a?h^B5c;}o%$GNh_b+ZOd}7_w1@DRc-1v#Ha4z;P4b%8zU%u=|<4|p^RV%&^ zCaX}VV_HKNr~x9qCtU;rpafB!ayp~WR8YV%oWXISHgx>b9FJd!KB(}waV;|(-{u}t zHk_p#eWeCkDA`V9~QM~1m+4$T0t z7h0iZna;Hr@#*}>8(E;WZ*@D@F$n972bjxMR#M32FvYF44C!H-K7qQql=x{%>Kxc^ zE8w=EHdsAN;XXsNQs`Xb57DyGGD~yHSemZcJq9U9b9MQ^@+t7%7?_UdSdKM(U-QR1 zXu`CWE!6RpTd4nY=+qwM^W-X@CmH}649U(L5?1ulzxyrz$nCV_TK*) T;#Z)PhE`w=A-v1i+O+=<@4!m+ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/hash.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/hash.cpython-38.pyc deleted file mode 100644 index f80fecc3f08ad7d309ae5189d39c4663d2eab37b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1990 zcmZuxOK)5?6t;bz^GZTnMWu-9QZZFCU?Q z%w)N_Fu4g`{tg2}4Cko8F~-IwIf;q=I$-Tmlee2`qK@rBGwY|JmwBvTs zi92@g=iQ#>w6p1@japRW=$EQiSyjph(RFk5Ml>7_cT>ECf&rleeHFU=76yeB zo}pv1PiA;V{s3vr(7v%DhN<%zngTo2u`9SWCl&B9sH+!29k>a9E^38OvbGd0~AJ&h>If&$a=<*T_ z2%p0~CWzqIzwjk_;fK=;OA;KOrI;E{&zi|8gnk>kyaB_E$aP=|onS?PE8thTJ7|XY zy(4EvzCsT!9vO!5%$+$ZFyk>fb}>4LET?2^y0#&&wdWH30?ZBB55+p%tUI-UlxQPC z=-QEwfgq_EP$0~+Bh1SrOf0%bO`^0KQKQPfCoY=RU?EoV?wPlC>qJe2L1I2!Hhzw1 z%03wK0t^Vdcm=z}$01k%5(-~VSC?Ti-Yp}5GATF+piOB}u_iZmm(qhK$rn2TrL0O} z*_)?uJ{y;yP`W5V`iPg0EHz@o#L-(&p7K1WbScXBU{{z>t@aF;(&P>S1}=o!?b`K} zz}i_eG#Q~a4z4Hiq(8S{ZXrOVi`%%1*Re3`{R@VT zQ3GKD8^Qo0Het{~UX90DITn$bU508IzN(gCnrFkkL~^<)8)5YRHYa!yRU^R-UJWZj zed*1c8kNC|X@Um_LxFt<^u@P%6`4#eDsu_9#$0^|L4vwJG=J}#h!?Mo&20$>t6wYK d@cLYOH%viT{dP$R$_)XRE?&cHr0uL-`5#r=48Z^Z diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/help.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/help.cpython-38.pyc deleted file mode 100644 index 2ea4bc7572eceb3a4a7a5587befe80b749e3c8ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1186 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 Q#?tIG)wR#Em(myhA5Mn+4FCWD diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/list.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/list.cpython-38.pyc deleted file mode 100644 index 59b1b93e114f2002818ae27725af1d4784dfa8fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9042 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 E0qXD^ApigX diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/search.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/search.cpython-38.pyc deleted file mode 100644 index eec7751853d73b89317fe92b7bdaada3b035eafa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4484 zcmZu!&vV?i6$VHy$z82}T9&26aTqspyqRj9w$o0>bv<@$r*Uh`ZX{1!c3hTTP%BC# zcMWhYX@|O0p5~M`z2_j$P}Fy*1QR@ADfc<2wviaVp`WI2>Zj#fc$!HqwS8Ob zSc#LmzN_1{q@FhX3Ej4nW;*Fl>b8?irPKbjZoA1$I_uBsc0HL(&-iE3d4FE_8_C&p z!C%nriR4_m=r8JaGg(UC@ZZqw$>h!SynkM|r;@kQ3;qS&o=)CQJ>TOjG7jH~F23ac z4}QhOjF^4F#B4Mj%^q0(yJAk9dBOZ;u_)%n*%#cuBo@RuNZu318fz`Rf(=-Um($@> z)k_9>6vS!2C-YUvCLTx;$w=IeJ2|?O{q1fbBh?$oPNX2H^+Ty58re+~+3y6MB#tst zb#C?2G|U8=XVxO6;$AkA+>dwTtYwrls}F+vH`i}{d}l5A=)t4a+oiMi=+><}YioF? zIa0nOWly4SJ=}YE7tgteasRRY)Vd5aMeBrgwj1R^9?3M$!X!}fke1YlGl8`PNw14u zb4SM5T5pi|2YH9KeDY_GI_l?WM9k-c0R$WXFyMUCuYJZgxUfX+h3nhG77onk2v^kc zbU$Mj^Xo8WqnuoeLfP3IEq-{T>UtYJ>Cpzfe%RR#yOHvCHhU`avM`N2jHv-^CHK5e zFU!L?Q{J^_gGlaOZx1gtJpEhl%U;*}eXpOxkm|{i!g`0F*aq#wMVUrXH&Ep)=LI`3 zwv2)o#$N#Nf^C^wmf*q=rm*tbmMv<+{v5Ezh;!%)hcsRq1TXB!T^$-L@z7aWA!F{A zwd!F$`sCj5Cm)8`0$N^g1G~#NdztsJ+Mjoqw7ttB+6V_p?k$fRt(H|HRwlD&Z1YkK@ewg9t5S^Nksq?sIn0X-GVV>Q!DlN`f)Ij zNoi|H%JK~C7|ERUp%rvxZ_sa}*C+vZ9`DGa9>s1p#fq+Lca)a&<*%$G7`?atZ5MMp0lM#`qk! zxxoxhe~TOcv7O<<7)shl`|BK`klu4pERTC@>*^mfX{FDSBhFFJVX`6o5oY;%r$*)pF$9H13SxEc7g0v?F3ALL+@N5t! zqY)2zxqc8+VaF}>fkXU${c-APW4*5&A z?Z}VNwu)L8)c+-s z{JUoL_07mjVwHOvvX^?~9xql1!!Swqys#PqwZiRmdaAbfY2@vMh|A+KJZ+a?+<%Jh#Nt{J(Z+#Qr!C8Zub473Hc}_1S%X?lg!zUxJ6K38(MQyDoe?)%x zF{;uTt*vFA5V}VTmLEa~_%=z^+Kz|@!hS!>L^-_~cQXG7ls;MjIuepTRfUSy)N$oAdB6%*T*{3@>TwXbKCxc%MWsXSSO(F zH}b{-`|CXbwy`x)IDqNDb63n#?*J!5)<$pcsFybj=YVfbVutgOpFxjw8fec~?N8ZH z*>Bk=>@oY4J-ceLd}_M^?T^101rsGNe8pE%M)?N{0OWyc~d#`8} z!}{{d`^sDKmetT%R^H`h)fz6`U0qwhdGFqx+gBm?E+=7*uxkw`$K=Cb-n+SeXKno| z<(j0{m(hxhk_Z{zFF+eA2Pb(u#4i_-{~SwJR-kwhvyHvpnl8;W+?8ana$=_^w~=1p zOv|;0IVkCH4dXl8G`_WJGe|sKeX3IJA_ZBXWP};t1AZ7m zTB7SIj8J+4xw*(^xTJZ%&Jcg*%vATt;x z-;#3Wvij1P5>kz09ZKfP|1%Mwoevb$a4pfvr%pr5#qm!@yPc@IdR4jZ8{@-BfucmU zbpodEBmVhug)GV`4%*c%S?6`-sW||3OhL>P=2d$9=J*_y!jT&&CQh%i(nw>~sUoQk z;NFAVaFe=9>NdSRx>o5^P=l+A%Gc1)t!2`8uT{C-b%L9EA63(+PSqx%)YLUFN{Ai( NjfOe5;+}7`{tL3Ig~$K^ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/show.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/show.cpython-38.pyc deleted file mode 100644 index 689b6ac53ae5b5b75196a9e726758e926d60a815..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6325 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc deleted file mode 100644 index fb226e2b53360a13e3ebd300284a654d15d21e53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2694 zcmZuz&2J>d6|d^=8PBZOHXtGbsQ?Q*(#}`{i33_81RF&t$qKPqBpRW1yQ{`ic7M65 z+Ji^qOLhe(^A~W~Jw^N{x#S<{YfjuaqePqcYTDyrp?kXY>eZ`P@8kDg&BNiaPvH4? z{nNoew+Q(UPBtGOCLhA5&tTw$)0`AErW9!>cM3OlE$!xB;m5wEy*wzwIJC5%M@290 zSvtu3#a6s!=`bG@!+2=vD8Er`$J>6_W46t^xw5&>*rMX;)q)ZC|%<$u?DAJMxx%WV5EvvHQ{7rr>OWgKJsZE;a zse!dWDOD+8?$)W&B2nVBkxCSzG#a=s%9SYclc}nTB$p+ga=TWQ5t&J9S+5p~ipwe3 zf=Uzk&1K1}xz5o1&ByH~`VJ6+#FUfR;WT!+6MNs1DdjHr9!IgyeI7g}aquniNE|{a z!uICFvNNc2DgB5N(r56jS6H29C+U&UlfGR51DVt;JF|Eu%gn2b?OAa-p2k? zR`ZgHuQO4jGq6{Q_gBis?9)aG#-%omk-1*)+E6r?X2uQ<>T@%zN~VQr>PdZmC2(+X zhs|d)n_1%+%SC!7*rAv~xL8@SLYS1NCPiDhFhUg&aM+O=HkG;1Y%ainwb>J^X3QRB zO4f$WRa)0V>1zRYc>Wv4aB(K`sy;Ya?O#0XthohgJz`&0E62ZLce`MIz$TNGC}Ypd zj1{}P2^(vt-H<_Y)(_^r2j4b)`g0fzF?2~DImgbDE}ie7td`{1J@z=|4r1VlAOd)J z3B}Z{L|7txix2ql63Pv@{*!>;z}2S?mJ^_4`~JcitHp3U-Y}{iY)o_;V3bPUdKl8h z@ilg!Dwvsx>$K*OX#j^TE&E8GiIQ!qvd&Hz`}+(qwh9}As)U5HM#ILU$&IWLda?jW zj{Mf+LL0CkLu|Dn7t<7E+7J_ema5j9iM$3E&KLf8d@gkB;?UQoQX(;`5sP>3Rpr}; zrTThZgETu`3 zHp&W~fH!b%$}NSq2DU}0b`Q`eltBTk^&?d^^~h~KE%IsWrRqqx&dK}-+V+wp%TukB zFHk=KI;Ijp_Y$#X=RSm%z|J zz^C7YfzVwVP=`2l{r(*EHaPzcg2nIF+3kA9pn=|xd=_L3<2EG z+Adw-yxi^h?71DEoqo9V^fxBtu89!L+`FVNkw^3&)bzN&^iBdETw;NEPx?=ZwFJ-J zf|CXyKjh(w$0M*PT1M*oW%T66Q$oq<_qHH<_n}`$5-yJvpgeNguq*F2)T{ep@z*b^ z2A~T45E0Ix*Fal>Sp}_U1MS$8Zr!%`jApmB5bSmAt_avQ|Md}^=AlgM!XiwD_GUPj zvPU_Umpy?}yI_&Vr)rO{g2MGNU421R_k46Yv;ynx8fZnA2 zD-i#$?*#yC&(8bLoM)cz(BN6%4S?s72;@Dwc;Q#DR!upIu!zwjDB^yCacXj;2T5|; zqQ5B3%Pe9;$iu z*FuniwG94KYhV7Q%=HCsVG-~Aav8Q;%shWS@FxIE4XrkVo~u{bdrr4Ce^N-DS)5t- cH=@PB92>1Ry1UB32k3>yxD6b5>H2m54-m8zT>t<8 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-38.pyc deleted file mode 100644 index a29582650d1ee417ba6c4ce59158bf6945fcae94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5246 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 None - logger.info('{}: {}'.format(name, value)) - - -def show_sys_implementation(): - # type: () -> None - logger.info('sys.implementation:') - if hasattr(sys, 'implementation'): - implementation = sys.implementation # type: ignore - implementation_name = implementation.name - else: - implementation_name = '' - - with indent_log(): - show_value('name', implementation_name) - - -def show_tags(options): - # type: (Values) -> None - tag_limit = 10 - - target_python = make_target_python(options) - tags = target_python.get_tags() - - # Display the target options that were explicitly provided. - formatted_target = target_python.format_given() - suffix = '' - if formatted_target: - suffix = ' (target: {})'.format(formatted_target) - - msg = 'Compatible tags: {}{}'.format(len(tags), suffix) - logger.info(msg) - - if options.verbose < 1 and len(tags) > tag_limit: - tags_limited = True - tags = tags[:tag_limit] - else: - tags_limited = False - - with indent_log(): - for tag in tags: - logger.info(str(tag)) - - if tags_limited: - msg = ( - '...\n' - '[First {tag_limit} tags shown. Pass --verbose to show all.]' - ).format(tag_limit=tag_limit) - logger.info(msg) - - -def ca_bundle_info(config): - levels = set() - for key, value in config.items(): - levels.add(key.split('.')[0]) - - if not levels: - return "Not specified" - - levels_that_override_global = ['install', 'wheel', 'download'] - global_overriding_level = [ - level for level in levels if level in levels_that_override_global - ] - if not global_overriding_level: - return 'global' - - levels.remove('global') - return ", ".join(levels) - - -class DebugCommand(Command): - """ - Display debug information. - """ - - usage = """ - %prog """ - ignore_require_venv = True - - def __init__(self, *args, **kw): - super(DebugCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - cmdoptions.add_target_python_options(cmd_opts) - self.parser.insert_option_group(0, cmd_opts) - self.parser.config.load() - - def run(self, options, args): - # type: (Values, List[Any]) -> int - logger.warning( - "This command is only meant for debugging. " - "Do not use this with automation for parsing and getting these " - "details, since the output and options of this command may " - "change without notice." - ) - show_value('pip version', get_pip_version()) - show_value('sys.version', sys.version) - show_value('sys.executable', sys.executable) - show_value('sys.getdefaultencoding', sys.getdefaultencoding()) - show_value('sys.getfilesystemencoding', sys.getfilesystemencoding()) - show_value( - 'locale.getpreferredencoding', locale.getpreferredencoding(), - ) - show_value('sys.platform', sys.platform) - show_sys_implementation() - - show_value("'cert' config value", ca_bundle_info(self.parser.config)) - show_value("REQUESTS_CA_BUNDLE", os.environ.get('REQUESTS_CA_BUNDLE')) - show_value("CURL_CA_BUNDLE", os.environ.get('CURL_CA_BUNDLE')) - show_value("pip._vendor.certifi.where()", where()) - - show_tags(options) - - return SUCCESS diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/download.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/download.py deleted file mode 100644 index 24da3eb..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/download.py +++ /dev/null @@ -1,147 +0,0 @@ -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import logging -import os - -from pip._internal.cli import cmdoptions -from pip._internal.cli.cmdoptions import make_target_python -from pip._internal.cli.req_command import RequirementCommand -from pip._internal.req import RequirementSet -from pip._internal.req.req_tracker import get_requirement_tracker -from pip._internal.utils.misc import ensure_dir, normalize_path, write_output -from pip._internal.utils.temp_dir import TempDirectory - -logger = logging.getLogger(__name__) - - -class DownloadCommand(RequirementCommand): - """ - Download packages from: - - - PyPI (and other indexes) using requirement specifiers. - - VCS project urls. - - Local project directories. - - Local or remote source archives. - - pip also supports downloading from "requirements files", which provide - an easy way to specify a whole environment to be downloaded. - """ - - usage = """ - %prog [options] [package-index-options] ... - %prog [options] -r [package-index-options] ... - %prog [options] ... - %prog [options] ... - %prog [options] ...""" - - def __init__(self, *args, **kw): - super(DownloadCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option(cmdoptions.constraints()) - cmd_opts.add_option(cmdoptions.requirements()) - cmd_opts.add_option(cmdoptions.build_dir()) - cmd_opts.add_option(cmdoptions.no_deps()) - cmd_opts.add_option(cmdoptions.global_options()) - cmd_opts.add_option(cmdoptions.no_binary()) - cmd_opts.add_option(cmdoptions.only_binary()) - cmd_opts.add_option(cmdoptions.prefer_binary()) - cmd_opts.add_option(cmdoptions.src()) - cmd_opts.add_option(cmdoptions.pre()) - cmd_opts.add_option(cmdoptions.no_clean()) - cmd_opts.add_option(cmdoptions.require_hashes()) - cmd_opts.add_option(cmdoptions.progress_bar()) - cmd_opts.add_option(cmdoptions.no_build_isolation()) - cmd_opts.add_option(cmdoptions.use_pep517()) - cmd_opts.add_option(cmdoptions.no_use_pep517()) - - cmd_opts.add_option( - '-d', '--dest', '--destination-dir', '--destination-directory', - dest='download_dir', - metavar='dir', - default=os.curdir, - help=("Download packages into ."), - ) - - cmdoptions.add_target_python_options(cmd_opts) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) - - def run(self, options, args): - options.ignore_installed = True - # editable doesn't really make sense for `pip download`, but the bowels - # of the RequirementSet code require that property. - options.editables = [] - - cmdoptions.check_dist_restriction(options) - - options.download_dir = normalize_path(options.download_dir) - - ensure_dir(options.download_dir) - - session = self.get_default_session(options) - - target_python = make_target_python(options) - finder = self._build_package_finder( - options=options, - session=session, - target_python=target_python, - ) - build_delete = (not (options.no_clean or options.build_dir)) - - with get_requirement_tracker() as req_tracker, TempDirectory( - options.build_dir, delete=build_delete, kind="download" - ) as directory: - - requirement_set = RequirementSet() - self.populate_requirement_set( - requirement_set, - args, - options, - finder, - session, - None - ) - - preparer = self.make_requirement_preparer( - temp_build_dir=directory, - options=options, - req_tracker=req_tracker, - session=session, - finder=finder, - download_dir=options.download_dir, - use_user_site=False, - ) - - resolver = self.make_resolver( - preparer=preparer, - finder=finder, - options=options, - py_version_info=options.python_version, - ) - - self.trace_basic_info(finder) - - resolver.resolve(requirement_set) - - downloaded = ' '.join([ - req.name for req in requirement_set.successfully_downloaded - ]) - if downloaded: - write_output('Successfully downloaded %s', downloaded) - - # Clean up - if not options.no_clean: - requirement_set.cleanup_files() - - return requirement_set diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/wheel.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/wheel.py deleted file mode 100644 index eb44bce..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/wheel.py +++ /dev/null @@ -1,197 +0,0 @@ -# -*- coding: utf-8 -*- - -# The following comment should be removed at some point in the future. -# mypy: disallow-untyped-defs=False - -from __future__ import absolute_import - -import logging -import os -import shutil - -from pip._internal.cache import WheelCache -from pip._internal.cli import cmdoptions -from pip._internal.cli.req_command import RequirementCommand -from pip._internal.exceptions import CommandError, PreviousBuildDirError -from pip._internal.req import RequirementSet -from pip._internal.req.req_tracker import get_requirement_tracker -from pip._internal.utils.misc import ensure_dir, normalize_path -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.wheel_builder import build, should_build_for_wheel_command - -if MYPY_CHECK_RUNNING: - from optparse import Values - from typing import Any, List - - -logger = logging.getLogger(__name__) - - -class WheelCommand(RequirementCommand): - """ - Build Wheel archives for your requirements and dependencies. - - Wheel is a built-package format, and offers the advantage of not - recompiling your software during every install. For more details, see the - wheel docs: https://wheel.readthedocs.io/en/latest/ - - Requirements: setuptools>=0.8, and wheel. - - 'pip wheel' uses the bdist_wheel setuptools extension from the wheel - package to build individual wheels. - - """ - - usage = """ - %prog [options] ... - %prog [options] -r ... - %prog [options] [-e] ... - %prog [options] [-e] ... - %prog [options] ...""" - - def __init__(self, *args, **kw): - super(WheelCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option( - '-w', '--wheel-dir', - dest='wheel_dir', - metavar='dir', - default=os.curdir, - help=("Build wheels into , where the default is the " - "current working directory."), - ) - cmd_opts.add_option(cmdoptions.no_binary()) - cmd_opts.add_option(cmdoptions.only_binary()) - cmd_opts.add_option(cmdoptions.prefer_binary()) - cmd_opts.add_option( - '--build-option', - dest='build_options', - metavar='options', - action='append', - help="Extra arguments to be supplied to 'setup.py bdist_wheel'.", - ) - cmd_opts.add_option(cmdoptions.no_build_isolation()) - cmd_opts.add_option(cmdoptions.use_pep517()) - cmd_opts.add_option(cmdoptions.no_use_pep517()) - cmd_opts.add_option(cmdoptions.constraints()) - cmd_opts.add_option(cmdoptions.editable()) - cmd_opts.add_option(cmdoptions.requirements()) - cmd_opts.add_option(cmdoptions.src()) - cmd_opts.add_option(cmdoptions.ignore_requires_python()) - cmd_opts.add_option(cmdoptions.no_deps()) - cmd_opts.add_option(cmdoptions.build_dir()) - cmd_opts.add_option(cmdoptions.progress_bar()) - - cmd_opts.add_option( - '--global-option', - dest='global_options', - action='append', - metavar='options', - help="Extra global options to be supplied to the setup.py " - "call before the 'bdist_wheel' command.") - - cmd_opts.add_option( - '--pre', - action='store_true', - default=False, - help=("Include pre-release and development versions. By default, " - "pip only finds stable versions."), - ) - - cmd_opts.add_option(cmdoptions.no_clean()) - cmd_opts.add_option(cmdoptions.require_hashes()) - - index_opts = cmdoptions.make_option_group( - cmdoptions.index_group, - self.parser, - ) - - self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) - - def run(self, options, args): - # type: (Values, List[Any]) -> None - cmdoptions.check_install_build_global(options) - - session = self.get_default_session(options) - - finder = self._build_package_finder(options, session) - build_delete = (not (options.no_clean or options.build_dir)) - wheel_cache = WheelCache(options.cache_dir, options.format_control) - - options.wheel_dir = normalize_path(options.wheel_dir) - ensure_dir(options.wheel_dir) - - with get_requirement_tracker() as req_tracker, TempDirectory( - options.build_dir, delete=build_delete, kind="wheel" - ) as directory: - - requirement_set = RequirementSet() - - try: - self.populate_requirement_set( - requirement_set, args, options, finder, session, - wheel_cache - ) - - preparer = self.make_requirement_preparer( - temp_build_dir=directory, - options=options, - req_tracker=req_tracker, - session=session, - finder=finder, - wheel_download_dir=options.wheel_dir, - use_user_site=False, - ) - - resolver = self.make_resolver( - preparer=preparer, - finder=finder, - options=options, - wheel_cache=wheel_cache, - ignore_requires_python=options.ignore_requires_python, - use_pep517=options.use_pep517, - ) - - self.trace_basic_info(finder) - - resolver.resolve(requirement_set) - - reqs_to_build = [ - r for r in requirement_set.requirements.values() - if should_build_for_wheel_command(r) - ] - - # build wheels - build_successes, build_failures = build( - reqs_to_build, - wheel_cache=wheel_cache, - build_options=options.build_options or [], - global_options=options.global_options or [], - ) - for req in build_successes: - assert req.link and req.link.is_wheel - assert req.local_file_path - # copy from cache to target directory - try: - shutil.copy(req.local_file_path, options.wheel_dir) - except OSError as e: - logger.warning( - "Building wheel for %s failed: %s", - req.name, e, - ) - build_failures.append(req) - if len(build_failures) != 0: - raise CommandError( - "Failed to build one or more wheels" - ) - except PreviousBuildDirError: - options.no_clean = True - raise - finally: - if not options.no_clean: - requirement_set.cleanup_files() - wheel_cache.cleanup() diff --git a/venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc deleted file mode 100644 index 53d4581e2cfe00113767e089b0f53ac2c2e27257..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1560 zcmaJ>&yUe}FJJ$+^Z`@i~XGG>c%i*0b8kbik z%}A6Wkm>{I_5qk@=f*D!cK~d^&7HaBQ#YDifMxdb}3ywB5O7tul!Dp)r+dqf!*gAd&{| z3Yi9NWR+gFbp0za*I?$a!*9hKx3G7bk z+}Ab@%??bp!==9>?bSt-Ysqt4X)jCf)S2t(_iiUywRs0GHL(XS7Lg>udiL+6U%M9x z8*z?gaNdqNFDlspXS|(oe%1(mu@ZAGtBiAlc$qiRAZR^WP`k9AwVmLVEfLd8~m`eP28#mwHidVefz&0Jo#Q%X}A8Z zDrIGo4H+2BvEAF;k9>TW;LV307|0j@U?v7fUq-K7U%e-1^ht-=r%1O&UO`9{o*+US F{sU2%x|09^ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/index/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/index/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 6eee595dfdc94735942c46bb7c3bb5c7d245f754..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 190 zcmWIL<>g`kg0lr566ApNV-N=!FakLaKwQiLBvKfn7*ZI688n%y#69y;QY#cP^GZ^S z5|c|Z^Yavv^HWl}{4^PFvB$@!SatrheG7EG|^9mA^vr|)a z%QI3_b99T7(n^X7%FRG>`te``^AdCPGePF-#{&g2OXB183My}L*yQG?l;)(`f!y>N Gh#3GfH8WfQ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/index/__pycache__/collector.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/index/__pycache__/collector.cpython-38.pyc deleted file mode 100644 index c24519f7cde4b4d0acc056e784d41b9bcfb46065..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14156 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 axcgnt-8;SC_-Sd(bxKdU#nQ>?gZ~3*&uO^; diff --git a/venv/lib/python3.8/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-38.pyc deleted file mode 100644 index 516f4b3148e5fca0de84d21e43cac4dc727134e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25749 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/candidate.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/candidate.cpython-38.pyc deleted file mode 100644 index afcd970c1ae11cc60796b34ea039326f913a338a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1421 zcmbVLO^?$&5VjNNW4rD0Ej}br;6x-g<%9%62vH$GK!x~{$i;8o+J&%A8f+KXrEuAm zIPo9gxIczJkSix{oH+n9X}i0Ka>3F(8r$RX8Z>*J3X7$5iIN*c_#)UMB9Ls; zOC+LUf zPk^h_kDc0Glk4@0ki)#p%cp#xGGpSPW@T2$y3+{FUrr^fgSo>LC|7%CTuH41U{Qyh zLjucr%xY$&8fvT--A3pDY}0y)PqTBrO}=02+M?=Kd9^w&t8B0)#plD&j#x>xuJ=J+G_wLg9G|wR@3iO&b$)D|TKEgeoaKPxk=a1s z1M7jA!vKPQM9o0YscxU#My-wb^1`fV-<;NO&qcc!U)g5055HMt_75HOez-v&+5x-} z<5Uf)>Pv%I3@%LDRbM)q2H|bS4bbkTTg=d`r diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/format_control.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/format_control.cpython-38.pyc deleted file mode 100644 index f01064bb303c2b3e0d242c2f380bca33f091fb23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2416 zcmaJ@TW=dh6rS0e*N&4mX=qDZ=prhFp>_ZvkfMSrg*K%KQ&IJymSDQsnZ)bt#hG0< zjqALS@Gp3BKVKtgfA;@=vV+-Q zia6aY5Vz5@2N*cvG$JwWP^#ueWW;92)N?bkV!LBgB5ZjJYgXjMl};sgJ8oRBk|tr`N8wPg#E%7-^|dsP{e<6^d6*`CRG1G%UR3YObSM%`1Eu?PGeO)&&)OIS=}=BO z2B#g9FLIMxhqPmrHg;@Y;qD>nIK0Yh_*R6==Xm{)9MDdc&+`TFYWy5OkMA5eaFeBC z{%$H`KVM6eT&B@*{ho;WLVBC2^l%A(D@?W&0g=qxlxghkcEh0S`Ci`-w*4*P!3Exi z@WLd^{U{Q=RrAo=fiipA)Z9Q{L(gtv7~vAzu3X5;0okV`LsQo@WsK;EFz_&f|B$?( zZTQQ~l$Vl}ZG?$0_lmhRiS~{OEL)j~Hsu^t%Q}V^L@wZSw7!zZ{gr;$Zw?Y=u;9(z zt`Jc(+t|!yfA=f3w!*?B7ZR~piBm43Y^A&~3reT7`g?`TAQa||EkbRkjv$6h9g1!^ zba-*bi>;|}pe{XaYJTDbrC~&Ra72%6BNDO-29gEm@G!tRFAO;kR$-@kS4e%EayX~B z4r5}6v8$M8`V3>ZeAWad@P+{@5;_W{0b>|2p>=rq*Z{c<0lB0G<-pk^6T#SZaR2j2 zB@j?ZOq-h9==#Wum~e_CNssmr-kynWO-$sW(H_>G?|=M!|EBkRztOM@rwl<+g~G_s zGRBl^RE05iD$G8z=cl%g*g`w%B)8Yv75!Lq3J&zqqtMQ8F=nS5gQA0S3#4AUo6 zF6ERP2lO}O=-A-qgzlpRN9ML8pNx#LIUy7tJ^5PPngDc0CPyFJisJSq^1Ja300p}$ z@|w!0G3rOKPa&iYZ97j_T{Ulyj%d0~eM7tf^1!J@*$Ebt{q`0S^CG!TUY1zRGQ z7u2$uh~2_cAv_zei(SBFBv?Gi2Y$rFvmhF9k$s9?*+&?NS)&FuURn6M`d6dN$K|JJ z1HDFvH)bo~?Mi1VLfuOBHS}x~14neb#=gcN6s9BJhu^_d-cD{SWa=5a;V6KzAr~-2FECBl& zW{C$2Cr^&9hQdKO2T^|3r5E6KhM=aqg0r%gGJQ)`-wL{Fw0^3?dmqet?=AcPzp~2` zfh)9=Ci;EVm0e!Vl#S`F%1geh$TJwThz!z3m%tth{eGWRut6+hy&7Jhwe*cWK$CW( zE-&MNqQ)37eSqX*MV+x7r6qXOOdHH*TT;=Xzh|auh(HzaTV`Pi#-(yPi3ooLh-`326-4| zWffi464Mu{g<=r8c(bwwugos%jjepI4=qyt>p{(xgu*ZBsG*|S=|)ckxi;i&Hz?d& TrK7%8TC~gSMxE9HoXh6F2Lwh? diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/index.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/index.cpython-38.pyc deleted file mode 100644 index f6a7a221b6bf5174efb3ec370b0d751e5a075786..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1146 zcmZuvJ#X7E5G5&DmR&hbnkGZrK|_aXh_w|(Q3M5AAjlE~{aCcHib%(DWr-!}d>Gym zAXEQ?Gv>$i4{+_&t#g<5NZY6jlmJif?!@EWd;HkzbrGy@;^(KQK0@EEv%VmPUc*)| zz%aycg~m7|7#$!+n0Jks$Gs~r^SRG_)?&d|lC=Q0S?F-UI`2`^{Q;*@f=x^0Qt`ri z>&sg@>KOozGR#m$7|y&KG{EkjFmv^qX0bE^ELwyaOf~`xHBUV=`sYZdq*ZvL}04&ggWv}2%ZvEsZCIGT{VU2Q3%mNBjFD{G~GpI8#JM< z?$Gw2tT=^gsDpX#wlMJe_swE(g? z+dCg}UhS!qftKR@xy_}}t>&`Mt90BjUa7RSg7n3uY(q_3Tt#3I*}wtbz!8pG)17tg z`m2EpV*gt%i|qq^16yr?(P$2=jtFo~fJJIm*tMZ~hZqDEupa345wEQf{4Vse? uFZAMR`p1{YhbH_0r7c>U%}r@%GvTWRRr}Zu_yA1gZSE3G5cwT=i|-%ig)L?P diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/link.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/link.cpython-38.pyc deleted file mode 100644 index 9b9de3d85a52f54feabf148d04c770d0fea079fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6659 zcmb_gJ#ZVx6}~@!00@E@#Uuf-RB~CCawOKeA=oQY^!Ye&QIGaynuc#F6&{ z?H(i%0~U!iah235shKpIq)d}0MVeGelO}U*DtD=!!uj4F00JZmdnO=n@7>#X@4bD0 z`}XcmOcXTy{@(o0gFhV8w13mX;LpOt6q(~R3dsRXetB(e?S`}V^E+#m+t zl}+CpM20-}qgs+vc>W{?vzgEM_D8Pd>}nK10RP;3;)TFZfBx0Yubivb)~_wsLC)OSCPBM2|O`j*3yCJaPn7el8^BXta z4O&9>nkySz)@W^mKk^s-h(!TlJ;6>Y?2N*`4D4ZGUtzYw&MNGyz#aj1o-HWsQNXXUQwp8~ z{5m_W;A4Q#u(E=Wvp3kA(BcGeXW62{odmqZmKFRm;B)M}f?ol=!Y(M-W*6Bi-h1^M z&C;s#h@H0*>xLI@wLiGUn}SOo#?p3e6-LbVF=JDx0Cm%?ZNV}2^^ox=r==~u0Isv| z-nvn+@vGD_saw=YF!{;EC4YvYqwgZKp6g;d);s!BeMgUtU9$sBM{}$WjhT*tG21c4 zO2-ThMo(iM3u7+M$Ayme)Yu&F=y8FWzcG*%2DG=_2N0nYASEtCZ#S?JbC+qbqq-e8 zxQ%s1Em7lkGxEZiGdqs#GY!G(Jpx*1c|Vt06mY2$<+AOCGIm370LNa4+K(Gta3w(5 z>9H&AdejQp**+)IDH67fg%@rt_0e551%KG`pqta&jvG;U*}kpl>{=AYt{37J#r(mo zF5TiyMfaf3hu8-^c9|QycHQGXJ8R1(uX%tObhdA<-Lx-UTwSv7G(2es?zX+o2PoFJ zhgi8bF3ERgo=#*&Wgysy zG_HC%~c`JT-;gGf>;OcdvrVZf^1Iq{Mh#1*cQ3!}cv725GM-|X+8Hc07WT3%ne0VgHzAUVp)g4@veo2593l}p$AJ>D1-iy1rgq>B}1#;AOo=2P|D(d*`{c3X>$7?qH) zPqE`OV9Hjdeb_$JvspJ=FQ1a-L~EB$N&Ac{+<3-+CN+vO4{0KfVn|FBrm`VkCfE>7 zF;6pUSRmAx%mI-kR*B34Ap71%7@##$D;8&f z+$Tl60^BWJsQ|N`Q%gcL4e_QO&BUd6-vB_ocXis+_V%(JqhrXk%2S!A`aNUE+_5?) zyqDb_>lmP<`D<~G_O{LZEP9b&=^fg~%*uEAa{D+oQ~Q*lG-s_EDk!p_s#oX+yj(~u zYNC>?fUUh|lBd%0M4@u)XwHa8kd{d{ZQ;aWdKhbk4_i^plhTJ$azW|7CPXBZJrEb< zd~ud2Eydv+f%z6lk*regGggx8>GLJ%(nK(e6b@!dw~T^5t#=clM>k}|p_rhqJSH=$ zkQQ&?5y41U<&sgpO7g^3HIsFcuR_9Xmz2l)QwK!$V}inv{I-c4>IpmoT#}Ww28aDd z#m8G9*cy;FuB4?e{4h~vy?wD?jMYw4bHm;?Z&N=$SdI7UF3dsN3G&HE)o7yGS1sF4 zRZHD}K(&7KmheW5*o7sGP4ju*7M6+_ah{|pxfB*7<#X zAl71iS5>!Ni!$fAay<%ycoVaTMxqu=G%VAg6j&r^lw*i^2Un^^uQK$`EeAB|7o#HH z>1ey!bCjexst-oxTM7{r2_=7oti;4=<(GX~y&?hRkQjP>43}E)YXB(N?qzn6_*4pZ zGHUrq`HtDKm{!m18Q)Azu5z}3;?oM%Ldw}RLn#Q;I3SxOnTIVdwvmm(-3ZXL?@!Yi zaByftj#@EV*p%qkcvDjK*UTxsJ=ZI92k6?9UoX6VpKolucjoI~yng?U^3WQ|jQvou z@jz=#gNaIEN0+m-J)z+@$;C*tw?Txn-;@KEePvMDk#*b^wMM!bWi~|AYQE@hM;UY` zn3>0`>97DODGqY@EijTYTBF*7zxE-uq(PeYQCf;@tur**HEP8EziXOv26+!IPF#Uv z>8A4`K_AhuZ#joYzWh5-4zKH2T5$$e(U;U-IU^hH`3{Dam5X${@V2_GtX`t0)$=Qz zfUTCXY7cnE z7iIg^Qc)(Zk(Ec8IGl8mjH-EFlub3jR=QcBVW zN-4?oE$S?cN@CH@h~lPd$f)8r=HZ+Rnm^;!p18EJ>rNby)-M1vU1<@{^_z5}*EX%a zqLvXq#e8B!GHo$3o^9WXvfH1hv-3ovh6O-L7FyxWzX9&n^`g=30n(Wv zZ7CA_+V-PF+sgNPAzdAsMp`Bhe(7QCA0&*}ASBbo=}-MwX`g|~NNG9bqAD%_91xbC zuX-~zr2?seAHlS*srbJFpo6}ADS;+m>6>)6O0oF1 z1bLAZ3ZbmM!gN2BP5XtVT0my%gNDd;qrmU{-MdP3#;BObCyEaA+y6hx1> zTta=vM-oB7n;z9p4%dWM?D=wu>Tl()gs?ljhL7unvq&| xLw<@l(Z`+v_bMNgdz0L|X#~GdWlhp2pPY_Aqi7WMnM_eH>QneqaTNEW`9EBX32y)Z diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/scheme.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/scheme.cpython-38.pyc deleted file mode 100644 index dc8407033c5c6eefe76d89db5bc89617d6391446..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 862 zcmZWn&5qMB5O#jrhKRzIqXnl*G&vw~KnPeN!EJ@K;?j$8<7s1Xu z15O%lci?s!_S~+x+(~WZ(!lL)E*r&t4chU_HXbhhV~zlM?R|^S%2L@1i}uRbwkfPz zmru%@H)&OHS=4@G9!cZDHI&x;G@&A|h}l0vb@#F9`0pB83LSi7mmlA<1?V$43X)4yrx}1|p=k-cf{{Qkx z{%&AKajQ>q4aIQ38lU7G^pN#y`tcz_7j;aqE+&k+gfQ+>!lWA!rixMi(K%6=wA2=( zm!xbR3`z}Bfx~`+mD8=qK2_4o*|<*;%*uslToNFRh8qP4&wpbsqviL@(r?n& zxV;lNkV7LkAVi-FLE*M0=y!$qyp`tWWFiF3h!8Hs8xlQ%JHZwa1O)@FEJ~BXaz0Dk gJu>uTyZlH!8;mEefwBv3efIqL^otM(LzU9(50LEW&Hw-a diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-38.pyc deleted file mode 100644 index e1d713c68e6abebbdd49e9eeafa9219d1aaf7ac8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3253 zcmbVO&2JpH6({FwXGg1*Wh=Iuga3#kNyL^=G0ryKE!>Gqt&iu7f3q;avsUY$M+t8@4fkA zc{w2P{ImM^quVQle20U@$AQ5o(B$8tOG!#O>D6D_qh@UNEc3N{HheAap(mZ3eqoVR=Je5JQy#tnWcU+t|@!dAruWcd7Yex-K>#&o*I zUOT0|tDlmznFc2$4cN6~yLUaM+oZGfFVK%{b*NrV;-W0FB<9(eMMa!5m~^XHNF*-^MVOk>avr>2^_yyymWAHPmZ@rE#L7c%+6=UzB+?5*)T%{`|`aUq*L-egE!n zqK98>ZGE=&DGJ=oq)PDc#m9!hC(z{2p<@JH1#Y4}n>neK+9%|g_T1D--4oLDQZH@5 zw~_j36TW^Lph0?Ro5dm-ZYO2M#=i!3gXKRT)YnrfUQwsMzdj0D<>=7n=MtbOUl^Pv|}J^#@1J#F@fvpHk6PbmAP- zBUf3w_SBiUI5%;D!=Abm=af>i?!kp+!JEM%NXhBB@9jE<*9U2#E&xlN)67gf$ z@a+D&%Byv7;H^$;HnTn!&Fp?M_#PjHQZBc_6 zOG0t^?7{PWXhsJP1cVc4u}j2l>=oU$26WGc5uMs8okAvaDu+}U#$KdPkj?QVmWjT zpx&m=bN{&m;Gfguw|{{D62#o>K^m{sTx|%%H?&Vvnp!9RU&uEEXvCU7!{X9n$By3@BKYfc%<3>gRl(n$Neq1O>$B6=?D%bc#$N=9D$HmGf;K zQ5HlYg-C-qkvAsbk!u*27&F$^GrHdKbh9dD_81eeSO*#68g$y-AC-{H(5u>qTx{|+ zT=;u9VFPZV__sh+EJ()uIkt2=-$R3{Csl^gaq)`hj($~) zyeRY~KOkt09}uhq4C>Yq{niBa->iKH0(u?+7!VyQK8DYN+QA0LpP4eR?g&^hk>NpJ z9e@14DLNMeXJENGixcsS*?BNw&NdTo!K}WH!SX8mznW=6{8oGX&JWRKtJB0Zj{km9 zq=P7`3pUWLDB2&z{A{HWMQNG9^islODRTzJJQZ)Fl31I>huGc5Ztgilp~eD#oL_?` zThRHI<5)Df;Wzyiv(ovIz(w7_QVdC1tinkA45!|JO4*GL08^#tVl9o4p*vC;lxW0T z@6AOHfMz!@518x%l%VPh4DcGGuN%Hu%>^#3xplbKIqU+1Iiiaf9IN`@;`)mcYKAFGVEk46`?Ehm=>FJnGv>*8g?<502r@TE|q2zeJ)tc4Z25biBMB`_{@!75iP=7l5vT9ATiE;&qz zyNx2%A&jhzCERSZGK@=o)h2-uBDM2ODOe(Fsf5c~&pa;%N1(%d1kVf}mx0-(9N!G> zh)2JrJG?^_?IN&v7lVy<3D|g-f=xJvUShU^@R=0>A0zkmMa=3KXf``->xUN4D`r_q z0G!#-Ez>uGpOc@i1$1jWtfXWXRta;Y^OGl1w`@3}ow&;svY9nmTr9}vUw$?r%nDKo zTT1UC+8eSu;?K2I?P=-QI6?z7g0{5i#62h9ke=H6E(nmF8!a+&>ADL0fF7hE+d(V< z=uB-3fX0d&b_Kdl$x3Qww}+L@wa^4|f%5)V#ego1kWOkYekDOyQ1oUmW^nGw>~;k0 z(jM3Z3OWyj5~KL1WL10ehAA0dTMRwqTslw88_Kcpp*vx@Kzc zIiZxBf>ImGw2d5@aac>igpOV4au_8egxlY{){{?$%_C?myK5|~y;Lsq+X}X@4fjej x*iYgx`K14KM?==v#)fOO8FZIMTjvN>z+nTlX85%0>MIO07eJ1p1ds42{tt2!%y|F+ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/target_python.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/target_python.cpython-38.pyc deleted file mode 100644 index b39cffcb90710ab845988740fec8d7874f73e264..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3219 zcma)8TaVku73K^niPCCqH;r#;YfOQlv63~nP1-&fj?vb3E@-0|$)-Tm1T! z_|KDnU2>d%)5rSd;p2CB$^!`LNR~JQdh>*(e85w8;4=Dl6EAHH8n*2v&9pUWF-NuZ z9{L)IpSB0>v@__WTZ1h-rkQlp?ZGy4-gRV4`cEC{t4n9@;Id>NJH7UEtmgE4yxJZs z6PA;r$hA?jx_Yd18RuCTXQMncd6?xgH$7He%W|DYNqnlp^&#ka>4Q%ne;Ph`@6m%l zh97;>@4w%Fx93*gpW@O~{)dHuwkW9@dy^tj81C*x;~}lSel4T$I{qqWz@#(ak_}wh zmag=kvVkWXviZ~*G-_`KP08U$r|RxS8ZJDZnu9z${jwu)J<5hrQBIP`s8W~%B?_Gv zN}Cv;`A9^f9xdX`C|zg;De_E-7^AJWI2&6<=4j{xs2U;dy|k96`+Z%n2bSJM#4{!w%7s{IC3`Gv}Fa+!;S(b1vOyo@tmS zjgubrp7F2QyfJezyEXG5{TYL7&l->&t947#pRP@7Bf9Q7jx~tlaJPtbl!^j@fG6o) z@q1Ak4d(>>>citeyg#yy9Z{-C4-XI^@_FHLxzt43%t2&Cq?K5rMeI*)c!v|MRc1sv zEsaV8@gZWaPvTPTh?6);#3;_>hN^S@wa#IbiG3yZCvjqshdN^mn_)^>Dv8(!Vh`r2 z@7H6O$+Kiiiq6x6Y2=Iq5OusiAt2r*TV)ytzY3eoLGjsEqJ`97`ovQy0*P_T%qEg;ff@ zi{QhmLKVM$^EW0Mmq9UoZ4($9405|CMw4u4y@^U}ssC9sP7$dTv9T`ypyfBhcfl0# zLznMA$KG%%7Ch&8_qMBR;W$24Sy*i5wQ>>ns=FR|P5e}Ohk2Y;ZWA(Wk?=k&j^rLd};FpyLhBY=hwfHHzs`kCH%G8&IzW|0XhQjJwpYb_L2}+2A_@j_KgAX(QHDB|B_fK12 z&ENj&=X#EU+^j9>x%w7VRPK?QRt=zYqAob51^WAVN~&)jVB){%H8f5&j{Xq|i{B-5 zq3{*_tu8MTa89082P+W#C#t-#Le*W5%G;P-k_xBcu?}wUh2QXLS>}J|H9L&IIKBCQ zW4aM3$^jW|QTiSlghpG8|9}=Dmer*h=%s?pDerSmg_$skhY*W1$KSlUYs<0K07ST_ ze_vwqBV{JKu3xJf`S{Ue0qVrbVvOTOE>L8LM?}jiA>Nj;w8xZa9MSnA=q$CN+|`q) z=Hie7)wU3V*CicTMxb>yQmDK`RE#t)&Ekiq!WZk(td)v>&#PJsN?YZr@`$~9EqxOq zsS`<<(zG2`qbw2iJe$p$o^GSR^2no$3G|7LspDe|sgu|0xRf#w4Cjn9kM8f9%_hG< zFXuCRULRMlMKqN~sS3lY6NccjNkZ*z7=AH{l0{D|3}rqHL;W){`85)6kRZNX6SOZi z9mKcsl(egS?zOP5>HfCU^RL<7-W7crebo){Xt3nbU{!JI$WV+fj=}LFDT6dFhjp=d zWm84nZKeed1e*A=YA!wqmYNQW+Na<3Jd`Dw>!3a-VM<_Q-L~`c{X;c0*4{M_t;3dn a{Cjn*?h{Ryv^#x%g>_k%d+cT2b^i;3J60nA diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/wheel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/wheel.cpython-38.pyc deleted file mode 100644 index 011db68802149bd9898720b0e5f8e89c7150a586..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3182 zcmbVOQEwZ^5x%`Ul1GYC9M_25G$}4X+L%dn64E3{1%XcE$cfQbHSEM`SUZ;!cS)Xn zygTh4C7GaJDgn(?3iKCPF9rN#k{__>Tc7&Y=b(W5&7Me+v6F|8xV_z(-I>{$Z)Wb( z<>iKj-#7Vxzx)=nf74?A=VI|b9`y+ZZgniqxSg;L!`n&hq0?~~(cHuxRyq|kuO!uB zty5!`sLA)it0vyC-l;R|Ba7F#cVcl*G>)Cl61VSIt@`-O+ai}jiL_9D)$ z2tP`>pUZ4N<^r5?upg$c!gK-u9ptzGYo_CvUaUUY{E|2kv*~1O9i|!VJ}$6?5}u#Wrfbfe&lldl)*pn%Bc-n)zB&nw3?w+ zPw9+j<~8u^+%uGhq15LnONP>zqcs0!^%!5`%@Yq+H9mw5khRR0;p>(0pJ#X6kWs7v zt!KeugCda{tPvIsv|{DQC35^;CZ|}Pi5tK2D{N4Hnib#~gw2JMBm~-}muBI2Y*jmm zhpw1l>57StW`TAP80}I(x(sfe{>axJo}b}S>lg;s#JYd=2shicKD6$?bOe9yGR!U< zIfXr86MNzuJO6O^uI#Psxp%C`R?E>Ygexe6bR{XAEmzyYx@L!(J=ARc7;sl2>B$S= zeb-(qhWT0^=c}VMkGc;8Up3jes&;yX%n#lr-dY%^g^+2KtPL|R618Ub1o=Z<-&CUL zX2ZN4kkw5LRc15KvT+sr$@mq6`XGdaxCp~wGs(J9qT0di+;(e4FB^FwMIn?zSBCJ+ zKoah>Hw}%h^kp{6bxjJ~tt(`W*fls<#aXKB#>rt3^>sz%NnGfL@i#G*d>(t{MLJM7 zO0Z3}9C?MvFB7>@T0mJ~93w9i>*vJsrpD7s{St#!X)+hLtUhs_D!b%dVoi3D{!W9r zPsS^YcV37w#hdPR9gn(%p)lq41d*o59w`38m?cvKYwWr=5vUoYW$ zW)_Me02L17^w}BWfMe1FDQQa7I>|K&vPLsgmY#n~*n6bZ0g;AVw;{fH`VCYNHJZzyLJ16Ki%1qzaRsCO~Wb;geLh84aT1H!GMD>@f;pS&B$Y}jXvVI z|8r~Ji(bXMAc@~<%HQH8H!$cI(SL&wHG^j|pbj1N>4Vo`j$*B^m<`hg9f-rO$V~|< z`)7H6#vT=MqJrXK4k41jud8Q^idkekyP{hdGoEF?_BKl=wW*OQ!i?*9cGGUMCa%(S F{tte!P{#lO diff --git a/venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index f36ecbf3fd7c526fde2b98acf0f598265843bcee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 212 zcmWIL<>g`kg0lr55{!WKV-N=!FakLaKwQiLBvKfn7*ZI688n%yw4L+wN)j{kiWLe< zi&Aqc74lL`%JYk|b%C73lGGH1(vr-a%#zI1Vm&TDO~za7@$o77$?@?k8H$*ICV`1x zPWmOe1^NY<1-hkq1&PVosVTbU8L6o`y2VLpB}E10W*|BJ_{_YL)S|q^9DS%A`td-a b%#!$cy@JYH95%W6DWy57b|9C224V&P#>YHo diff --git a/venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/auth.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/auth.cpython-38.pyc deleted file mode 100644 index 593b224e889ec8f0dba91b6b2596ce1241774ecd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6978 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 U4>?_MusU596l0lZO!vZn0j*tLHvj+t diff --git a/venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/cache.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/cache.cpython-38.pyc deleted file mode 100644 index 7c8a1ddfad3ac3a3d2aff378faf14ad4a03a788c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2691 zcmaJ@NpBoQ6t3!Jrl&o&$BuC}AWbBe0WwAiA|wzbv9bwe65@m;eQDZVHFn#*rK-lp zqwxhBN$M6U0%846iPP|t$UV~_Ej5oPCw&6XAJyMKgbhOe z#KG~$fx$I+<*y(Z2??Xj%4kU8YiCw&hc?AICv$Q)bdBz2wY(nIjb6*Vyb(5xUeEk| zBAm#ZVbhGgY%-q;r;Ognrt?L79IaDI6mpNshLh&C} z9vATn7ckSf5lg;^yKrzT%?=0NLoTbbki2c_nV7A`2{?>YUPV2y(sjYB4CY{)&kNZX zJYp$&oW1w#!Lw-b&dtSdqlb^X-Mih}Fzel~@GNnbP&~}|K^;k6gjY5}C^9r8@7Ms! z?rOg$$~-ctZh@Ej3I|LIf5sEzbU%>tZlp-QVO{i2GKb6kKhVVtv6l?^IiQGL_NM&&}hJED*#JEszPS#~(--Gbuj+W#BXV zJ)z_YDb6{7LeZYJ?u*M5<|uha3hOE00!-Fm<8Ck5!leup1kIcSwPL&+ zto5Y|T<&3kAG3`Pa>-U## z3Q-DOzkA;(hPh*68ldR2vR_reuHhP^Gk2T<1XFi*NulEAdB5VL(O+C33_xNFA z4mJ&%>j5TVunft|#>{Q5rpaoM%0PmBpvs^xdB8W2PUI9RR=YR1@e#UZ!8>hNPhAK81(wVxVlD&)!Y~IvsJ#fXI8{-k z8;4FHx{l;oPn-jbS5V4Plw`4#Q8WrKMpm2!@iDxz27*{EIz9z$hEe4=}w$4L$8d@v#EZMe|z2>aBL$X%u(V_jD^~(tQUoPxz*9H30 zHC`ko#+G;FUIn!)*4`89iK&ruV}aJAHfsYIK(9s0SH}(%*C(@OhxTtt#MJu z<;x)2u8F*8o5hVd>vOYBe25mjm%&dH*BEi zLpChK23*JrD)=;JL?^I}j)%`c(>1~Ka)Y<+qvMaxed@?H#xt(?J#aFvMU3BI?qu{v zMr|Jp9=U>o_oFB;SwBO)8AZ?gaW-D5M-eL%D0eLK5$_+N_6Z8C20b}$2?@`#gSKGK zbpcIGgTVIk9=wK1k2-F%<~6*!H(?r2dtO{cQ;eea$A2ZVbXj0K)NjM}+KHgwvQl&s zY;kBI%4{?c$hN-p|3-4u8ZI8UI=JIH0Gwx1U=ELe?BFi%^i`V44qgdzODdk5tTO4O z&lz8*Eb~+*CL{HQ|5{dC72LK0b3@n011uZ!N5E98;p12$8XnE<>3uZ{(AW6iM!pHc WsX=L4O(@SMv|N-9ZQ34QqW-`Ae~60! diff --git a/venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/download.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/download.cpython-38.pyc deleted file mode 100644 index 3c8263f10b55d716c55a0e19a8c124f6a3a9873b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4370 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 diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/py31compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/py31compat.cpython-38.pyc deleted file mode 100644 index ffe68f213757558ae6d429df94aad60fcc33ef48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1191 zcmZ`&OK;RL5Vjp}HhrN|^?+0kIUyp^RumzGgis}30;Da{77Do-6T59%=Yj2|-BoY& z%x{1j{W1K3Tsd*$%!!$7x0KgJo*BpE`R3*4b92)K=u7?m^}~RWuedo+5p33Bxo5z3 zNJ=zK*=Sx7MNLrflvA=r$~8`OXMfs0p#(oTWhP9+Rt9PCh^RpEW1{$bmhxAmWG}&@ zPm<0z@JbTeENtqcuB^1f`?=Mbuk5gw;n{g&uvv%Yt^(5}rHZ6X(KJv@1;-@iimMLD zjtW&5WT+y*n6h|p^m#fyr5D-`W0x1T(XpSv#%h8aXI1I-p^pn$${lT2&Mt1{#>5^j z`zlu2Xs=_r?X^9SR$YtV419cm7SgyX&Uebn>Ug6c%Tgg)Zlpc)q^+&2i>q?%C$Gw1 zC>e!tCxoFxTgX#b?h-IXj))+h?y+rhL_bj6Dbgn=w3h@8FJ+;d2(#MGjc&TdzQRqy z8t$~&Zo+*CcE_C%I|a^u++OuXy;|q>@}R6`wy)Ll!LHV3`PR*Rx3;xib=nVVUscAf z*25duv#O}2U#W*pBt%~3UWi2ujRPYzq@$(38@V#E{4F!g64yOgE(CT&_8Lh!>o-D4S`U{v2KyqKp8D~@)0Vz2gCG< zwFAA#i4S0)uZ#!!bY!vi46B{6-e$s^(CrRvst>WKOAwZ8UnXUAfnNB3X~*`xq>CNF_6yNW3sF>RU{IeG z;_X11)03_cs>+10GXP*`kzGWF({PR42A{M=!Luo?dn(8p8kp diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/py34compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/py34compat.cpython-38.pyc deleted file mode 100644 index d08546751bbc2e4945ca56fc7188d66d359d4e7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 450 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 diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/site-patch.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/site-patch.cpython-38.pyc deleted file mode 100644 index 4ecaedf4917ba07383ba13d0e2704d0d41e069d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1474 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 VdDE}XOwU{``F;`iYiIq^{{Y|oqxAp) diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/unicode_utils.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/unicode_utils.cpython-38.pyc deleted file mode 100644 index aa08c80cb8821900bad0c22e91e331d659ef63b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1151 zcmZ9ML2uJA6o73f&C)I#V;cf-vJeuhMAs8yhY2CEax6$=Y^y*eirv;Mbu!ywYt^3M zhqOn241XY3xNzgV6VFMz4Q%=O`T5z7zxSM@wY3_8@+1B8>6e4hPdm6>2n=3A(|aHo zVmL;fvd0|^V-l00({V6j4s*Yuj>{^{gTBI6m=C?j@FA*Kf5U3juH)R%;xfW^v?x~h zp}m5p--9q{f(-slz7qAoI5U^w37V5bG=4lmvkD_~JViJ5DR|Gk(t3>Kwu{WlSxvpg z$ktON$q9JCCphhn(|&z$Rmn`Ru~+x=n$SXO6UvAyd&|6P_@(KZQOfhxOo}LBoP{RL zt1?l;FcxE;dyHFi?r~Z4!BOegQYuk!J2wr@;5$+Q?02=_G{dx+inNi*G>pzTYg`OC zj~maQi9xDT)zsW%sY#MpHx~zXGb3WXn~w6TJ!+UHnp--069mEmRDx?D*P(h?t%LO+ zoGuuu&KJg(A z8xR9!=OUXw%VPEGgx-O{H~^|>f-Tj8CkX%ZUJ zUM3?W5*fx+C6FkRx9ddNXkXvCRpe!PXOer`D1fTAz~%od){Gii7Ld+QU|QQxMuZfp zrS5|ctV{uY@aEM#Sb{fuLA&>kRt>RKe2UA0{k|`3w8fwf)=pz%Ow9 Hz~A}{XXg*E diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/version.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/version.cpython-38.pyc deleted file mode 100644 index e6854ceb3b2fcd73e54104b8f789e8f0d0c87d98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 292 zcmYjMJ5Iwu5S_J+;usmZPIgkQN!%|LcJ-%`%~`24X!8U*j4$6>*5_?cFAMHRJFI!U)phoW3B5&QD^ js9lmKUHx5AZKoa3lTS}pO1K_RSr}!8x6>$M1>0jArK3_P diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/wheel.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/wheel.cpython-38.pyc deleted file mode 100644 index 5e763c96fcdc8dd7617a4916469a59c73262e10c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7383 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 diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 0b073421ffea16af6e163a5323d06308b2e063ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154 zcmWIL<>g`kg0lr55VK+hrAI&HK*6(AVyq(vXW}2*`~6=rpnb#xnW|{j4!38 z$XUjjWz?Xx)aZKW(+PAiQPVuCtX1YkQEZs4+;X;(b)j~uEbh`|XXmqdGr5wY@=wsmL#1dw zJ8e!b|5kzKr)N*69_Q$>c|RG3Hmsd>+Lx>SGeS>whTPh>YhlOM#9p+I#KZ6cX{oNe z5>YX8E1|=Yf68ZlGxKS_^nD}f{0xs@U*|&nV)6V`BtFocKNFNtnH4URnagGF3Rz@A z<*KkNx0Y+SksDXa(p9o@wX9tu8`sL#b+RMhO0CsKm8w#;YE*luWUsngvF#tIv)C5P zi}7yuHbo7_1&?v5lsTE%_-VNcXr>7FY1&894;fcfO9L>bc=QOc^ZH2ZFg_qm}9_z!>nTp(R(`&aMF|VIIwX%nCUP8n8{FxSK+)=@0?f3>h~OQ Pz9HP?FS|VZ@B951Pdkm2 diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-38.pyc deleted file mode 100644 index 5f440b165fc8f59b2fce3728709f3987a5aaaeec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8927 zcmbVRTXP#ncAoAT3$cl;+Q-`EzN0IL)6=b2rV8r1?~uA5HUPY5qc*znJF7 z)BHr57t{PD%F9#YsF)Im#q;7I{x5%PmygP+&12%EIQ5OO#Tc!yq}My0jys*^ucY~_ zY5rQ8zn&{?nU_`W_YtZ!-#kbGmMD0b?b3?9IfwkTSvu=p8uR~ zJt3#$ao{b=Az73!P8hN{VQjGSOY$X*n(Z0&?gra@dCMrD#Qf*e?^AMk!zh>JOBj7p zmN5DhjRwAHS(4LoP@bUL4K`uS8lZhZ_bE&m<Q)zao~z`(pkZR(@4{K(mPt z2}*1AHKf;(&LF*kbQbANaq(NH{Fb;Ret@xWgJX>HJK`g88KoIJgL*5Hm0F`2s3>+s?QSis1%5o#R5d@U zEVuk>gz`esiiZ|G70UU0RoSGfxS-3|WZ0@lVLT8<7_qVxdBBrP3iH0exO`cv;HtV3 zC>duyR6(m5XFmwkm!1-F;p0{iNwK8I7FnFVT#Kag>W>($ki~@rQ6;+Hlwpy_xuvG8 z)|P8h#Uq#eyI#E}c4`LGnk$~VjSgd<_(Cq%d@0@w8ck2tLM(c+TRHFFt*O9oNIzQe z8Zx#!!!XDLNfo)%p-LOp`=jNZM+!#(q)}$VD09KerruyvjiP#OKJVf;=exCJrEWtn z%>B{}-Q}R=i<53Elqz(?TS2QXTqT#Ka-+aqoL_X$oPM*U$1gmzVy9B^vBpXz&Q~gp zK(y-gU8q#8R11Zq}NoT7J{3-j?Fjm$#&>pE`S{ zcB`qHYC4ors~H7BJ)ExGmA(knGQMx&5qC@Kr)#^E_qY0;w zzVCv^F?Q`o$%0+l<6TR{Io*_WfMREft{+6MyjKgcLO-kt=?2Sal^RPAKmE?d)8r@q zpT*N5oTv7a06Y9AIE3C5rm&D(A|q_%8IctZa$Dpe{Q1~g2!yN>hR%<^DZPgjk|l1l zwo!pmT{0fB1&Cor9|h#k3T1s+x#+TMyNN|>el4n0P7@N1ovjVhRHaT!m87Qgqwl^s zBcpAsvJJLmsOQm!$xH~pp6ek~M^LqUN^m@SR4T8btutdGol!UJnJ|N%nn>DT!8Y}j zt2{E>(9>I_8~MUoVdlZ<^%Dlv<@yt$Sfusi;X>%~1l!2z2F5 za~^Gll1(h^4K#KZ*4c`rWzWiJJM_vNd_>0AP$->^VDZ>O5M63C>yng}6!S_2>WMSw zpiXK~ifi(%o~eiQo^+cQirIvKXV6C-Brrwb1p>r$>Lmg@MCmUrQ-{$ojTF)<9p;$y zS5#X?>if~zo<|C4tM_s!wi;^f2DGwwvo7~+N0&2_?V#gHw*$QJw2jy6o~1cyxWU#& zJNQdG#6Prl6aQ3dUj~wM9dr&;RQ_IcW^Rxs+e4%YeD4u{61jvMw?HQGU}g$DI8|io zMKnF>s5Py6a7yd2o}-6Qb&7^Q=@d(7xPYX$33O5Ud(p+OHun(q^pjJhtDZ{B#m<6o zZiTDO--{4p#Sc50_rQBPH{E} z^%A!6Q6lrRP3@&l`*wGNQaZk;CY^G-OEL`jlStnG8@FU97H zj2@aX3u9J~S=7V0q}+nmxY(hSm(b8GyobK7io zo6T(7WRPoq%xnIh_0pR4dJFh~_0en9dWM7pvPbNs<_YXbkye8=b3pY!0N7^7x7pNp z$4*lBRP3sQJvKdG#5_>nd4f0t$F44)I>r6Y6x-~?HY@HCs|aU3dxQ|@GX|j4IYk1 z*4IRQvWpj^44E{+ZgX{!Y6X7=EfHVl*yD?lozxIBcE^03xOK_Suk$ujzQ}B5+nj6$ zVif83gdwsM*mr+Qk0gAX)FvE?OeCXeMEB(K3u*}K)l#|V42h(W61fRD!O`Rd1oO=L7N*muo7F$X^_)BtBCmxj;PR>JKnJW{q8&8|P+Lq%ZF^)$CuA%ff^%=UW9|G)IHzC@?du_I9Y#DvLm$*7N3C}JW{~UE&NIU#B_0%=( zaF(O~5MyGCYSgEMc9_aTb0Itsy60%$EjH`YSDx;<8q|DT#qDIL)E88lsrkNCyH`a0 z{}d^70Sq>tbslq`|6gv7{FY}59E`~NG`IWURaBLVIYog2RU@GN&3*Waooe7m9uyI-^~p^*P@#ICI*kz^=dYMi z4eHB-rt;~-3K0T{E$Y8(M{)6xxTpcu&(JYE0AMiA4uUakp65f%L8AO zi)2RcBTd^ja5-WTE=5o^JYv|3sR$Nw(`+-^QS3u{U7Aj)rW<!0t#BA9M)UV*3=04TD{!LFAqvU5^--8Z zMHWd@_)qv)F;*C8gCYC;XX_@ErAZ1nRo7Fgx<(xo=!L{L*vvpNgZ>Th6f|F6k0Ay7 z*KPAh=DM|>S+`MVMOoBE5pj*Rn%m&(*|xo!TX+0XDz9gC3u@5fbTQ}K*>aqu$L{^1j} zcd?)qrCP?Q9X+X5P>gM_*+d{J-nR#lb{X~2CM-d0Ob*ihVlK|6u`2bY#<4=tQlBwdWq3E;YQ> z07`_uYJT^ts)BVgxxQCVJZeizP+UkaC3SgM*7aREwv+2G%#2m@mxDOlxpG*yYrfb; zdOVie?%q4kztUFFHI*D78zdiK>W@*XQdQ?i)`eUNEn>9abO{h7KrRG}t(vPAR59xC zm04%LBltSrWr$e#MfPeY%5FMa24GIZyoQ#B0~!{#3}I~!qQ?-v43YUU{H86asnx8o zza7AqWf$V1{)=49PAhWOV^(@ZD=ZEuIu3Q3z}o~UOru^WaF)Os0X9&a7Yc9TbKc#GmJp!VdVqUwC3^7F5b?o4N4C+&_B>u!7`s}~J$J%&$1=QvO;Y2dQAHW1#Fu`SJtaApJ z9YT@8=|cooZAyYq82U^(RC2bh4eqDL8JzVx|B8P`MjJ4_ajd{&`rC;CKI!Uv zgo}*}l#Af8w#JXhO@Nm{?mS}sbJsqazZMVZo=f`m0T!jBLddH~gvrG1L5IF!wT@6N zDU_JWI1B6)ecUBHI+BKW#pGdttnWA*!Etb7^s!~G4PVhO0N*zvs+~GTp0YYdU>8fg zfV%xOH?cXwC_~-Zo*WIOGt=iqLQCo?f*fw(yl}*bK@HC&<4vfRywKh@8mSz$v%sR+LkdFm~VzGKPs_OkFPS9m5RsiEANUFFpEF zUWeH6+~QutgNE`c>h9jevxfA1cUc9Et~=td=(ZI|mfv}i@m9zSi@KqD!qel1lzIzp zEre(12Ko`qtGk|BX;EC39&Q4XRto#WY`TH!t_f@wrB4B_ka*#OBFDQy?-V-(T*u0L zT4=tWF`5=4uG&(Hrd`yb9k;21stm*AWr5a@Cp)bqV!PE8u*TX%Y34!f zE#o%zC9hBsQHp#-MOsV^5Fn>g4FbgMa-2nU0k4Qra-qwU6RzJO!^E@K{yZKeaPag> zcZ1xEc^#)8B`jkE$jgoG;O45VMmlJo_%oz{lhCDeWA56exeJ%)6$wQ=g!L~{NMugG z!NvnO=C3VXy1Gz#@5*AFOH^3p>SA0-KX1%k{$xJ3FI>HP8MXOtE%aRaed+rAmDr(2 zGz2@s*uK0tcWr(lwy!05r`!Bzi#ucHu3x>P{*u;6sx!H@@_H2Wx{SHJ6LZ8i`3j{- z-Ju@jm8rV~$O%u_j(i2pjoNZN>F^QZOCC07=}^Oe02qhUrT=`AO~T14un~)_oBsdC z%8l6gXGexcGWgrDceoGRxDVUE<(Bh&OY082Ao5V<4pV?_Xo~; diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-38.pyc deleted file mode 100644 index 4f6f69f1a3b99f900539a16e45ff76359cbb39d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10811 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 PnEWl)WY@jOYc~D{DOp~W diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index c471c8ed62025e7b46ce27009f16cdd4be18a8e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 712 zcmZuuJ(JTg5S8UPcD^p*jt~OPwJ9#CZn)wG_yr6z42`Z3x~!6jlP!%U=Lo+BN`4G~ zKrIy=HABHV9|UHQ$LqIGes6cBx4mAQ;QDHRyt|@=e5;ec*ASDJ__{R)AP@nC7#fg3 z6H>^a1#Rd+7kY34eHg$4IE6EKxEwM9LwKa4oH82Kc%)+%_O8u2R%EU1NOeo!@r21F3dvUaY7&)w zBv_0!CbY!MAs+{?H-2S`^C@!Y3#H|x6;jS|GS1nkcB;J6ZaO!4E((}#oys$mhS+T! zJH;s~>y0`7vn$eHm@*fh?}d(?{7ZzUuvQlEg_I+7+lHSnW4OOPw|qn>)b%4<@0(tcZGo-pXk5%!2W8a-6*47+K$>$ Gm;MG(fz;su diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-38.pyc deleted file mode 100644 index 9e4a782bd6d35e4caf4022d9725ef5a35903bcd3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 954 zcmZuvOK%e~5FXo`hmr=BiX(yuabOS40#e082vq{XEti5oxtL9Cl1=x8?NvpzJ<%W1 z9{Dl+0beg^ zqw=#`6#1wy^C+>l(hu)He(>ZXGUUEP#N#ye{f#5jWI7Io-=fY;GOb)vfbuQ$0QJXQ{ zMMtq3B&@a_Tk=y;!x>}n4)$=B=>9#f8I5ZE=2aL>`ZBT7R5`A|+y{k8<_6akyuiDV znGX6*-)pl)N20uqYN;q7W6rku>iR#dt9*?4#4T+3u9SJ4X(@eA%B)aTO8%CVpQ<=r zzcgRcU|*_7KW>_$M2ZGx$#hw--_XPcZquZ3%&8r1etUFjrZ?z_*{ MoSqY1OQm+iA5z}tz5oCK diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/build_ext.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/build_ext.cpython-38.pyc deleted file mode 100644 index 78e0fc26096137cc068a3d06aa54b9b201ac8fa2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9895 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 G{r>~>&zau< diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/rotate.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/rotate.cpython-38.pyc deleted file mode 100644 index 5d8a4b9dfd9a26fcd0eaa023031e3324cb3b3ab6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2520 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.6 +Description-Content-Type: text/x-rst +Requires-Dist: Werkzeug (>=2.0) +Requires-Dist: Jinja2 (>=3.0) +Requires-Dist: itsdangerous (>=2.0) +Requires-Dist: click (>=7.1.2) +Provides-Extra: async +Requires-Dist: asgiref (>=3.2) ; extra == 'async' +Provides-Extra: dotenv +Requires-Dist: python-dotenv ; extra == 'dotenv' + +Flask +===== + +Flask is a lightweight `WSGI`_ web application framework. It is designed +to make getting started quick and easy, with the ability to scale up to +complex applications. It began as a simple wrapper around `Werkzeug`_ +and `Jinja`_ and has become one of the most popular Python web +application frameworks. + +Flask offers suggestions, but doesn't enforce any dependencies or +project layout. It is up to the developer to choose the tools and +libraries they want to use. There are many extensions provided by the +community that make adding new functionality easy. + +.. _WSGI: https://wsgi.readthedocs.io/ +.. _Werkzeug: https://werkzeug.palletsprojects.com/ +.. _Jinja: https://jinja.palletsprojects.com/ + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U Flask + +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + +A Simple Example +---------------- + +.. code-block:: python + + # save this as app.py + from flask import Flask + + app = Flask(__name__) + + @app.route("/") + def hello(): + return "Hello, World!" + +.. code-block:: text + + $ flask run + * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) + + +Contributing +------------ + +For guidance on setting up a development environment and how to make a +contribution to Flask, see the `contributing guidelines`_. + +.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst + + +Donate +------ + +The Pallets organization develops and supports Flask and the libraries +it uses. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://flask.palletsprojects.com/ +- Changes: https://flask.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/Flask/ +- Source Code: https://github.com/pallets/flask/ +- Issue Tracker: https://github.com/pallets/flask/issues/ +- Website: https://palletsprojects.com/p/flask/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/RECORD b/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/RECORD new file mode 100644 index 0000000..b84dba6 --- /dev/null +++ b/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/RECORD @@ -0,0 +1,52 @@ +../../../bin/flask,sha256=oKXJDZPqk6BN2kppYhY7euvhskduDexwetAAkeqfyfg,255 +Flask-2.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Flask-2.0.1.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +Flask-2.0.1.dist-info/METADATA,sha256=50Jm1647RKw98p4RF64bCqRh0wajk-n3hQ7av2-pniA,3808 +Flask-2.0.1.dist-info/RECORD,, +Flask-2.0.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +Flask-2.0.1.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92 +Flask-2.0.1.dist-info/entry_points.txt,sha256=gBLA1aKg0OYR8AhbAfg8lnburHtKcgJLDU52BBctN0k,42 +Flask-2.0.1.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6 +flask/__init__.py,sha256=w5v6GCNm8eLDMNWqs2ue7HLHo75aslAwz1h3k3YO9HY,2251 +flask/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30 +flask/__pycache__/__init__.cpython-39.pyc,, +flask/__pycache__/__main__.cpython-39.pyc,, +flask/__pycache__/app.cpython-39.pyc,, +flask/__pycache__/blueprints.cpython-39.pyc,, +flask/__pycache__/cli.cpython-39.pyc,, +flask/__pycache__/config.cpython-39.pyc,, +flask/__pycache__/ctx.cpython-39.pyc,, +flask/__pycache__/debughelpers.cpython-39.pyc,, +flask/__pycache__/globals.cpython-39.pyc,, +flask/__pycache__/helpers.cpython-39.pyc,, +flask/__pycache__/logging.cpython-39.pyc,, +flask/__pycache__/scaffold.cpython-39.pyc,, +flask/__pycache__/sessions.cpython-39.pyc,, +flask/__pycache__/signals.cpython-39.pyc,, +flask/__pycache__/templating.cpython-39.pyc,, +flask/__pycache__/testing.cpython-39.pyc,, +flask/__pycache__/typing.cpython-39.pyc,, +flask/__pycache__/views.cpython-39.pyc,, +flask/__pycache__/wrappers.cpython-39.pyc,, +flask/app.py,sha256=q6lpiiWVxjljQRwjjneUBpfllXYPEq0CFAUpTQ5gIeA,82376 +flask/blueprints.py,sha256=OjI-dkwx96ZNMUGDDFMKzgcpUJf240WRuMlHkmgI1Lc,23541 +flask/cli.py,sha256=iN1pL2SevE5Nmvey-0WwnxG3nipZXIiE__Ed4lx3IuM,32036 +flask/config.py,sha256=jj_7JGen_kYuTlKrx8ZPBsZddb8mihC0ODg4gcjXBX8,11068 +flask/ctx.py,sha256=EM3W0v1ctuFQAGk_HWtQdoJEg_r2f5Le4xcmElxFwwk,17428 +flask/debughelpers.py,sha256=wk5HtLwENsQ4e8tkxfBn6ykUeVRDuMbQCKgtEVe6jxk,6171 +flask/globals.py,sha256=cWd-R2hUH3VqPhnmQNww892tQS6Yjqg_wg8UvW1M7NM,1723 +flask/helpers.py,sha256=00WqA3wYeyjMrnAOPZTUyrnUf7H8ik3CVT0kqGl_qjk,30589 +flask/json/__init__.py,sha256=d-db2DJMASq0G7CI-JvobehRE1asNRGX1rIDQ1GF9WM,11580 +flask/json/__pycache__/__init__.cpython-39.pyc,, +flask/json/__pycache__/tag.cpython-39.pyc,, +flask/json/tag.py,sha256=fys3HBLssWHuMAIJuTcf2K0bCtosePBKXIWASZEEjnU,8857 +flask/logging.py,sha256=1o_hirVGqdj7SBdETnhX7IAjklG89RXlrwz_2CjzQQE,2273 +flask/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask/scaffold.py,sha256=EhQuiFrdcmJHxqPGQkEpqLsEUZ7ULZD0rtED2NrduvM,32400 +flask/sessions.py,sha256=Kb7zY4qBIOU2cw1xM5mQ_KmgYUBDFbUYWjlkq0EFYis,15189 +flask/signals.py,sha256=HQWgBEXlrLbHwLBoWqAStJKcN-rsB1_AMO8-VZ7LDOo,2126 +flask/templating.py,sha256=l96VD39JQ0nue4Bcj7wZ4-FWWs-ppLxvgBCpwDQ4KAk,5626 +flask/testing.py,sha256=OsHT-2B70abWH3ulY9IbhLchXIeyj3L-cfcDa88wv5E,10281 +flask/typing.py,sha256=zVqhz53KklncAv-WxbpxGZfaRGOqeWAsLdP1tTMaCuE,1684 +flask/views.py,sha256=F2PpWPloe4x0906IUjnPcsOqg5YvmQIfk07_lFeAD4s,5865 +flask/wrappers.py,sha256=VndbHPRBSUUOejmd2Y3ydkoCVUtsS2OJIdJEVIkBVD8,5604 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/__init__.py b/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/REQUESTED similarity index 100% rename from venv/lib/python3.8/site-packages/pip/_internal/operations/__init__.py rename to venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/REQUESTED diff --git a/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/WHEEL b/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/WHEEL new file mode 100644 index 0000000..385faab --- /dev/null +++ b/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.36.2) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/entry_points.txt b/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/entry_points.txt new file mode 100644 index 0000000..1eb0252 --- /dev/null +++ b/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +flask = flask.cli:main + diff --git a/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/top_level.txt b/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/top_level.txt new file mode 100644 index 0000000..7e10602 --- /dev/null +++ b/venv/lib/python3.9/site-packages/Flask-2.0.1.dist-info/top_level.txt @@ -0,0 +1 @@ +flask diff --git a/venv/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/INSTALLER similarity index 100% rename from venv/lib/python3.8/site-packages/pkg_resources-0.0.0.dist-info/INSTALLER rename to venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/INSTALLER diff --git a/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/LICENSE.rst b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/LICENSE.rst new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.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/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/METADATA b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/METADATA new file mode 100644 index 0000000..afd84cb --- /dev/null +++ b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/METADATA @@ -0,0 +1,112 @@ +Metadata-Version: 2.1 +Name: Jinja2 +Version: 3.0.1 +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.6 +Description-Content-Type: text/x-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/quickstart/ + + +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/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/RECORD b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/RECORD new file mode 100644 index 0000000..4819ff9 --- /dev/null +++ b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/RECORD @@ -0,0 +1,58 @@ +Jinja2-3.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Jinja2-3.0.1.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +Jinja2-3.0.1.dist-info/METADATA,sha256=k6STiOONbGESP2rEKmjhznuG10vm9sNCHCUQL9AQFM4,3508 +Jinja2-3.0.1.dist-info/RECORD,, +Jinja2-3.0.1.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92 +Jinja2-3.0.1.dist-info/entry_points.txt,sha256=Qy_DkVo6Xj_zzOtmErrATe8lHZhOqdjpt3e4JJAGyi8,61 +Jinja2-3.0.1.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 +jinja2/__init__.py,sha256=fd8jaCRsCATgC7ahuUTD8CyfQoc4aRfALEIny4mwfog,2205 +jinja2/__pycache__/__init__.cpython-39.pyc,, +jinja2/__pycache__/_identifier.cpython-39.pyc,, +jinja2/__pycache__/async_utils.cpython-39.pyc,, +jinja2/__pycache__/bccache.cpython-39.pyc,, +jinja2/__pycache__/compiler.cpython-39.pyc,, +jinja2/__pycache__/constants.cpython-39.pyc,, +jinja2/__pycache__/debug.cpython-39.pyc,, +jinja2/__pycache__/defaults.cpython-39.pyc,, +jinja2/__pycache__/environment.cpython-39.pyc,, +jinja2/__pycache__/exceptions.cpython-39.pyc,, +jinja2/__pycache__/ext.cpython-39.pyc,, +jinja2/__pycache__/filters.cpython-39.pyc,, +jinja2/__pycache__/idtracking.cpython-39.pyc,, +jinja2/__pycache__/lexer.cpython-39.pyc,, +jinja2/__pycache__/loaders.cpython-39.pyc,, +jinja2/__pycache__/meta.cpython-39.pyc,, +jinja2/__pycache__/nativetypes.cpython-39.pyc,, +jinja2/__pycache__/nodes.cpython-39.pyc,, +jinja2/__pycache__/optimizer.cpython-39.pyc,, +jinja2/__pycache__/parser.cpython-39.pyc,, +jinja2/__pycache__/runtime.cpython-39.pyc,, +jinja2/__pycache__/sandbox.cpython-39.pyc,, +jinja2/__pycache__/tests.cpython-39.pyc,, +jinja2/__pycache__/utils.cpython-39.pyc,, +jinja2/__pycache__/visitor.cpython-39.pyc,, +jinja2/_identifier.py,sha256=EdgGJKi7O1yvr4yFlvqPNEqV6M1qHyQr8Gt8GmVTKVM,1775 +jinja2/async_utils.py,sha256=bY2nCUfBA_4FSnNUsIsJgljBq3hACr6fzLi7LiyMTn8,1751 +jinja2/bccache.py,sha256=smAvSDgDSvXdvJzCN_9s0XfkVpQEu8be-QwgeMlrwiM,12677 +jinja2/compiler.py,sha256=qq0Fo9EpDAEwHPLAs3sAP7dindUvDrFrbx4AcB8xV5M,72046 +jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 +jinja2/debug.py,sha256=uBmrsiwjYH5l14R9STn5mydOOyriBYol5lDGvEqAb3A,9238 +jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 +jinja2/environment.py,sha256=T6U4be9mY1CUXXin_EQFwpvpFqCiryweGqzXGRYIoSA,61573 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=44SjDjeYkkxQTpmC2BetOTxEFMgQ42p2dfSwXmPFcSo,32122 +jinja2/filters.py,sha256=LslRsJd0JVFBHtdfU_WraM1eQitotciwawiW-seR42U,52577 +jinja2/idtracking.py,sha256=KdFVohVNK-baOwt_INPMco19D7AfLDEN8i3_JoiYnGQ,10713 +jinja2/lexer.py,sha256=D5qOKB3KnRqK9gPAZFQvRguomYsQok5-14TKiWTN8Jw,29923 +jinja2/loaders.py,sha256=ePpWB0xDrILgLVqNFcxqqSbPizsI0T-JlkNEUFqq9fo,22350 +jinja2/meta.py,sha256=GNPEvifmSaU3CMxlbheBOZjeZ277HThOPUTf1RkppKQ,4396 +jinja2/nativetypes.py,sha256=62hvvsAxAj0YaxylOHoREYVogJ5JqOlJISgGY3OKd_o,3675 +jinja2/nodes.py,sha256=LHF97fu6GW4r2Z9UaOX92MOT1wZpdS9Nx4N-5Fp5ti8,34509 +jinja2/optimizer.py,sha256=tHkMwXxfZkbfA1KmLcqmBMSaz7RLIvvItrJcPoXTyD8,1650 +jinja2/parser.py,sha256=kHnU8v92GwMYkfr0MVakWv8UlSf_kJPx8LUsgQMof70,39767 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=bSWdawLjReKpKHhF3-96OIuWYpUy1yxFJCN3jBYyoXc,35013 +jinja2/sandbox.py,sha256=-8zxR6TO9kUkciAVFsIKu8Oq-C7PTeYEdZ5TtA55-gw,14600 +jinja2/tests.py,sha256=Am5Z6Lmfr2XaH_npIfJJ8MdXtWsbLjMULZJulTAj30E,5905 +jinja2/utils.py,sha256=0wGkxDbxlW10y0ac4-kEiy1Bn0AsWXqz8uomK9Ugy1Q,26961 +jinja2/visitor.py,sha256=ZmeLuTj66ic35-uFH-1m0EKXiw4ObDDb_WuE6h5vPFg,3572 diff --git a/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/WHEEL b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/WHEEL new file mode 100644 index 0000000..385faab --- /dev/null +++ b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.36.2) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/entry_points.txt b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/entry_points.txt new file mode 100644 index 0000000..3619483 --- /dev/null +++ b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[babel.extractors] +jinja2 = jinja2.ext:babel_extract [i18n] + diff --git a/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/top_level.txt b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/top_level.txt new file mode 100644 index 0000000..7f7afbf --- /dev/null +++ b/venv/lib/python3.9/site-packages/Jinja2-3.0.1.dist-info/top_level.txt @@ -0,0 +1 @@ +jinja2 diff --git a/venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/INSTALLER b/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/INSTALLER similarity index 100% rename from venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/INSTALLER rename to venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/INSTALLER diff --git a/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/LICENSE.rst b/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2010 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/METADATA b/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/METADATA new file mode 100644 index 0000000..ef44e2b --- /dev/null +++ b/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/METADATA @@ -0,0 +1,100 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 2.0.1 +Summary: Safely add untrusted strings to HTML/XML markup. +Home-page: https://palletsprojects.com/p/markupsafe/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://markupsafe.palletsprojects.com/ +Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/markupsafe/ +Project-URL: Issue Tracker, https://github.com/pallets/markupsafe/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Python: >=3.6 +Description-Content-Type: text/x-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/quickstart/ + + +Examples +-------- + +.. code-block:: pycon + + >>> from markupsafe import Markup, escape + + >>> # escape replaces special characters and wraps in Markup + >>> escape("") + Markup('<script>alert(document.cookie);</script>') + + >>> # wrap in Markup to mark text "safe" and prevent escaping + >>> Markup("Hello") + Markup('hello') + + >>> escape(Markup("Hello")) + Markup('hello') + + >>> # Markup is a str subclass + >>> # methods and operators escape their arguments + >>> template = Markup("Hello {name}") + >>> template.format(name='"World"') + Markup('Hello "World"') + + +Donate +------ + +The Pallets organization develops and supports MarkupSafe and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +`please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://markupsafe.palletsprojects.com/ +- Changes: https://markupsafe.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/MarkupSafe/ +- Source Code: https://github.com/pallets/markupsafe/ +- Issue Tracker: https://github.com/pallets/markupsafe/issues/ +- Website: https://palletsprojects.com/p/markupsafe/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/RECORD b/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/RECORD new file mode 100644 index 0000000..6fba495 --- /dev/null +++ b/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/RECORD @@ -0,0 +1,14 @@ +MarkupSafe-2.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-2.0.1.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +MarkupSafe-2.0.1.dist-info/METADATA,sha256=FmPpxBdaqCCjF-XKqoxeEzqAzhetQnrkkSsd3V3X-Jc,3211 +MarkupSafe-2.0.1.dist-info/RECORD,, +MarkupSafe-2.0.1.dist-info/WHEEL,sha256=C-sg6l2ppbqlkU_0fUt0o5fTSvsM-h9TfVKAh4ryMfI,111 +MarkupSafe-2.0.1.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=9Tez4UIlI7J6_sQcUFK1dKniT_b_8YefpGIyYJ3Sr2Q,8923 +markupsafe/__pycache__/__init__.cpython-39.pyc,, +markupsafe/__pycache__/_native.cpython-39.pyc,, +markupsafe/_native.py,sha256=GTKEV-bWgZuSjklhMHOYRHU9k0DMewTf5mVEZfkbuns,1986 +markupsafe/_speedups.c,sha256=CDDtwaV21D2nYtypnMQzxvvpZpcTvIs8OZ6KDa1g4t0,7400 +markupsafe/_speedups.cpython-39-x86_64-linux-gnu.so,sha256=eGr-sqbWsXEBzb2iypAevZQXZFzkverTnd_GX5lvgnM,53224 +markupsafe/_speedups.pyi,sha256=vfMCsOgbAXRNLUXkyuyonG8uEWKYU4PDqNuMaDELAYw,229 +markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/WHEEL b/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/WHEEL new file mode 100644 index 0000000..a98f911 --- /dev/null +++ b/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.36.2) +Root-Is-Purelib: false +Tag: cp39-cp39-manylinux2010_x86_64 + diff --git a/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/top_level.txt b/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/venv/lib/python3.9/site-packages/MarkupSafe-2.0.1.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/venv/lib/python3.8/site-packages/pip-20.0.2.dist-info/top_level.txt b/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/INSTALLER similarity index 100% rename from venv/lib/python3.8/site-packages/pip-20.0.2.dist-info/top_level.txt rename to venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/INSTALLER diff --git a/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/LICENSE.rst b/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/LICENSE.rst new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.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/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/METADATA b/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/METADATA new file mode 100644 index 0000000..f991d5a --- /dev/null +++ b/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/METADATA @@ -0,0 +1,128 @@ +Metadata-Version: 2.1 +Name: Werkzeug +Version: 2.0.1 +Summary: The comprehensive WSGI web application library. +Home-page: https://palletsprojects.com/p/werkzeug/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://werkzeug.palletsprojects.com/ +Project-URL: Changes, https://werkzeug.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/werkzeug/ +Project-URL: Issue Tracker, https://github.com/pallets/werkzeug/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +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 :: Internet :: WWW/HTTP :: WSGI +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks +Requires-Python: >=3.6 +Description-Content-Type: text/x-rst +Requires-Dist: dataclasses ; python_version < "3.7" +Provides-Extra: watchdog +Requires-Dist: watchdog ; extra == 'watchdog' + +Werkzeug +======== + +*werkzeug* German noun: "tool". Etymology: *werk* ("work"), *zeug* ("stuff") + +Werkzeug is a comprehensive `WSGI`_ web application library. It began as +a simple collection of various utilities for WSGI applications and has +become one of the most advanced WSGI utility libraries. + +It includes: + +- An interactive debugger that allows inspecting stack traces and + source code in the browser with an interactive interpreter for any + frame in the stack. +- A full-featured request object with objects to interact with + headers, query args, form data, files, and cookies. +- A response object that can wrap other WSGI applications and handle + streaming data. +- A routing system for matching URLs to endpoints and generating URLs + for endpoints, with an extensible system for capturing variables + from URLs. +- HTTP utilities to handle entity tags, cache control, dates, user + agents, cookies, files, and more. +- A threaded WSGI server for use while developing applications + locally. +- A test client for simulating HTTP requests during testing without + requiring running a server. + +Werkzeug doesn't enforce any dependencies. It is up to the developer to +choose a template engine, database adapter, and even how to handle +requests. It can be used to build all sorts of end user applications +such as blogs, wikis, or bulletin boards. + +`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while +providing more structure and patterns for defining powerful +applications. + +.. _WSGI: https://wsgi.readthedocs.io/en/latest/ +.. _Flask: https://www.palletsprojects.com/p/flask/ + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U Werkzeug + +.. _pip: https://pip.pypa.io/en/stable/quickstart/ + + +A Simple Example +---------------- + +.. code-block:: python + + from werkzeug.wrappers import Request, Response + + @Request.application + def application(request): + return Response('Hello, World!') + + if __name__ == '__main__': + from werkzeug.serving import run_simple + run_simple('localhost', 4000, application) + + +Donate +------ + +The Pallets organization develops and supports Werkzeug and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +`please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://werkzeug.palletsprojects.com/ +- Changes: https://werkzeug.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/Werkzeug/ +- Source Code: https://github.com/pallets/werkzeug/ +- Issue Tracker: https://github.com/pallets/werkzeug/issues/ +- Website: https://palletsprojects.com/p/werkzeug/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/RECORD b/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/RECORD new file mode 100644 index 0000000..960fd52 --- /dev/null +++ b/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/RECORD @@ -0,0 +1,111 @@ +Werkzeug-2.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Werkzeug-2.0.1.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +Werkzeug-2.0.1.dist-info/METADATA,sha256=8-W33EMnGqnCCi-d8Dv63IQQuyELRIsXhwOJNXbNgL0,4421 +Werkzeug-2.0.1.dist-info/RECORD,, +Werkzeug-2.0.1.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92 +Werkzeug-2.0.1.dist-info/top_level.txt,sha256=QRyj2VjwJoQkrwjwFIOlB8Xg3r9un0NtqVHQF-15xaw,9 +werkzeug/__init__.py,sha256=_CCsfdeqNllFNRJx8cvqYrwBsQQQXJaMmnk2sAZnDng,188 +werkzeug/__pycache__/__init__.cpython-39.pyc,, +werkzeug/__pycache__/_internal.cpython-39.pyc,, +werkzeug/__pycache__/_reloader.cpython-39.pyc,, +werkzeug/__pycache__/datastructures.cpython-39.pyc,, +werkzeug/__pycache__/exceptions.cpython-39.pyc,, +werkzeug/__pycache__/filesystem.cpython-39.pyc,, +werkzeug/__pycache__/formparser.cpython-39.pyc,, +werkzeug/__pycache__/http.cpython-39.pyc,, +werkzeug/__pycache__/local.cpython-39.pyc,, +werkzeug/__pycache__/routing.cpython-39.pyc,, +werkzeug/__pycache__/security.cpython-39.pyc,, +werkzeug/__pycache__/serving.cpython-39.pyc,, +werkzeug/__pycache__/test.cpython-39.pyc,, +werkzeug/__pycache__/testapp.cpython-39.pyc,, +werkzeug/__pycache__/urls.cpython-39.pyc,, +werkzeug/__pycache__/user_agent.cpython-39.pyc,, +werkzeug/__pycache__/useragents.cpython-39.pyc,, +werkzeug/__pycache__/utils.cpython-39.pyc,, +werkzeug/__pycache__/wsgi.cpython-39.pyc,, +werkzeug/_internal.py,sha256=_QKkvdaG4pDFwK68c0EpPzYJGe9Y7toRAT1cBbC-CxU,18572 +werkzeug/_reloader.py,sha256=B1hEfgsUOz2IginBQM5Zak_eaIF7gr3GS5-0x2OHvAE,13950 +werkzeug/datastructures.py,sha256=KahVPSLOapbNbKh1ppr9K8_DgWJv1EGgA9DhTEGMHcg,97886 +werkzeug/datastructures.pyi,sha256=5DTPF8P8Zvi458eK27Qcj7eNUlLM_AC0jBNkj6uQpds,33774 +werkzeug/debug/__init__.py,sha256=CUFrPEYAaotHRkmjOieqd3EasXDii2JVC1HdmEzMwqM,17924 +werkzeug/debug/__pycache__/__init__.cpython-39.pyc,, +werkzeug/debug/__pycache__/console.cpython-39.pyc,, +werkzeug/debug/__pycache__/repr.cpython-39.pyc,, +werkzeug/debug/__pycache__/tbtools.cpython-39.pyc,, +werkzeug/debug/console.py,sha256=E1nBMEvFkX673ShQjPtVY-byYatfX9MN-dBMjRI8a8E,5897 +werkzeug/debug/repr.py,sha256=QCSHENKsChEZDCIApkVi_UNjhJ77v8BMXK1OfxO189M,9483 +werkzeug/debug/shared/FONT_LICENSE,sha256=LwAVEI1oYnvXiNMT9SnCH_TaLCxCpeHziDrMg0gPkAI,4673 +werkzeug/debug/shared/ICON_LICENSE.md,sha256=DhA6Y1gUl5Jwfg0NFN9Rj4VWITt8tUx0IvdGf0ux9-s,222 +werkzeug/debug/shared/console.png,sha256=bxax6RXXlvOij_KeqvSNX0ojJf83YbnZ7my-3Gx9w2A,507 +werkzeug/debug/shared/debugger.js,sha256=dYbUmFmb3YZb5YpWpYPOQArdrN7NPeY0ODawL7ihzDI,10524 +werkzeug/debug/shared/less.png,sha256=-4-kNRaXJSONVLahrQKUxMwXGm9R4OnZ9SxDGpHlIR4,191 +werkzeug/debug/shared/more.png,sha256=GngN7CioHQoV58rH6ojnkYi8c_qED2Aka5FO5UXrReY,200 +werkzeug/debug/shared/source.png,sha256=RoGcBTE4CyCB85GBuDGTFlAnUqxwTBiIfDqW15EpnUQ,818 +werkzeug/debug/shared/style.css,sha256=vyp1RnB227Fuw8LIyM5C-bBCBQN5hvZSCApY2oeJ9ik,6705 +werkzeug/debug/shared/ubuntu.ttf,sha256=1eaHFyepmy4FyDvjLVzpITrGEBu_CZYY94jE0nED1c0,70220 +werkzeug/debug/tbtools.py,sha256=TfReusPbM3yjm3xvOFkH45V7-5JnNqB9x1EQPnVC6Xo,19189 +werkzeug/exceptions.py,sha256=CUwx0pBiNbk4f9cON17ekgKnmLi6HIVFjUmYZc2x0wM,28681 +werkzeug/filesystem.py,sha256=JS2Dv2QF98WILxY4_thHl-WMcUcwluF_4igkDPaP1l4,1956 +werkzeug/formparser.py,sha256=GIKfzuQ_khuBXnf3N7_LzOEruYwNc3m4bI02BgtT5jg,17385 +werkzeug/http.py,sha256=oUCXFFMnkOQ-cHbUY_aiqitshcrSzNDq3fEMf1VI_yk,45141 +werkzeug/local.py,sha256=WsR6H-2XOtPigpimjORbLsS3h9WI0lCdZjGI2LHDDxA,22733 +werkzeug/middleware/__init__.py,sha256=qfqgdT5npwG9ses3-FXQJf3aB95JYP1zchetH_T3PUw,500 +werkzeug/middleware/__pycache__/__init__.cpython-39.pyc,, +werkzeug/middleware/__pycache__/dispatcher.cpython-39.pyc,, +werkzeug/middleware/__pycache__/http_proxy.cpython-39.pyc,, +werkzeug/middleware/__pycache__/lint.cpython-39.pyc,, +werkzeug/middleware/__pycache__/profiler.cpython-39.pyc,, +werkzeug/middleware/__pycache__/proxy_fix.cpython-39.pyc,, +werkzeug/middleware/__pycache__/shared_data.cpython-39.pyc,, +werkzeug/middleware/dispatcher.py,sha256=Fh_w-KyWnTSYF-Lfv5dimQ7THSS7afPAZMmvc4zF1gg,2580 +werkzeug/middleware/http_proxy.py,sha256=HE8VyhS7CR-E1O6_9b68huv8FLgGGR1DLYqkS3Xcp3Q,7558 +werkzeug/middleware/lint.py,sha256=yMzMdm4xI2_N-Wv2j1yoaVI3ltHOYS6yZyA-wUv1sKw,13962 +werkzeug/middleware/profiler.py,sha256=G2JieUMv4QPamtCY6ibIK7P-piPRdPybav7bm2MSFvs,4898 +werkzeug/middleware/proxy_fix.py,sha256=uRgQ3dEvFV8JxUqajHYYYOPEeA_BFqaa51Yp8VW0uzA,6849 +werkzeug/middleware/shared_data.py,sha256=eOCGr-i6BCexDfL7xdPRWMwPJPgp0NE2B416Gl67Q78,10959 +werkzeug/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +werkzeug/routing.py,sha256=FDRtvCfaZSmXnQ0cUYxowb3P0y0dxlUlMSUmerY5sb0,84147 +werkzeug/sansio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +werkzeug/sansio/__pycache__/__init__.cpython-39.pyc,, +werkzeug/sansio/__pycache__/multipart.cpython-39.pyc,, +werkzeug/sansio/__pycache__/request.cpython-39.pyc,, +werkzeug/sansio/__pycache__/response.cpython-39.pyc,, +werkzeug/sansio/__pycache__/utils.cpython-39.pyc,, +werkzeug/sansio/multipart.py,sha256=bJMCNC2f5xyAaylahNViJ0JqmV4ThLRbDVGVzKwcqrQ,8751 +werkzeug/sansio/request.py,sha256=aA9rABkWiG4MhYMByanst2NXkEclsq8SIxhb0LQf0e0,20228 +werkzeug/sansio/response.py,sha256=HSG6t-tyPZd3awzWqr7qL9IV4HYAvDgON1c0YPU2RXw,24117 +werkzeug/sansio/utils.py,sha256=V5v-UUnX8pm4RehP9Tt_NiUSOJGJGUvKjlW0eOIQldM,4164 +werkzeug/security.py,sha256=gPDRuCjkjWrcqj99tBMq8_nHFZLFQjgoW5Ga5XIw9jo,8158 +werkzeug/serving.py,sha256=_RG2dCclOQcdjJ2NE8tzCRybGePlwcs8kTypiWRP2gY,38030 +werkzeug/test.py,sha256=EJXJy-b_JriHrlfs5VNCkwbki8Kn_xUDkOYOCx_6Q7Q,48096 +werkzeug/testapp.py,sha256=f48prWSGJhbSrvYb8e1fnAah4BkrLb0enHSdChgsjBY,9471 +werkzeug/urls.py,sha256=3o_aUcr5Ou13XihSU6VvX6RHMhoWkKpXuCCia9SSAb8,41021 +werkzeug/user_agent.py,sha256=WclZhpvgLurMF45hsioSbS75H1Zb4iMQGKN3_yZ2oKo,1420 +werkzeug/useragents.py,sha256=G8tmv_6vxJaPrLQH3eODNgIYe0_V6KETROQlJI-WxDE,7264 +werkzeug/utils.py,sha256=WrU-LbwemyGd8zBHBgQyLaIxing4QLEChiP0qnzr2sc,36771 +werkzeug/wrappers/__init__.py,sha256=-s75nPbyXHzU_rwmLPDhoMuGbEUk0jZT_n0ZQAOFGf8,654 +werkzeug/wrappers/__pycache__/__init__.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/accept.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/auth.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/base_request.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/base_response.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/common_descriptors.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/cors.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/etag.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/json.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/request.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/response.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/user_agent.cpython-39.pyc,, +werkzeug/wrappers/accept.py,sha256=_oZtAQkahvsrPRkNj2fieg7_St9P0NFC3SgZbJKS6xU,429 +werkzeug/wrappers/auth.py,sha256=rZPCzGxHk9R55PRkmS90kRywUVjjuMWzCGtH68qCq8U,856 +werkzeug/wrappers/base_request.py,sha256=saz9RyNQkvI_XLPYVm29KijNHmD1YzgxDqa0qHTbgss,1174 +werkzeug/wrappers/base_response.py,sha256=q_-TaYywT5G4zA-DWDRDJhJSat2_4O7gOPob6ye4_9A,1186 +werkzeug/wrappers/common_descriptors.py,sha256=v_kWLH3mvCiSRVJ1FNw7nO3w2UJfzY57UKKB5J4zCvE,898 +werkzeug/wrappers/cors.py,sha256=c5UndlZsZvYkbPrp6Gj5iSXxw_VOJDJHskO6-jRmNyQ,846 +werkzeug/wrappers/etag.py,sha256=XHWQQs7Mdd1oWezgBIsl-bYe8ydKkRZVil2Qd01D0Mo,846 +werkzeug/wrappers/json.py,sha256=HM1btPseGeXca0vnwQN_MvZl6h-qNsFY5YBKXKXFwus,410 +werkzeug/wrappers/request.py,sha256=0zAkCUwJbUBzioGy2UKxE6XpuXPAZbEhhML4WErzeBo,24818 +werkzeug/wrappers/response.py,sha256=95hXIysZTeNC0bqhvGB2fLBRKxedR_cgI5szZZWfyzw,35177 +werkzeug/wrappers/user_agent.py,sha256=Wl1-A0-1r8o7cHIZQTB55O4Ged6LpCKENaQDlOY5pXA,435 +werkzeug/wsgi.py,sha256=7psV3SHLtCzk1KSuGmIK5uP2QTDXyfCCDclyqCmIUO4,33715 diff --git a/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/WHEEL b/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/WHEEL new file mode 100644 index 0000000..385faab --- /dev/null +++ b/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.36.2) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/top_level.txt b/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/top_level.txt new file mode 100644 index 0000000..6fe8da8 --- /dev/null +++ b/venv/lib/python3.9/site-packages/Werkzeug-2.0.1.dist-info/top_level.txt @@ -0,0 +1 @@ +werkzeug diff --git a/venv/lib/python3.9/site-packages/__pycache__/easy_install.cpython-39.pyc b/venv/lib/python3.9/site-packages/__pycache__/easy_install.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52cb6fd0cf5e9260dceb93a65c8417fb483b8228 GIT binary patch literal 328 zcmYj~KTE|h6vdOaY7yTj5VW|x!Det0L>&}yd5CUZu6fPXgyv6a(n1|v{4{>0u1;>w zPNwSc4%~A%aQPj+SnQIhi}3aM8uMc=n@VE2jOUM{2~rWHf;LHaAQF-4#H3Y938rs^ z5|KTS<<`soeQ%2(vAE`bytO`Xt&7?j!>yQd0K=69_>4HRq*FH6)iRrQ0EDXn<`>Hi z0#t_{L*EAHv@ibwB}OQyKWdjo#yjb@WBl4TFzF1kpo|N0Y?a_%;=r!ZH^H^+Mg`fg z*`4dclhewv0qwxFTC;Wx(%F;plzA2KxaD=jpV70;xw0Ln{LDDfYdoiM)6c_MlG8o< E18e49$p8QV literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/INSTALLER b/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/LICENSE.rst b/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/LICENSE.rst new file mode 100644 index 0000000..d12a849 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2014 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/METADATA b/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/METADATA new file mode 100644 index 0000000..7be0832 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/METADATA @@ -0,0 +1,110 @@ +Metadata-Version: 2.1 +Name: click +Version: 8.0.1 +Summary: Composable command line interface toolkit +Home-page: https://palletsprojects.com/p/click/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://click.palletsprojects.com/ +Project-URL: Changes, https://click.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/click/ +Project-URL: Issue Tracker, https://github.com/pallets/click/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Requires-Python: >=3.6 +Description-Content-Type: text/x-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/quickstart/ + + +A Simple Example +---------------- + +.. code-block:: python + + import click + + @click.command() + @click.option("--count", default=1, help="Number of greetings.") + @click.option("--name", prompt="Your name", help="The person to greet.") + def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo(f"Hello, {name}!") + + if __name__ == '__main__': + hello() + +.. code-block:: text + + $ python hello.py --count=3 + Your name: Click + Hello, Click! + Hello, Click! + Hello, Click! + + +Donate +------ + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://click.palletsprojects.com/ +- Changes: https://click.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/click/ +- Source Code: https://github.com/pallets/click +- Issue Tracker: https://github.com/pallets/click/issues +- Website: https://palletsprojects.com/p/click +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/RECORD b/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/RECORD new file mode 100644 index 0000000..0fa14e7 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/RECORD @@ -0,0 +1,41 @@ +click-8.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.0.1.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click-8.0.1.dist-info/METADATA,sha256=Q_8tjC_Ps-9OmIDcovMWvqzrNlmYNwJ7yZxyeJ-SIsk,3216 +click-8.0.1.dist-info/RECORD,, +click-8.0.1.dist-info/WHEEL,sha256=OqRkF0eY5GHssMorFjlbTIq072vpHpF60fIQA6lS9xA,92 +click-8.0.1.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click/__init__.py,sha256=TweMqq3qEdmxSl3M_O0H1crtKtd7_oS7PDd0WlLote0,3243 +click/__pycache__/__init__.cpython-39.pyc,, +click/__pycache__/_compat.cpython-39.pyc,, +click/__pycache__/_termui_impl.cpython-39.pyc,, +click/__pycache__/_textwrap.cpython-39.pyc,, +click/__pycache__/_unicodefun.cpython-39.pyc,, +click/__pycache__/_winconsole.cpython-39.pyc,, +click/__pycache__/core.cpython-39.pyc,, +click/__pycache__/decorators.cpython-39.pyc,, +click/__pycache__/exceptions.cpython-39.pyc,, +click/__pycache__/formatting.cpython-39.pyc,, +click/__pycache__/globals.cpython-39.pyc,, +click/__pycache__/parser.cpython-39.pyc,, +click/__pycache__/shell_completion.cpython-39.pyc,, +click/__pycache__/termui.cpython-39.pyc,, +click/__pycache__/testing.cpython-39.pyc,, +click/__pycache__/types.cpython-39.pyc,, +click/__pycache__/utils.cpython-39.pyc,, +click/_compat.py,sha256=P15KQumAZC2F2MFe_JSRbvVOJcNosQfMDrdZq0ReCLM,18814 +click/_termui_impl.py,sha256=3IBc-wR8art7cOIN3y4vQ3ftyCs4GNLMjDcrSalUD9c,23423 +click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 +click/_unicodefun.py,sha256=JKSh1oSwG_zbjAu4TBCa9tQde2P9FiYcf4MBfy5NdT8,3201 +click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 +click/core.py,sha256=xYDxID7ShkgY2Lbw7vKOMjP5ImT1NLCTqMJphUicAQ0,111335 +click/decorators.py,sha256=u_Ehdo3PA2nzCoud9z6fGhxwtMI8vVNG_SL8Bl9lsnY,14871 +click/exceptions.py,sha256=7gDaLGuFZBeCNwY9ERMsF2-Z3R9Fvq09Zc6IZSKjseo,9167 +click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 +click/globals.py,sha256=9pcmaNfGS1bJV5DoFYhfv51BPeHP8dWaya7rP3kcrY4,1973 +click/parser.py,sha256=x5DbnBV9O8kXiMdJAdtpdTO2eRUXw2ab5PRMLxo0po4,19043 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=F0CHHFOP4ulDsYoqTMm9FXih_OVKsg3mzD-XBzMN79c,17881 +click/termui.py,sha256=MJNkEntRiNZvwa0z9SVK0d6X9BvUcFhvxKky5M-kBGY,28809 +click/testing.py,sha256=kLR5Qcny1OlgxaGB3gweTr0gQe1yVlmgQRn2esA2Fz4,16020 +click/types.py,sha256=ngn3qOaHcDvyeMF2UT5QJNNpJAAVrA9BRj4t8x1xOZM,35375 +click/utils.py,sha256=q7xUTlebAnIENo2Uv-REArW_erqGFm_8yMW241mMjzQ,18752 diff --git a/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/WHEEL b/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/WHEEL new file mode 100644 index 0000000..385faab --- /dev/null +++ b/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.36.2) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/top_level.txt b/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click-8.0.1.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/venv/lib/python3.9/site-packages/click/__init__.py b/venv/lib/python3.9/site-packages/click/__init__.py new file mode 100644 index 0000000..9e0afb2 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/__init__.py @@ -0,0 +1,75 @@ +""" +Click is a simple Python module inspired by the stdlib optparse to make +writing command line scripts fun. Unlike other modules, it's based +around a simple API that does not come with too much magic and is +composable. +""" +from .core import Argument as Argument +from .core import BaseCommand as BaseCommand +from .core import Command as Command +from .core import CommandCollection as CommandCollection +from .core import Context as Context +from .core import Group as Group +from .core import MultiCommand as MultiCommand +from .core import Option as Option +from .core import Parameter as Parameter +from .decorators import argument as argument +from .decorators import command as command +from .decorators import confirmation_option as confirmation_option +from .decorators import group as group +from .decorators import help_option as help_option +from .decorators import 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 get_terminal_size as get_terminal_size +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_os_args as get_os_args +from .utils import get_text_stream as get_text_stream +from .utils import open_file as open_file + +__version__ = "8.0.1" diff --git a/venv/lib/python3.9/site-packages/click/__pycache__/__init__.cpython-39.pyc b/venv/lib/python3.9/site-packages/click/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ccd9fdac3ad29f238f54212f9d70a0b5cc5dacf GIT binary patch literal 2706 zcmd7U$yOUj6b4`cl8}U$2OBVU8;miN#9$1V!GIWy!*mR6?xs`fE~E-QovIcXKS5q4 zCvT)}Ryik&th36!R}9V@1Rwu=Rozw9eO2m4w72IH`14o%_s_rQ6Nx{l@#9Z3Hn#A; znQKWT+yo@tCb!vZ@|&T#iQIy2ffjZWorEMig-$_=okpi2&2B}vLMuCi&OnBpMQ0() z&Y^RVW4C#2ejf7dJh~m)+3n~K=wNrCJE4=^iSB|fb{D!Ey4l_69_V5BpnIX0-HYyn zK6W3vANtw-=m8jD4|vb~=kT2U3_S>g?C0nq7-A2ihhdmKgnj`p*u&@%7-7Fazl4|U z5%eo~#eRvlz+%7hUi+gk%C^vBFvfoEz46CkoIUEj^(SD0J?6dhCt;HP20aB+>~Zuo zOtasjXJCdsfu4m~_B(U|3hYUA5sK_7^c>8wr_u8;&z?aqzyf;~y$Fl!0{T6?XBW{+ zu*9D8KKRS9%$`TDzzTZ-y$Y-BMf6Ab$bOGrgEjUNdL7o;AJ7}H!Cpph!X|qK{Ruv? zSJ7Lr#r}xihHds5dIxsc>*x}c*c<3w*kx~ed;UJ`vp=B^;DEh_{tTbl+vr0$WbdHA zz!!E2{S*Ae-bEk55qb}f-Tm{#N$cz`u7-i-hi(m9Dln1K z(zVKWR$P^qiCs^XtuTrsp^dcS(DKE#%-w1gtDs^zq3?^pwLBHz$&OZ0Y^}JMN@r1F;!bmqKbXdcYj~B9ic8E)g*m6T@tRReOa%tVFxQff-x;3YY zi&vCm(Td9C@OTs&QTAjZ_h%D67bctPnQdLE`7(&nZ9BM7sd0taY<*()JxihINhele z&^R8%@*9mz9pJ@9i2QNQi`CP>^l5Z|cJ@qY;mcTRJS`)hR&8}2SL}7d;7Vy<&=?zw z*jOl4xu3nQD!u5bzn4mDN5UA}l}@Nd9Ma_J$ANi1hLhf3W`^5g`4>E^lYAR$_i4V4 z8>!8ISKcm%nr^UbN4O7_x-_C9v9AOB8n^e*lgFMPZ?l89&)zpjKHN%nUwLv*YrfE~ zV`U8PiXVsMPr`Hj;2z7CL3 zL@jWt*qMq%&Ct=dNQV_IjVU+Iz@{JZHZimeooeDck0+`H4@~Zyo*v<`bg3FDhYn_T zMJz9rPfk+dXypFU>GlO8x9^1_{wf0gELsjvs55gIJa#oU+{InQ!_P!a*O)%P_%wwBJ)Jg}K7~$>d4B)wbQxvF&;i_p{XW z0@wKNPUs{>iXu(XN|B++QqZ3PkbC?R7~Mv__$NU^w^MXbbW(ItbW`+D^iuRu^kdX> z@?ozUJwUzBD4tUcQVdZHQ@o%Up?HY_xki=f8K+-SuZ4lz#0$&9Gx{~P(h=`KJ&FxT z)0V0!J%$bahGLxJEyV=IJBmq)DT--|8H!no0!0y{o{I4kHhPXa<|!5^7Af9SEKz)* zSf*H^Sf%(#u|}~@v4K%f)nbL0yGb3ND7GlJDRwAI6uTJpHrsx9TG+oO^f4Wv_(v40 z_!ut6%Ew3fU8G!Ls`93|E6sHrM#TesJlD#_GkmOEg`NtFH!`>>;ya@l@rz}#uv#=K vma~y?uJNmAiVnSkingr+729?px~pf_8*d+ck>cNWzhWfQ`KJHDzvh1d(4)__ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/click/__pycache__/_compat.cpython-39.pyc b/venv/lib/python3.9/site-packages/click/__pycache__/_compat.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..88c9cc541928c3de9b44941a46b360ad7d89c36e GIT binary patch literal 16055 zcmc(Gdu&|SncscQgTvv7q9|ID8EdR4w&=B}m*ZCy+q6X5ifu{}X)B)Cxf;&7BMmj2 zq0haf#Mxms4b@sHn$%siMbWB&2()PRM+@||eV{0cV*5bR?gESMqP=~k4N!D}wrJ6R zQYW$d`+eumgF`CVZHjitd*+^V&pqe+zVp4#_nj$^jN~kQ{!8@VuYdcJW&Mbi{tutN zhAXV5EbCoMS<0?kCG%~UY^ggXN50*XE8kwplkZe1jc=!(S;>~NwiS5GLl1Jw-L^}^ z$-TF2H@~G)sO8tK(uhh2&T?VhYPM8{cMtZdtQy*O@NBg2jb9B$^H%d$gOR*d+OO== zSdd;mfNLDr!5cQqs&m*nYy}f4cisxz2al;?%z7v|tn&A5HKGc4z0wiYM9;@@9S9Di zZ|8e5nB)j*^nP0HS7Ucmr7r}BgGqJZzN5y~LA?0{o*%_n6KHu%9YRa-4NDzXNA6nc zNMJ8Nx#gCQq2+NkiI&MNr}Ra&D(_%y^@aPcdO{t=xX0B;J6enCNwj`R+6+dIAGTzc zW9o~T<*7ZM99Lh$lc(|IAjT#{PpPNTaza`Tqcqq}suTA;HKm@xvnhGjdD8iwRKJ8C z&#IH?@r=^wbF}+*r;nlW(O~k16HJoE=s~I<6{>R$0I{@ps5pH;t4^uY!0VS($ey?c z=}l^%xt~&J)j9NgRz*Lj-*f2qW%WGzo#bq?o-e2u0rPaX{*rnb^;6yYSJZjbPpdVw z?3|l3e--QTih30zo>A+M?D3kKL65WQ_9J_|t}dX*IXr(3{NgNsIe5P6fmRXT5}R?>DL;4Gvt=lQ0}VV<$Zi^)hIBqN#k z2Umr#9t6%Gf+N4Be9ZYOuzX%!2bN{Eg!%>a0A&Qric)B~h?emiGGm7`A5~KUAgZbx zcxyJ8RX0`bt`(dCE$2{MmfBg=-aze^)Xt&yW-uL`3Qnu~eYbQ8bA3(L%*^;WXH00Y z0*!MfI2)Xko^SPf;%*0?kfDTf$(s#O&t9;me))H)f#;{}c>lGaeCw@X<6^B6)tZg6 z-iXtcjT^UXjo3v|a^JXcA>Kc8<;v{*8<*y1{j2ZJFJ5|Qww1patOxbx>PpavPR08c zX0N_Cd(~gKJhyml=IU&0#bf2QsOjI<;!EoIZE%gKvKGE3ckD`O=5a ze6xJAHFL7`;X^x4>mXXwjS9i)|2U{zz!i?7h^zV08Evpsx@xJV`x@EwY*l3I&BXvy$@qa@#*zbH=8TLsi?NnjBakM)>JvX z8LXeW7=*W?=IW_8YSGQLrBhd$I;uA7wdSeyps{|cURye~x)I%MHqK4IbSkVx!O7Kf z1~D-vMKsND({B*85S;O{L>>80nzA5@$P| z;&h;OQ-^T@B&-BJo~rUvJ?PYL>srLRrVXvYe0D#)&*Bo=oyJWYhIGx+qmk9Nw(L#2 z4TFmMq_Q`i$Zq2~TAa4q_LTemG+4x&k25-0t(PmoBB)%b*BXJpv{tPK8kE%sF{YkC zG3CVjiQ`fbMqTXUL;ifTaiQJ}(RVSp6J5G|4V|4$?FqLOT?#5HL#lQFATP#?oE#;CRt>YJN29;Z3u~sdXi#KXuhGJ)>inXv<4lA|V zbexj!x%nv%lGIc|C5+ScX7kqCYV0-2D?vQ`w$x_1v{SZ$wabzT>b209VY(DO32;LK zZ#j-VX6J4FB<_K#P;(cm3?JZjuiC&v(!E2ql zDsmVWqnkl7k({C-ejl#YVxt)qtIf5BnilxyTdB3Edh$i!oB=bGqe$yKX4M52g!G|- zGHBt33}tQuF_gT>yFP*QVT!8O<>VGgl9M$xXT`{RFH-}=zM2_4DPea zQSSZB$5z!=o=V*vDGi||4IeF|ve3@CAS1OQSP!o>{4uCj%7YYneFRfr6*G_I*Ej{v z)MX=l={`6!xaT#DD|`_Jxh%4l9TL3lwNqQ}w&P(zd=HC|+On3@6u-7xb!%2T{pai- z*f#v%1xs^;sZ4A~u~#XFQJj6fMiqVOa-8?)YIoLF7mUWpBmxqr!Ziq4ob~-$qZau- zUiQMEUVS7I`b(Gs3V6u(EA?_1`o38nN}#5Uyn@TD%#ddnKF_(WCm$u-)16s0*QxSI z(IY>$@@?yZwGAP=W;MnjboRy*9ieMD5VQLEE)Fl&!Y4EVie!B#wRtt#P^*g4H+l+1;?{=g@W) zmr?Rg>*ymPFoR4vb8}N8TsbNU-;Z;?ztU7|b>8QF|D&~X-8|7xak>*I;_PK1N4X9w z80pwsYBq5@)7X%u)92WcfW#xo@>YU6=+j5HX?BstCcl3bSIC=e8Y}au<9MQGsbryQ ze>_?!q(v@v2`25$YkXOw=nAHd?bY!NF&6Px@QO%Vbol35V4+L7(#1pF5H;T2D)jHjYXu4RO35(%c<>s?^2g<%$ zyK{1FwMYd|-QNf*K^Q_bF{g|Z!mlV+YPzzv5=P|)o=)fF0l}j+hhZ!>tHq8D9Wf27CDr$R@b89Qdt2|cpH_QfhsnamV-(Z7Ms9o zBP^b1Ht-Ul##Ggyp#m*~RstQBYmMT1phHNLj0ISh*WlKm3zT~RPP#QUEl=jAT%$g^ zHorpC()sYdD=hQ~pvx@Zf@91YE3Jciuj} z?dqp8W(-C9rqg!XZXN7bj9rZc^K%p(jjkrNoe%F_Tw*9`vS=umZ5T#aexrXKeGKga zIEE3uBV!HN>|x(eOrP)H!V8Ia*E%!+P`492Cl5|>;=T0)MSv(#0u+^t0Sflp+HyA? z@!f3wROCExBM*dz72gK91pGm&ZEw?-JM(dh%ynie-Gkq#j;AqVoLa(Khq1>#SYScx zbw04GgJdQc4P3?y*aatRk2bhLtK!uuA=eP->*9o@^%mJK0aQLIP zo{roHUIZMrEMn9eWuFJo9osO8uoUC46q${y9ZR7+anFcvYJM@!cBDzu_RLLXH5J-k z=3yew3>W2n%j5kg%;qX~Hm67cVRI3vJ=DruD_tvaHn>8kusTtYCK`$rNi zPVuEcNT%Op&z&-$zlOH&;u0IOn_7luqk}Z-K(dQwUCvp=m^);k!!O4Z8R+oK1Sm@x zV42>AW8cR$^Bs!xJN5H%HVlGW+(peTf?E4 zY*(!=r%dd{DV=HO#q#ghbb6ci1g~bf}x-fM5BCF&u zO`esd(1fRNjbyb%bJAK~!zBxaeN-N-@>807nEIdQb7SskwvaFE6RVo2|2UKE2liH? z-L;}e!HpICJ6k~)Mb1`lV|Bu;LEBD)A4PUiK6K_qV6l71)v#kU2GdBVV3mld7=x=j zQ6e_jDPq60B(AaSkpq37xDg}^7|C|&J=|9)h@H<4p}d0DR)H=lK^CSt4>7VgzGeV! zjma~|JcCGK%OuZV>o66Cs}C(GCa5I+7RD6;19Lf=eyL%ecX_u{cy?f6rm5aU? zyM4u|&~`uc=I7$H+59hJ2Txk|$;Sy+DL7E0T%*`U*Fo$KAPUk@J6GwiqH{>2Yo&59 zD|v4WrRLu5{|#Q6776%}l6&E!OMEb}Ogj-V3-#;hw;PcU(YgZ>TBWXCr$LFt3MTvV zQIMb7*=wDf>Fl}TTCUW>O0!X|-B{Cb@DO{b!N2Q|JIpLxxO6GmhwDj<3Ql_xUuH>c ziA6Q6?N^;Cs4{Gq|BJ;lm!T4m84tTeL2^pz%7n_(!V-_bs($Bra>uu4;F>>2yl ziQZsHN5dM*!PPIgusEM{#T?gjvmX2f$7AXBMPGlSZ=(NHDp^VT!Qj3g-~z5JmWTug z$A|Y>T(Ve3Bbr!r1iyibLSoU*JOVx(0ImpUF$Rcs0uohY!@xYdSki1acc5w@d=fg@ zcxzzEzQ0d3_i$ZwjGFJ8W`eW+BIs~{4mx6gXf1$FodfsKk$HYE=okpkJQ5vl;3#X| z4|?|Y?N6XWW3=pm!|63JIdCMx0&Lme#YTH)H{Y1sR{bx9Y@-9U0pJ% zaW0heeY)B1{GwjQOV~a<&Jc``yrpX1rb%vuO;{jf8%;u@iH;)L5BniH&ej3c3LGl2 zO5oV{x_G$^0C=|kWxTXwNAU}x@sMb&2pW2W;N)3^EGW9V#bN-&ef=PUll)yUZsM)~ zdob!Yh6B&{;JZzzesA!BH*W5NkM7R|Ma90x+Xgao+u(9c~ z@01;T&DEd*I{XT;{|<}p)4?SgF)8p`)8{)MkpRSi3Cx_M@8T}DwPb#gfJY8EOG+@# zKQL~bE=SFkTE*BLZX!A#@&qM{+!r2$SSkA+LROpbTon9ny%brJ{X+2lZdRo(!iPc9 z?_xWppNkMSQRynl2Cot%%X}ZXG1l?)YUFmGGRWBf)C=#>GrGqpue;@`EZoLAqA z(ke%*p@yaYr%=yJeFSw||3%abQs1YndS)}N_zgd*H5%dcmSkgxH?s)#F_4wt_;+T9 zt*p(g31LM;%Oki7uUjbhy>4v|wNsziI@=zKFoGIY`?lQ6XvNe055}ZCz){uycILsj z8pGXzKjZyb2R>k~^%Ukj*v_?wj8}(oE~@c{)6Q{&Y}s2|D)`85tZrG8#&W{8o@h069_rVf5RwW0LTn}HF z?smj61N(Mtm-QtKHK)Iea#8#h{vEHn&V-Lu;F)vB;e9zW_@J%B94$?AZBwo z{B-d$y2}p9%+`P=(JR=EUcY_)Bvphc5RSx=aRQ_kF?UqOE9D4VvfBh=qq+7pGCAcc zJf>;Eu=UitNa=7}dcBEEjJONeag;L!SfNt z5U2!2*~E3=nU-)GvV;EXm*!`#zTeu1M2OKJCuN#CSD7DVyWP_--l_c>)+lxw(bN}X zw~X}RI-Y474{@)=)EQ-!dyf%-S*l9pzqM{O;krS;HdkV&iF5*DcTt?dQ4rE4&RkwF zUDKESs~4|bMT39g>g>#7jE327TzFfy+p&lA)y>#jZo)ClsG62z5sJn+g&oRSn>oR3y;z9~`Ju~SvC9q2iBbIM5w z?2qtG5sBeG_Ww350rxVn1lUSVz@fla%apEXkGWayMn3n_=AcWK-#GcfoI}nTbJF&x z%OK$BXWWEM%DZq&WJ~S2`JZ`S;iq1@U{5+ZJMR?iaa;ct%vIrp{T~{V*Kmcj?47)= z9H&SHDaNI6JdTFLE2VLqBBfIIZIxD;yWW;v%Bq9G5c+howkaH@Na5XKWNw}02y9*< z`+#>$=5|DmyIQ3}GSUGx&U`MjK~od@F93vjSXGiw|0NXh2-mAi-o3Y5)L9pBg_9`u zNIfzc=}HjOnV*A;==fD+!*?uOfkETmJUF(4gG+$|C?_#y4<5~U<$!^gMEh@YG0mog zIY?w7$NSi>n}pn*9>aUkstE%03z!({SzQtmJHbT+F#aZ9 z)PEfXM2+;)f07N1bm+gqg1{r@Atd};Y#6}dZ=>yB5eLF&az&JY*8YB6%*d~z!wxT& z7`V6u13Jod`}WM*5IbG6YS7N=3%%Cdrq=<{y=7>M)#5)OG#!j>}KnET;ficBVq5sqe-2nTV4!bDP6+Nz?Spf#HldL&Y%d1*AWG^1( z#O&bvzx(KkO@}FaZfbNOKV~%eLriRvVca#w*;P$TjuSaY`9N~Kq)9JTrvDDBe~-oA zXVGH{xucpEJ@gxdi8ZKZ1cpZ4vCNoTaI>yF1zVTdQzQ#LyC2?nCCl(7lVFTDirh#l z2%?#l^RU1l=XTbXuyQh74;V2QIqX|&tJ3qoVqhcdw*Ga@v1=*1lOD%YE(POfRb<{Y zGotRM^$`UGCvlKV@0<^4eGc;Dr& z)2Jlz*k_W+6e8ivh*M$Lg53;$sc`})>*Nj^4D}8VdVPET=P-(yJ2^A?kJ&JQ#s2Un zeMP#c3FUuG=n0<%i=2gOhb8?dsF7(Ya@-16aCJXy?}E;CgoU)~7K3U$y$sM6&`9+x z{%;VEV-vrs1DvZxHlwpC#mN5@-3H+sllVqi-&pS+49#LPlVu=r{~2D24;t<=VGr4V zLMXx=3N(X$G+5Lx;R6&co~kCJ;yiG&^>Q|jCtEMHnXQ+kaBO{+kr*Tp?K;vsOeS*g zz3H`a^b+?xLF|0bj?xb@QF=Lh&tAq4Y_J_oE$6<6t?0*g)sb^x+0Ar2-A?&AoCQpg zXU})e0y-OidPiE7Vf1usX~FpS#hLkqOE`H2&Jo8uj5e?b;7Kew_jJufe~L>R@Rf1q zn7f3s4i7pE5gs?X_TjTAG`1EwEEti8rJ_DIK(cvPg2rxwnGl#?|66y04z2^ z&2wja?y|mtmrO?SZQONE$5NKyHsO$Fp!Dys%WtrtGSdHog~-`&@s3z%(s3W5XAdTW znB30cT#@Hw;jtFr2c(@sCJm35$2Zf?4iV!!U4=J}iU}7|(BybC;uc2Ra;abskKwCN z6YOWTC-`zFP*HeZAXKYEWq#Z7>dZ+vc4w?3}xT9sbxNPs)zw9_immi=D-l% zym7$MyZZqkq6fJ`;S!2_2#IY%8{PxDq75P55{R-lo=LPJPR=LV(41L&k!R=cIe5>8 zCPS>GPm|djAMDU%y_M3xjoHj$kT2ryp$lV3`O*KH?f-^FmopI`1r@H4YDe&Z&T=9$ z5{YI_#KdkrWqvbZB(al>=F2@Lz#15nm>apKNTZ=QFB8{h@_)-a(L0A8HSk-6O3b^P zb`I^+Kg25)TsuBp8DU4-?k>aj$z_jIdx&Sx*UKwQs{G0lrZJ~!{sV^ieNPbLr9EX{ zM(d3I`yN)p-+REVIjrgo3*t68zW~8k;zE*{H6}Vl7@_wgmr%}w!R5t2&x9v;^EfA# zT%P`e7-U}mA(ZHYR{Rj^ZT$s~?9`gF5yKBH0-Y@Eu}BK|HidT_}x!(F1VC>XW{*YvvCH$daCJWLs+(yo4InuH@^lex#%v+ zT))W4vln2=m>U!`5${9LseyE%MAq=jf;hud2MCtve}LY`Zx>~Jf>rU>ALreZEX1`x zjJtTmq{fpU5E<`uie27gagD_XEIwr6vshxm#WdMsW^zrELi28&1(Q-HtR+z{<{{$L zyA6Z@8_=QmkcZm`SH3-(=DwG$zKx7T#Ht zUunH#oDtEsMoIniVm-sfrekbTU~xrHoD+fR7#pM97b_dd-Z9L_g^_ALq~FTw!+%?uwaI5emG&5A*O3knzvJR`@i3rEqlA8X?CCduS(j+BPW@|$#2}{++&1$jd0$6ad zyFB+UNURri#$epE4I@p`I;kzD3)@YiOs0=aM$r)9G~XbXvEWPQy$) z^|VuWhLPib-+%8e79ccj7ua+E^FH^S|NWn>jE-gveEw_j{kOmHi*-$_r?IZ5H?7ih>ILtZ_Z0q4sAtgTS@j%NQA8R0 zp2X@-yl1JRI*Fbi^Tyvb^&iVgoGP92%$3tO1E&X&%~^IYlNV|~v)*7sc0S6MfW;>SC`o1I^-`R-~{wdL@1 z)mGhG^^gl{P2?Aw+6|UHH}LdoyB0T}ap#-vEzfJQDvK^n9k@Yl)pMJR?#uOB^_Hue zcN(W$zlpM1V^Mpz+ZeOH?zVkTxr^;amBUx+wP4+?`Po*zQbl>KfdRJ{RcR=<*+8dg z1~jPnZo~7Gr)IJbNd$96GfXXcLEzmD9-1gXexj_r#Y(##lv!H#1J!H?C{Mop)~jz` zXODg8QC{%;pzJlOO;u|wvAX70f?yrcNVDZN&`*1nRb;b(YOQjm;n$E$b0f-iuL0PO zhRe$vU%gxPT6`%~I9_$R8Jcf|RwH<1j)rEolNvqpmE&*f~D>mUA%BXbE~ zzlRs`3=psZ;(Y-G;ozI_l7|eSICCjH)A3(MN-`*kAbTY%C1|~53Y0!%ELwxU$VsWa zG7>}VoASs8vhNkth{^$7bIMSoK)}2j1Gg4%b_DCN;}jO&oPakU?H1urSN33ULu zeHexPCe=aY#=ZUCgyczzMC1d5lEdnVluQmvj;bf5x0-&K#}un&sU(GkiF#$htA`He@xny4S#RpF&~7P= zTVAaZ#l4mvChpV}R+H3T(AJG=0n6=w_5n!X`!c@%NuXud?iyvI>mW6|38YpxiPY|< zkUHHo(nL3dG}+A}O?5|FFDesIx(k$Q8~Rg0X4BZnb#o}oc1Mwpbn{4a%0fEY9YdP$ zjw$OF^J860dVK{P-L4l__iaG7bPHWmIh)pog<1!a;w#Dk406Hv--&ztMlh}to8}kI zV1I8S*uQchm^@?z2fNm$xn*sb!Bp4W|WdK1^bD^PQmNXKbczLZ#`l6mf8(GEw--hknE7=v< zfcFi386!UOW|twmX7M`BV0pb&Qx&XvZT1zkxd4&3dglyXH04 zX6vFF+0;*57T8FO)V&wd2Ift zkr?AibLU^yOz$YkT4^(9F?CSGzezJ2wfS`J$ySpfVi887WVfTQLj7ke5&{TNfo)*ep|qgvA?|%Wos= zQ&lyvz_i&puybK?t18jB{~)Bh;wmq78 ztJxOC#SNO&fZYDRx#0ECxf*W8y#tJL7wXOGtr@(C>~ii#yFq#qa@1EbRhU`w8Zo(E zLw=7}B2|{l%c%6zNTU75j_*bVY4+HQ+34{y`*OnrBf#ry; z{SgabgL1jSL1a&pyQhvCeDu^L1@5WN@}vQoJu9%cOrjxRr;h{Ck`nqN7eji6DARcT zFmw6Z{M8%fE0=GCiN$)`U*2n}`Z{{7;XBwS$IO|XL&J!<1HB$wFcDPt>I8sz!PqJ8 z*$Nhn)M*`7kT@+@Sw}!oo7BARx&MOZ_4T-E@AcQqHD?!B5_S$2+ zRSmjm7}1lJ1RLm#4KEw@AHCRV^yFgwEcF;!ERHyc7A%K-g!E<2Euo=&fQ}yr5ZZow zRlg+=B-UPg8jcfP%Md8!-;gR$hrfsp!z+Dqc%_dwe{A6cjC>XYap92jrk)05`b;6e zS6FUO853AIUrNJHHn3{SCfQv56NI?Ad#>7sboyyj#>*_2Ojk|v zgA|Bi@0tYO8@0vs+(R;shawZn(mR%NL+i}BN9K7=EG^pl$M6Vk=mWaUf<(l)XIYx^ zJ=lTD4^zO!cHlubTyD0tznjZsVHB=bM6&-Z`uUuWe1?K*_|LTto1Mww^WN^bV?W6! z2ItIm2Ha8b9qb%VSWf&n_l~)*8V{^b$exN!dSuQPZQy30qXXulLrh)5BPyUcACgJ^ z#Y1IzfSQ>4vsip#@5Q3wj>U3c2a6^Dj~1)U2~dx+aB%hmD5lEzDOg=tVq)&0LaUDD zzVOI=CZc&uvq+bi>_y^(MOK5aqfK8p?X{P?iJe@DdXwPhHvkYfWe3kk_=&vDrOMs{ z11E^5q$23^E5K0F5%$+=EFz!Ob4a1@vk%H{1km)OmaWf4ue?D{mxjh}>n}@NJ1~Px z5BmSg2x}&cEqIu~|D1zDr=0tOp%T4Z7fhXVW0R6|vN57C_ZiQn82H{NBitR02zqml|TX81?8VO?{pRimwg&d67@pkyaoSha71#sjT~Ur1r+B zkI>4GS@~5v!*a3+q0$N|0hD-G-moE@dN--diic@ zXuf1OP42=H<@ELukv3BF9jt(Rz!Q2={0MyeK9@v=>X6 zW?e;wZz*4`x8c3)v!YU_;oXU=MyhoWJSsAf!PXjZ1~Dbq+J)I-8~kgG?_WY<5QS}` z?Suui1v>LDXHF22A?1)m87xLC64(<0jRVPZsGBf5M~2aRm!$_2AQgL#A}f-zyZ^BP z@cS~p{#TH6;YWdXW_|*e9Q;OorgjpLn!NjxaEm&4QOuolW1swkw98lTSrjVmZ4iF(2PZ_)%0@$uRiIe=SI0wby-{)sEQQd`gx1!c6jVgTQZpHOmUbVJZ zgG0X2US04s-2PcN{)kiYlqj%$gQD}Timt4>G3uRn=lT=7G9eA?XocR)?mojao_Al17v)k+up5_#xWew04MyR6 zL2$_OBj>4d_gLV}jJxJ(AFGBU0sojff8Kp*=FE;^F2jqZ_TGnPe_8UL@Y(61m;Zkm z`!xniB4Ty#EPITkc-zMl@6xL01wLzbEbHyJcRPh~Fu^i>+soio+xr>w+(d+$9|Q7< zqf!49A-X4qi6d%snN^Zp0Td>qi4Kx5=u0#TaBYDYaw26riF_9Uz0+D&{+C0`Gs)gthR1No3w3CtR=qwjR8BH@LY3^J|)MUp($n>baRq^## zkdPS-`+%UMO{2`d3L5(qd{&KDn0v+eOQ&cIVxeSc31!25jhbFkJVxdl;%e)qltU`L zeF8P<*q04*Sxxt0~Yl5K@);;O~D3G^5EQ6Ta%Vy z??IVrOEfMb+GyLOF?R5Pla)na<;fk`Bl7{J#cu`dV+6t9Mi@PZt%iPva{X zopykXANBWr%gRHWpw$!o5q3qth)e%_?m|A1wkMMLbUtaBg+%|GAIm56c7A{UNd9zT z^6=q&Lgodz@=T-fg-AWpSpSm(KsB1X<)6p72L{4O77R^m#ojda6iiz<+Wg~C9l-_= z+_9lNBvz83CD`O!R_g_2la^@X=u(i;a{;U#gtMZSFjNO{)C&}-5^IKD+c9Fs{}N`* z^+r{43$_!-P^ox~e2`G-O-p|eBzj{igZ^1i_Xh#SRwGdxmBrPJ0^B}Oez%OzK{ek< zqV;$;L3;1Z2k{tCg~w%-TsH}a(C7o$VjNA%IbNRQy@@yM?eAhGCRL@uo9`+gv^fJ_ z1m-x_Irj?0xAMR1BLi~jgcRA#mYP#S_n2FV6;}#%|>V=md{2A z(d!ZR%1i8&A2wcM%N2(Hwf=ebM}U8|B@xrq>Mg!Q z3$B5B(?{I4-GKgmtC-rxRJ^BLFDPYXvT}7*>927VYf&-M1yvoqV~E&DXJJAb|3$K| z7mzo=uErq%Ct-Bb2c3hC9(||C#vmNCpswR)&d&bOV&vyfEla7x2R-$TS5qsCxOWK z*uIxkDV5%W4^CxzDbza3qMp44zvTl9R$|g`sVuydDR_8Bpqo!9pzxaE|D+n_Q{Q80 z*Ir4(n>T`I25s~A9axju-bj#L$#qjJqlnO^gM2p)>oU_h)ioeCr#G@)%l~#T)kp zziX}^?YF%B;Thvy^Y-!E9}1ZiI=5d3y6qqX>cNY+e?s!8L7|1t*+6&@3b07Z%Ib{k zUT>^5Z;6^LvR00Idl0$ZQd?RMT)*9tYcmp-k7cHi#+}HJzl8o9NJ8h+S8v`F z>Jzc`$U1#vJ~R=ey#eoM0%0RKIkIHfVP#G4t85)mc|=}Z3-lJtzs)Z0_uXLmb7Gq9cCBbazIDFicFu5x;7)EVCBvR)VUsn4}2Q%miQ+T z0ZIZ_lYv7)1SkdHDJW(W2HPRy9T%RHbT8da_TWd^60_`0FlYyQ<)#gVv2fP#m(Ro! z_$^}ZanguH2;k8H1tuRrND-G&o{L0CBexC5>^{}GuqPhZ26);>Ufi{ED`5A$&V^HU z$-ZV{l%!KWwC*h6V#~Dto5&PLh0*D+1CD$hf(U{VUuM}aGf6Wca_HY;BA7=mtN#uX zI7UR|Z)1S4PP44J!TNWZ{1YUhxw!j;AE5YGc*0^`}u03U>Hv66>SHzrBbj@u08ks=2xMjtc#&WVr`@-Z^Rf9e|H~+|) z3GN2P1o(uM2&sp;_{vM!udGSHKJakSuGxrADS@^3KZGrO<&@|g7CQ?54;p`RG0BpP zNj6QuC^qcqe};B4k^T;$e~zRd^4gK8?o;Sj&}@f!NMs@< z$Wj*p&^#1xYJm`=lt8efxQAq}(A5s=XB%e$%);5jgrh<&dJ$I8Axo1MleC zp!KvuU2d%yaP&rk7w163q+{}F-f8LVi?@2a4`@cX!*dwFN_6OdND*0l zWzT;T0C1UJcAy72G<@ZZw=#HgCIAhHo|4a`zu?d^{@_$`>8sgVkF4+ySp7RpcppUn z0g^Bou{r&Zkb&Ry5-a3LWI#D`Di``6BLUao4I5mt_4L1F;Vxvz@O8=*G~XjGOrr_C z*Whd7q0U*Bc@(%nNuB>u+Ro!y_)(`2W5u8|-b=XUV@N^v%C8{B&tZxIQked@vNr6- zr(rqD?T1ARw%fB^aQeneT~l9()Z#7E2c&EUoP&g(M=71lP?lj?!fHe7EXq=}2PrQQ z2xaIZqtf@SNGW*N>`*9=0F^RZ);ou(BuAl7if#qLGbHf8HZ1VbYqXnyQk?INQM?O; zAPsH7DctGZvP_76)JhowDTv2KY5-Qii{*vw+HOj$$ATye`=eGwxL^V*$;hVl&Xla{ z00E0yw20I1AV$0fDyWKKI`CNqZ|C490 zdE>NWjb=NUcCdK*rPF?Gsgn?}lj3nV^=U*Pk}d5m*6u>Kw-@o$zlUBA$qe8sS|}cj zOt5Ut$A$I)PHS99Tv+FIh72DStt+^Ahft)Le_}Q2e}K-Bj`DRvloO(@0NWK+;Yh>9 zN_f4|X)&;z22;Wf7vu@864L*Q{l3G53Qp)mS~T|0f`?5j zoBe?UYx0Bz4cN(kXj$W8OLj(v=&9(;Au#f7j0qO;SMkt)jmckULN}NG873=8!qjIF z(FF_A_gO>|)51=;31RYbWBn#<>i^8*?Zpdpg=ODD@-4mqMS0qe72Q9vK>Xt%bNoHZ z)dHHxYbIzz~kZmGH_km!^VEh?>QwDCzL>WK-srb#t&AN*ho z^bFb-k1ePmhRzs`KY+jKdl2ux&QW?#taKNyiNf`eUSiJ@H>`RMbr;0LldH_7jy zIYUGiV0i!A$nYlDQd1mDf0uLk-(@fVyK-{l8<}pVhu}2N0YVeKksi9)7ng@4-U0sq zM>zEeA8_h}4|xKWG5S#@$d6Is{#eE37lxF3zz6v8!1du%i*M}kT;#fIA|4yRFlje# zx1mIJQj}EZXJ;R#Fdppg9551herFJ~@jd;=DAYaH#LJNa!FWlC_Tgwb9!#WO5etlT zdHQwCg4H=jmQlvIGZ%>Db^qebjvnA66@3R+1^)v^>sY7X)W1$3GjOkk<{jLOrC$mr zx2O=}HRz0ccU$-Y0DKj*xHs)pgHzL;#O#}wug`bT7|t-alW?b}-RVxYy1o>ZOk;vO zoy;Jwf1j^l&UDgu)zWFM6jo4bIS5+Vlunv}4=D2W?~gPLvI;F0;ol~7hY8oNw{?qe zFe_@Lu;Fbhkt)CbcSypNs%c@4)H-C7!|WYzVL>p~4^!t_J2TwRzOSC4rp&0Y-;7v#QIFqb|`HONdz6ivWP4 zCKy(pu5Vs5=5Hjl8<;RJt+<5Yq;r9Zuat;J>EO31_9N4IWFCf({kJhtW`Jql&Lj z)~qDLCCjqr^huNq&AMy;oUYuF+w#0|p*b&i!?5%Zk%GcT*;^DoPSO9^0Cw$~&IJg2 zZwUc@pL$^1SZ`e+`&2*aDs87L4;prt!Zx);D`}Bdq#sRUMT0 zYqLAmWq5-lKwcdi%jMvgHu%}ip7NUAc)@IqFH+!YT^KnQE@D_|n^*ZYd_Fskc)kjW zLUxaS5MIY#VU*)&VDqjy`Bcw=#%AIQ1Pw`nVNe*IPLP0MBW7jiVvvHHNn}@7_8{a@Sm`fbmEzl&Qnv65f^hkdtd!;1Ah zYp##Ek_grVFIWyp z$}{sX-@N?Fjmy{PBA3$}9E}_$On?D4HO}UnETV!{%JJq6deU;*eb-MA>(_WbC(zVj z91+wDa}*RzDrQ`<00^ZYM$bHGdWYT5BO9n6WPGI6cV4HR56>VjTEJ|u`~EN&%z{rqe1mi)JhUsWM8J_XG^#MPrz zYj_Fpj!Z7IVmrCQQPUTqfb&H(F#MlD;v|MISm(fjANzx@Pag^|GdlL<7mP0$pKzaW gpNCTYr?~?YOtbmQT@1CrzZC0=(5u*1&1bnnStAuJU5#P`Uj_xQc`- z?ZH8L3e!9SA&8&_iPvu$GtgP#&3Vizc}|2U_$3islBs{;#lE25lc9eDeq=PHZjhDA z%2PW}ReB_KhW7RdKzRz&`~*Uhm-iaS`@d7rF; zIuNAxf5&yF4r*VJW*ye-iq)NKN=Y5!*(XHp)Xc<~VGOzR z=IN=sJJvFtB}J)@l9N&k;{v>%63$zci(%JsBa1_gX==<}Bi6bD!u8A|&16!@L+f~v z8XJ3AWu2#``IG4P;K-YCG%4pYviZEUle0xGQZtdu=$SM#TP~vKxt&zw=-X1;!?MWB zXere)D)Mo(IJ1*dJwEt6GP#wXK%f~^-b7iEXR|0lGMqpi4i;zbUNT9QC?Jvl?ts~u z9T225U;zzjAD$jOoSuKsD&fH`&mnU`u7p%phv1$u{K#e?1dS2i<~tBjAF^UtrIlAh zA*ZCKpAkk9*a3}hG*Px;~(&)6F;c!D7%%0J4A%=zuXA zB7AQHdcN0&t?dT+a;(N}ypSl!n1yuG&0%I-Y{@osj9iusg+2{BDdIpMn8lD zdJn}m9_7c;fp|Bp54{jL&+vKE-(hsG-|PcYAyx|e#swC-Q5|W#lLO||ClQ$Bo3V0O6861v`a0`*L(Bc`@OGmaO8+@!S|2) z_nSv`%lgY44u2ImT!kT$Y#An3Wwv&X(uk%vmdQN=x$>&z<*YWX&5q5j%$s_%<8y0vf*hG6@oZY1txUZ+LRLX1M@N=;Mvi6fL*U7mQ+sw2 z&>lZP=1zQd>H^a9CG|u>H7Bx?^Kr>Jd4P6KkyEo(wKfG$=ZLI6&NUDxTLPa?&(4sw zIVyLj=cs1`%8Qvl^+Eq=>c7EQoU^5=Pn;CN={~Zapoc%gxIbMgX-`YLXN+B-o-M4Y zv*g@tb!yMi0s0Q23u%96a_L4aQ$ZzGgFwMVF^xw|@OVgLg_*>C&I#^ufxnDd$O&x< zNV)~paS9405wu5zpoGT2V{uMWtt>_tCi~;GR68qj!G(;$fm9)T(W)bMm!86IG?Mg*>s`3>ApuGh;?ZS}@sjZt0d*U`z)mz_~RL#0!2w}dP)be$G7D=O`m;WC9n@n-Wd z1iUw3;lLD&Q8|RlAqK_+p5h_v4-_OCY5;IUN(%%Ok9jIULZ;L}q5CEk3m82fMSRbk z4%gx+5X@+iS0Kp>R!^?fZ>$`Bpe^)~S&uw?aQ zw0*Eu-v7-KAAp|cq&0v7Y=KR#2IGX0Ko01rb)Cvx#go=8@FMNDwg4-X8{@4JsAxs3 z+e-51^26pwEy)yJPl9ka=u=rdd96BKmTjZD zy@Kk{)kY-GQ(UpY&4MxyFj_26t(HhA5Am^9&oT~i-cuQg(ur#XTI4ok-OtzU$naQy7cpaK908M)z U4>?IA`lhrSF7^dWsQP!t8)^ubN6e&^0E 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 F{|n*41R?+c literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/click/__pycache__/core.cpython-39.pyc b/venv/lib/python3.9/site-packages/click/__pycache__/core.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fcd753a8d10ffa2d01cb26c2a87b3f9808b9426c GIT binary patch literal 88348 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 z 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/click/__pycache__/exceptions.cpython-39.pyc b/venv/lib/python3.9/site-packages/click/__pycache__/exceptions.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7cebd045cabcfe500f17a1da83244aecdd39a695 GIT binary patch literal 10147 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/click/__pycache__/formatting.cpython-39.pyc b/venv/lib/python3.9/site-packages/click/__pycache__/formatting.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dcc28f23b9a81c200ea625f4047f42e1267edb56 GIT binary patch literal 9427 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

|e99Cz18XE}KIpL7PifIF3^8`mRNv1rRVs128 z#AMFF=a^Vl;KwhqSTGQ_oSS`#(@e+bSzN`v88dNjRF+GqBbl<%S;k8zVTk8|9YQ3O zGTQ6mkHc$)|6WQInclXvg3 znVdraHjhA1v0!rs1!c?HE)~%Goti`KLda{WOwT}jp>g>NY*g^B!`~`+mthQS*CQ#U zdYx~Jum+Dq`92Iz0bPbv`xHda0MoSgGx`agf*```JE!OXE+>aSIQeDImT^KvS^t)L z&~t~q%H^UiZp6~Vlx%d&zQ$d8o=Mz3PHgqS+A#o$bY zl!w+Jb&R>Rx2#nMUrDXo==ZYOy5dN2uX7LkB8Za|a|VP0Yr`^_PvEN}lj}_s z_$|MQ8oqkV`a-umD0F?lvza#xT$agHt-@BmY+}U-wR1~$zPf+^&aL6@*SB`R+3SBb z*eq;^aHX@vs*uio!=M;J!d(@YDGQ0Bge25mW_d7{Qsm9=QY+0wD4T@J9<_sWZh|y# j&LqtQ`^?_{+M;fvCTjbQqOS#LD+ti#V0(L`zE=MSX{d7* literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/click/__pycache__/parser.cpython-39.pyc b/venv/lib/python3.9/site-packages/click/__pycache__/parser.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..913696898ce71d5b2715becc6c25bf10a92d600f GIT binary patch literal 13581 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/click/__pycache__/shell_completion.cpython-39.pyc b/venv/lib/python3.9/site-packages/click/__pycache__/shell_completion.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f97c2190f8a96094cb9a13a433c246ab106376df GIT binary patch literal 16660 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 M=;)QAdg#;t0}P`ta{vGU literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/click/__pycache__/termui.cpython-39.pyc b/venv/lib/python3.9/site-packages/click/__pycache__/termui.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bbede3aa166e8407e44dccc4d7d8d6acbacd7797 GIT binary patch literal 26540 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 Yf7tS2^M2%qqfs#00sivmu>b%7 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/click/__pycache__/testing.cpython-39.pyc b/venv/lib/python3.9/site-packages/click/__pycache__/testing.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..040eb100ff221fa9e106c29d9a7b33fddc979a53 GIT binary patch literal 15131 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/click/__pycache__/types.cpython-39.pyc b/venv/lib/python3.9/site-packages/click/__pycache__/types.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..50757a6e7864cc9076ec1f59b1af9b357fb058de GIT binary patch literal 32921 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

|c+lpN`+Ocy$j^0(8qcBd;W{BCp{2 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 ReCCmn#~ykv@0fqt{{!g^PQL&E literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/click/__pycache__/utils.cpython-39.pyc b/venv/lib/python3.9/site-packages/click/__pycache__/utils.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20e2141f4cff521072027138c7d1c6c30551c92f GIT binary patch literal 17785 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 KoRqbC_ str: + return sys.getfilesystemencoding() or sys.getdefaultencoding() + + +def _make_text_stream( + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if encoding is None: + encoding = get_best_encoding(stream) + if errors is None: + errors = "replace" + return _NonClosingTextIOWrapper( + stream, + encoding, + errors, + line_buffering=True, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def is_ascii_encoding(encoding: str) -> bool: + """Checks if a given encoding is ascii.""" + try: + return codecs.lookup(encoding).name == "ascii" + except LookupError: + return False + + +def get_best_encoding(stream: t.IO) -> str: + """Returns the default stream encoding if not found.""" + rv = getattr(stream, "encoding", None) or sys.getdefaultencoding() + if is_ascii_encoding(rv): + return "utf-8" + return rv + + +class _NonClosingTextIOWrapper(io.TextIOWrapper): + def __init__( + self, + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, + **extra: t.Any, + ) -> None: + self._stream = stream = t.cast( + t.BinaryIO, _FixupStream(stream, force_readable, force_writable) + ) + super().__init__(stream, encoding, errors, **extra) + + def __del__(self) -> None: + try: + self.detach() + except Exception: + pass + + def isatty(self) -> bool: + # https://bitbucket.org/pypy/pypy/issue/1803 + return self._stream.isatty() + + +class _FixupStream: + """The new io interface needs more from streams than streams + traditionally implement. As such, this fix-up code is necessary in + some circumstances. + + The forcing of readable and writable flags are there because some tools + put badly patched objects on sys (one such offender are certain version + of jupyter notebook). + """ + + def __init__( + self, + stream: t.BinaryIO, + force_readable: bool = False, + force_writable: bool = False, + ): + self._stream = stream + self._force_readable = force_readable + self._force_writable = force_writable + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._stream, name) + + def read1(self, size: int) -> bytes: + f = getattr(self._stream, "read1", None) + + if f is not None: + return t.cast(bytes, f(size)) + + return self._stream.read(size) + + def readable(self) -> bool: + if self._force_readable: + return True + x = getattr(self._stream, "readable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.read(0) + except Exception: + return False + return True + + def writable(self) -> bool: + if self._force_writable: + return True + x = getattr(self._stream, "writable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.write("") # type: ignore + except Exception: + try: + self._stream.write(b"") + except Exception: + return False + return True + + def seekable(self) -> bool: + x = getattr(self._stream, "seekable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.seek(self._stream.tell()) + except Exception: + return False + return True + + +def _is_binary_reader(stream: t.IO, default: bool = False) -> bool: + try: + return isinstance(stream.read(0), bytes) + except Exception: + return default + # This happens in some cases where the stream was already + # closed. In this case, we assume the default. + + +def _is_binary_writer(stream: t.IO, default: bool = False) -> bool: + try: + stream.write(b"") + except Exception: + try: + stream.write("") + return False + except Exception: + pass + return default + return True + + +def _find_binary_reader(stream: t.IO) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_reader(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_reader(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _find_binary_writer(stream: t.IO) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_writer(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_writer(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _stream_is_misconfigured(stream: t.TextIO) -> bool: + """A stream is misconfigured if its encoding is ASCII.""" + # If the stream does not have an encoding set, we assume it's set + # to ASCII. This appears to happen in certain unittest + # environments. It's not quite clear what the correct behavior is + # but this at least will force Click to recover somehow. + return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii") + + +def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool: + """A stream attribute is compatible if it is equal to the + desired value or the desired value is unset and the attribute + has a value. + """ + stream_value = getattr(stream, attr, None) + return stream_value == value or (value is None and stream_value is not None) + + +def _is_compatible_text_stream( + stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> bool: + """Check if a stream's encoding and errors attributes are + compatible with the desired values. + """ + return _is_compat_stream_attr( + stream, "encoding", encoding + ) and _is_compat_stream_attr(stream, "errors", errors) + + +def _force_correct_text_stream( + text_stream: t.IO, + encoding: t.Optional[str], + errors: t.Optional[str], + is_binary: t.Callable[[t.IO, bool], bool], + find_binary: t.Callable[[t.IO], t.Optional[t.BinaryIO]], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if is_binary(text_stream, False): + binary_reader = t.cast(t.BinaryIO, text_stream) + else: + text_stream = t.cast(t.TextIO, text_stream) + # If the stream looks compatible, and won't default to a + # misconfigured ascii encoding, return it as-is. + if _is_compatible_text_stream(text_stream, encoding, errors) and not ( + encoding is None and _stream_is_misconfigured(text_stream) + ): + return text_stream + + # Otherwise, get the underlying binary reader. + possible_binary_reader = find_binary(text_stream) + + # If that's not possible, silently use the original reader + # and get mojibake instead of exceptions. + if possible_binary_reader is None: + return text_stream + + binary_reader = possible_binary_reader + + # Default errors to replace instead of strict in order to get + # something that works. + if errors is None: + errors = "replace" + + # Wrap the binary stream in a text stream with the correct + # encoding parameters. + return _make_text_stream( + binary_reader, + encoding, + errors, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def _force_correct_text_reader( + text_reader: t.IO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_reader, + encoding, + errors, + _is_binary_reader, + _find_binary_reader, + force_readable=force_readable, + ) + + +def _force_correct_text_writer( + text_writer: t.IO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_writable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_writer, + encoding, + errors, + _is_binary_writer, + _find_binary_writer, + force_writable=force_writable, + ) + + +def get_binary_stdin() -> t.BinaryIO: + reader = _find_binary_reader(sys.stdin) + if reader is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdin.") + return reader + + +def get_binary_stdout() -> t.BinaryIO: + writer = _find_binary_writer(sys.stdout) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdout.") + return writer + + +def get_binary_stderr() -> t.BinaryIO: + writer = _find_binary_writer(sys.stderr) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stderr.") + return writer + + +def get_text_stdin( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True) + + +def get_text_stdout( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True) + + +def get_text_stderr( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True) + + +def _wrap_io_open( + file: t.Union[str, os.PathLike, int], + mode: str, + encoding: t.Optional[str], + errors: t.Optional[str], +) -> t.IO: + """Handles not passing ``encoding`` and ``errors`` in binary mode.""" + if "b" in mode: + return open(file, mode) + + return open(file, mode, encoding=encoding, errors=errors) + + +def open_stream( + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, +) -> t.Tuple[t.IO, bool]: + binary = "b" in mode + + # Standard streams first. These are simple because they don't need + # special handling for the atomic flag. It's entirely ignored. + if filename == "-": + if any(m in mode for m in ["w", "a", "x"]): + if binary: + return get_binary_stdout(), False + return get_text_stdout(encoding=encoding, errors=errors), False + if binary: + return get_binary_stdin(), False + return get_text_stdin(encoding=encoding, errors=errors), False + + # Non-atomic writes directly go out through the regular open functions. + if not atomic: + return _wrap_io_open(filename, mode, encoding, errors), True + + # Some usability stuff for atomic writes + if "a" in mode: + raise ValueError( + "Appending to an existing file is not supported, because that" + " would involve an expensive `copy`-operation to a temporary" + " file. Open the file in normal `w`-mode and copy explicitly" + " if that's what you're after." + ) + if "x" in mode: + raise ValueError("Use the `overwrite`-parameter instead.") + if "w" not in mode: + raise ValueError("Atomic writes only make sense with `w`-mode.") + + # Atomic writes are more complicated. They work by opening a file + # as a proxy in the same folder and then using the fdopen + # functionality to wrap it in a Python file. Then we wrap it in an + # atomic file that moves the file over on close. + import errno + import random + + try: + perm: t.Optional[int] = os.stat(filename).st_mode + except OSError: + perm = None + + flags = os.O_RDWR | os.O_CREAT | os.O_EXCL + + if binary: + flags |= getattr(os, "O_BINARY", 0) + + while True: + tmp_filename = os.path.join( + os.path.dirname(filename), + f".__atomic-write{random.randrange(1 << 32):08x}", + ) + try: + fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm) + break + except OSError as e: + if e.errno == errno.EEXIST or ( + os.name == "nt" + and e.errno == errno.EACCES + and os.path.isdir(e.filename) + and os.access(e.filename, os.W_OK) + ): + continue + raise + + if perm is not None: + os.chmod(tmp_filename, perm) # in case perm includes bits in umask + + f = _wrap_io_open(fd, mode, encoding, errors) + af = _AtomicFile(f, tmp_filename, os.path.realpath(filename)) + return t.cast(t.IO, af), True + + +class _AtomicFile: + def __init__(self, f: t.IO, tmp_filename: str, real_filename: str) -> None: + self._f = f + self._tmp_filename = tmp_filename + self._real_filename = real_filename + self.closed = False + + @property + def name(self) -> str: + return self._real_filename + + def close(self, delete: bool = False) -> None: + if self.closed: + return + self._f.close() + os.replace(self._tmp_filename, self._real_filename) + self.closed = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._f, name) + + def __enter__(self) -> "_AtomicFile": + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self.close(delete=exc_type is not None) + + def __repr__(self) -> str: + return repr(self._f) + + +def strip_ansi(value: str) -> str: + return _ansi_re.sub("", value) + + +def _is_jupyter_kernel_output(stream: t.IO) -> bool: + while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): + stream = stream._stream + + return stream.__class__.__module__.startswith("ipykernel.") + + +def should_strip_ansi( + stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None +) -> bool: + if color is None: + if stream is None: + stream = sys.stdin + return not isatty(stream) and not _is_jupyter_kernel_output(stream) + return not color + + +# On Windows, wrap the output streams with colorama to support ANSI +# color codes. +# NOTE: double check is needed so mypy does not analyze this on Linux +if sys.platform.startswith("win") and WIN: + from ._winconsole import _get_windows_console_stream + + def _get_argv_encoding() -> str: + import locale + + return locale.getpreferredencoding() + + _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def auto_wrap_for_ansi( + stream: t.TextIO, color: t.Optional[bool] = None + ) -> t.TextIO: + """Support ANSI color and style codes on Windows by wrapping a + stream with colorama. + """ + try: + cached = _ansi_stream_wrappers.get(stream) + except Exception: + cached = None + + if cached is not None: + return cached + + import colorama + + strip = should_strip_ansi(stream, color) + ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) + rv = t.cast(t.TextIO, ansi_wrapper.stream) + _write = rv.write + + def _safe_write(s): + try: + return _write(s) + except BaseException: + ansi_wrapper.reset_all() + raise + + rv.write = _safe_write + + try: + _ansi_stream_wrappers[stream] = rv + except Exception: + pass + + return rv + + +else: + + def _get_argv_encoding() -> str: + return getattr(sys.stdin, "encoding", None) or get_filesystem_encoding() + + def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] + ) -> t.Optional[t.TextIO]: + return None + + +def term_len(x: str) -> int: + return len(strip_ansi(x)) + + +def isatty(stream: t.IO) -> bool: + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func( + src_func: t.Callable[[], t.TextIO], wrapper_func: t.Callable[[], t.TextIO] +) -> t.Callable[[], t.TextIO]: + cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def func() -> t.TextIO: + stream = src_func() + try: + rv = cache.get(stream) + except Exception: + rv = None + if rv is not None: + return rv + rv = wrapper_func() + try: + cache[stream] = rv + except Exception: + pass + return rv + + return func + + +_default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin) +_default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout) +_default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr) + + +binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = { + "stdin": get_binary_stdin, + "stdout": get_binary_stdout, + "stderr": get_binary_stderr, +} + +text_streams: t.Mapping[ + str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO] +] = { + "stdin": get_text_stdin, + "stdout": get_text_stdout, + "stderr": get_text_stderr, +} diff --git a/venv/lib/python3.9/site-packages/click/_termui_impl.py b/venv/lib/python3.9/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..06cf2b7 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/_termui_impl.py @@ -0,0 +1,717 @@ +""" +This module contains implementations for the termui module. To keep the +import time of Click down, some infrequently used functionality is +placed in this module and only imported as needed. +""" +import contextlib +import math +import os +import sys +import time +import typing as t +from gettext import gettext as _ + +from ._compat import _default_text_stdout +from ._compat import CYGWIN +from ._compat import get_best_encoding +from ._compat import isatty +from ._compat import open_stream +from ._compat import strip_ansi +from ._compat import term_len +from ._compat import WIN +from .exceptions import ClickException +from .utils import echo + +V = t.TypeVar("V") + +if os.name == "nt": + BEFORE_BAR = "\r" + AFTER_BAR = "\n" +else: + BEFORE_BAR = "\r\033[?25l" + AFTER_BAR = "\033[?25h\n" + + +class ProgressBar(t.Generic[V]): + def __init__( + self, + iterable: t.Optional[t.Iterable[V]], + length: t.Optional[int] = None, + fill_char: str = "#", + empty_char: str = " ", + bar_template: str = "%(bar)s", + info_sep: str = " ", + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + label: t.Optional[str] = None, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, + width: int = 30, + ) -> None: + self.fill_char = fill_char + self.empty_char = empty_char + self.bar_template = bar_template + self.info_sep = info_sep + self.show_eta = show_eta + self.show_percent = show_percent + self.show_pos = show_pos + self.item_show_func = item_show_func + self.label = label or "" + if file is None: + file = _default_text_stdout() + self.file = file + self.color = color + self.update_min_steps = update_min_steps + self._completed_intervals = 0 + self.width = width + self.autowidth = width == 0 + + if length is None: + from operator import length_hint + + length = length_hint(iterable, -1) + + if length == -1: + length = None + if iterable is None: + if length is None: + raise TypeError("iterable or length is required") + iterable = t.cast(t.Iterable[V], range(length)) + self.iter = iter(iterable) + self.length = length + self.pos = 0 + self.avg: t.List[float] = [] + self.start = self.last_eta = time.time() + self.eta_known = False + self.finished = False + self.max_width: t.Optional[int] = None + self.entered = False + self.current_item: t.Optional[V] = None + self.is_hidden = not isatty(self.file) + self._last_line: t.Optional[str] = None + + def __enter__(self) -> "ProgressBar": + self.entered = True + self.render_progress() + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self.render_finish() + + def __iter__(self) -> t.Iterator[V]: + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + self.render_progress() + return self.generator() + + def __next__(self) -> V: + # Iteration is defined in terms of a generator function, + # returned by iter(self); use that to define next(). This works + # because `self.iter` is an iterable consumed by that generator, + # so it is re-entry safe. Calling `next(self.generator())` + # twice works and does "what you want". + return next(iter(self)) + + def render_finish(self) -> None: + if self.is_hidden: + return + self.file.write(AFTER_BAR) + self.file.flush() + + @property + def pct(self) -> float: + if self.finished: + return 1.0 + return min(self.pos / (float(self.length or 1) or 1), 1.0) + + @property + def time_per_iteration(self) -> float: + if not self.avg: + return 0.0 + return sum(self.avg) / float(len(self.avg)) + + @property + def eta(self) -> float: + if self.length is not None and not self.finished: + return self.time_per_iteration * (self.length - self.pos) + return 0.0 + + def format_eta(self) -> str: + if self.eta_known: + t = int(self.eta) + seconds = t % 60 + t //= 60 + minutes = t % 60 + t //= 60 + hours = t % 24 + t //= 24 + if t > 0: + return f"{t}d {hours:02}:{minutes:02}:{seconds:02}" + else: + return f"{hours:02}:{minutes:02}:{seconds:02}" + return "" + + def format_pos(self) -> str: + pos = str(self.pos) + if self.length is not None: + pos += f"/{self.length}" + return pos + + def format_pct(self) -> str: + return f"{int(self.pct * 100): 4}%"[1:] + + def format_bar(self) -> str: + if self.length is not None: + bar_length = int(self.pct * self.width) + bar = self.fill_char * bar_length + bar += self.empty_char * (self.width - bar_length) + elif self.finished: + bar = self.fill_char * self.width + else: + chars = list(self.empty_char * (self.width or 1)) + if self.time_per_iteration != 0: + chars[ + int( + (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5) + * self.width + ) + ] = self.fill_char + bar = "".join(chars) + return bar + + def format_progress_line(self) -> str: + show_percent = self.show_percent + + info_bits = [] + if self.length is not None and show_percent is None: + show_percent = not self.show_pos + + if self.show_pos: + info_bits.append(self.format_pos()) + if show_percent: + info_bits.append(self.format_pct()) + if self.show_eta and self.eta_known and not self.finished: + info_bits.append(self.format_eta()) + if self.item_show_func is not None: + item_info = self.item_show_func(self.current_item) + if item_info is not None: + info_bits.append(item_info) + + return ( + self.bar_template + % { + "label": self.label, + "bar": self.format_bar(), + "info": self.info_sep.join(info_bits), + } + ).rstrip() + + def render_progress(self) -> None: + import shutil + + if self.is_hidden: + # Only output the label as it changes if the output is not a + # TTY. Use file=stderr if you expect to be piping stdout. + if self._last_line != self.label: + self._last_line = self.label + echo(self.label, file=self.file, color=self.color) + + return + + buf = [] + # Update width in case the terminal has been resized + if self.autowidth: + old_width = self.width + self.width = 0 + clutter_length = term_len(self.format_progress_line()) + new_width = max(0, shutil.get_terminal_size().columns - clutter_length) + if new_width < old_width: + buf.append(BEFORE_BAR) + buf.append(" " * self.max_width) # type: ignore + self.max_width = new_width + self.width = new_width + + clear_width = self.width + if self.max_width is not None: + clear_width = self.max_width + + buf.append(BEFORE_BAR) + line = self.format_progress_line() + line_len = term_len(line) + if self.max_width is None or self.max_width < line_len: + self.max_width = line_len + + buf.append(line) + buf.append(" " * (clear_width - line_len)) + line = "".join(buf) + # Render the line only if it changed. + + if line != self._last_line: + self._last_line = line + echo(line, file=self.file, color=self.color, nl=False) + self.file.flush() + + def make_step(self, n_steps: int) -> None: + self.pos += n_steps + if self.length is not None and self.pos >= self.length: + self.finished = True + + if (time.time() - self.last_eta) < 1.0: + return + + self.last_eta = time.time() + + # self.avg is a rolling list of length <= 7 of steps where steps are + # defined as time elapsed divided by the total progress through + # self.length. + if self.pos: + step = (time.time() - self.start) / self.pos + else: + step = time.time() - self.start + + self.avg = self.avg[-6:] + [step] + + self.eta_known = self.length is not None + + def update(self, n_steps: int, current_item: t.Optional[V] = None) -> None: + """Update the progress bar by advancing a specified number of + steps, and optionally set the ``current_item`` for this new + position. + + :param n_steps: Number of steps to advance. + :param current_item: Optional item to set as ``current_item`` + for the updated position. + + .. versionchanged:: 8.0 + Added the ``current_item`` optional parameter. + + .. versionchanged:: 8.0 + Only render when the number of steps meets the + ``update_min_steps`` threshold. + """ + if current_item is not None: + self.current_item = current_item + + self._completed_intervals += n_steps + + if self._completed_intervals >= self.update_min_steps: + self.make_step(self._completed_intervals) + self.render_progress() + self._completed_intervals = 0 + + def finish(self) -> None: + self.eta_known = False + self.current_item = None + self.finished = True + + def generator(self) -> t.Iterator[V]: + """Return a generator which yields the items added to the bar + during construction, and updates the progress bar *after* the + yielded block returns. + """ + # WARNING: the iterator interface for `ProgressBar` relies on + # this and only works because this is a simple generator which + # doesn't create or manage additional state. If this function + # changes, the impact should be evaluated both against + # `iter(bar)` and `next(bar)`. `next()` in particular may call + # `self.generator()` repeatedly, and this must remain safe in + # order for that interface to work. + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + + if self.is_hidden: + yield from self.iter + else: + for rv in self.iter: + self.current_item = rv + + # This allows show_item_func to be updated before the + # item is processed. Only trigger at the beginning of + # the update interval. + if self._completed_intervals == 0: + self.render_progress() + + yield rv + self.update(1) + + self.finish() + self.render_progress() + + +def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None: + """Decide what method to use for paging through text.""" + stdout = _default_text_stdout() + if not isatty(sys.stdin) or not isatty(stdout): + return _nullpager(stdout, generator, color) + pager_cmd = (os.environ.get("PAGER", None) or "").strip() + if pager_cmd: + if WIN: + return _tempfilepager(generator, pager_cmd, color) + return _pipepager(generator, pager_cmd, color) + if os.environ.get("TERM") in ("dumb", "emacs"): + return _nullpager(stdout, generator, color) + if WIN or sys.platform.startswith("os2"): + return _tempfilepager(generator, "more <", color) + if hasattr(os, "system") and os.system("(less) 2>/dev/null") == 0: + return _pipepager(generator, "less", color) + + import tempfile + + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if hasattr(os, "system") and os.system(f'more "{filename}"') == 0: + return _pipepager(generator, "more", color) + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> None: + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + """ + import subprocess + + env = dict(os.environ) + + # If we're piping to less we might support colors under the + # condition that + cmd_detail = cmd.rsplit("/", 1)[-1].split() + if color is None and cmd_detail[0] == "less": + less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}" + if not less_flags: + env["LESS"] = "-R" + color = True + elif "r" in less_flags or "R" in less_flags: + color = True + + c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, env=env) + stdin = t.cast(t.BinaryIO, c.stdin) + encoding = get_best_encoding(stdin) + try: + for text in generator: + if not color: + text = strip_ansi(text) + + stdin.write(text.encode(encoding, "replace")) + except (OSError, KeyboardInterrupt): + pass + else: + stdin.close() + + # Less doesn't respect ^C, but catches it for its own UI purposes (aborting + # search or other commands inside less). + # + # That means when the user hits ^C, the parent process (click) terminates, + # but less is still alive, paging the output and messing up the terminal. + # + # If the user wants to make the pager exit on ^C, they should set + # `LESS='-K'`. It's not our decision to make. + while True: + try: + c.wait() + except KeyboardInterrupt: + pass + else: + break + + +def _tempfilepager( + generator: t.Iterable[str], cmd: str, color: t.Optional[bool] +) -> None: + """Page through text by invoking a program on a temporary file.""" + import tempfile + + _, 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.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) + ) + + def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]: + import tempfile + + if not text: + data = b"" + elif isinstance(text, (bytes, bytearray)): + data = text + else: + if text and not text.endswith("\n"): + text += "\n" + + if WIN: + data = text.replace("\n", "\r\n").encode("utf-8-sig") + else: + data = text.encode("utf-8") + + fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension) + f: t.BinaryIO + + try: + with os.fdopen(fd, "wb") as f: + f.write(data) + + # If the filesystem resolution is 1 second, like Mac OS + # 10.12 Extended, or 2 seconds, like FAT32, and the editor + # closes very fast, require_save can fail. Set the modified + # time to be 2 seconds in the past to work around this. + os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2)) + # Depending on the resolution, the exact value might not be + # recorded, so get the new recorded value. + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save and os.path.getmtime(name) == timestamp: + return None + + with open(name, "rb") as f: + rv = f.read() + + if isinstance(text, (bytes, bytearray)): + return rv + + return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore + finally: + os.unlink(name) + + +def open_url(url: str, wait: bool = False, locate: bool = False) -> int: + import subprocess + + def _unquote_file(url: str) -> str: + from urllib.parse import unquote + + if url.startswith("file://"): + url = unquote(url[7:]) + + return url + + if sys.platform == "darwin": + args = ["open"] + if wait: + args.append("-W") + if locate: + args.append("-R") + args.append(_unquote_file(url)) + null = open("/dev/null", "w") + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url.replace('"', "")) + args = f'explorer /select,"{url}"' + else: + url = url.replace('"', "") + wait_str = "/WAIT" if wait else "" + args = f'start {wait_str} "" "{url}"' + return os.system(args) + elif CYGWIN: + if locate: + url = os.path.dirname(_unquote_file(url).replace('"', "")) + args = f'cygstart "{url}"' + else: + url = url.replace('"', "") + wait_str = "-w" if wait else "" + args = f'cygstart {wait_str} "{url}"' + return os.system(args) + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or "." + else: + url = _unquote_file(url) + c = subprocess.Popen(["xdg-open", url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(("http://", "https://")) and not locate and not wait: + import webbrowser + + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]: + if ch == "\x03": + raise KeyboardInterrupt() + + if ch == "\x04" and not WIN: # Unix-like, Ctrl+D + raise EOFError() + + if ch == "\x1a" and WIN: # Windows, Ctrl+Z + raise EOFError() + + return None + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + yield -1 + + def getchar(echo: bool) -> str: + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + func: t.Callable[[], str] + + if echo: + func = msvcrt.getwche # type: ignore + else: + func = msvcrt.getwch # type: ignore + + rv = func() + + if rv in ("\x00", "\xe0"): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + + _translate_ch_to_exc(rv) + return rv + + +else: + import tty + import termios + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + f: t.Optional[t.TextIO] + fd: int + + if not isatty(sys.stdin): + f = open("/dev/tty") + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + + try: + old_settings = termios.tcgetattr(fd) + + try: + tty.setraw(fd) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo: bool) -> str: + with raw_terminal() as fd: + ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace") + + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + + _translate_ch_to_exc(ch) + return ch diff --git a/venv/lib/python3.9/site-packages/click/_textwrap.py b/venv/lib/python3.9/site-packages/click/_textwrap.py new file mode 100644 index 0000000..b47dcbd --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/_textwrap.py @@ -0,0 +1,49 @@ +import textwrap +import typing as t +from contextlib import contextmanager + + +class TextWrapper(textwrap.TextWrapper): + def _handle_long_word( + self, + reversed_chunks: t.List[str], + cur_line: t.List[str], + cur_len: int, + width: int, + ) -> None: + space_left = max(width - cur_len, 1) + + if self.break_long_words: + last = reversed_chunks[-1] + cut = last[:space_left] + res = last[space_left:] + cur_line.append(cut) + reversed_chunks[-1] = res + elif not cur_line: + cur_line.append(reversed_chunks.pop()) + + @contextmanager + def extra_indent(self, indent: str) -> t.Iterator[None]: + old_initial_indent = self.initial_indent + old_subsequent_indent = self.subsequent_indent + self.initial_indent += indent + self.subsequent_indent += indent + + try: + yield + finally: + self.initial_indent = old_initial_indent + self.subsequent_indent = old_subsequent_indent + + def indent_only(self, text: str) -> str: + rv = [] + + for idx, line in enumerate(text.splitlines()): + indent = self.initial_indent + + if idx > 0: + indent = self.subsequent_indent + + rv.append(f"{indent}{line}") + + return "\n".join(rv) diff --git a/venv/lib/python3.9/site-packages/click/_unicodefun.py b/venv/lib/python3.9/site-packages/click/_unicodefun.py new file mode 100644 index 0000000..9cb30c3 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/_unicodefun.py @@ -0,0 +1,100 @@ +import codecs +import os +from gettext import gettext as _ + + +def _verify_python_env() -> None: + """Ensures that the environment is good for Unicode.""" + try: + from locale import getpreferredencoding + + fs_enc = codecs.lookup(getpreferredencoding()).name + except Exception: + fs_enc = "ascii" + + if fs_enc != "ascii": + return + + extra = [ + _( + "Click will abort further execution because Python was" + " configured to use ASCII as encoding for the environment." + " Consult https://click.palletsprojects.com/unicode-support/" + " for mitigation steps." + ) + ] + + if os.name == "posix": + import subprocess + + try: + rv = subprocess.Popen( + ["locale", "-a"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + encoding="ascii", + errors="replace", + ).communicate()[0] + except OSError: + rv = "" + + good_locales = set() + has_c_utf8 = False + + for line in rv.splitlines(): + locale = line.strip() + + if locale.lower().endswith((".utf-8", ".utf8")): + good_locales.add(locale) + + if locale.lower() in ("c.utf8", "c.utf-8"): + has_c_utf8 = True + + if not good_locales: + extra.append( + _( + "Additional information: on this system no suitable" + " UTF-8 locales were discovered. This most likely" + " requires resolving by reconfiguring the locale" + " system." + ) + ) + elif has_c_utf8: + extra.append( + _( + "This system supports the C.UTF-8 locale which is" + " recommended. You might be able to resolve your" + " issue by exporting the following environment" + " variables:" + ) + ) + extra.append(" export LC_ALL=C.UTF-8\n export LANG=C.UTF-8") + else: + extra.append( + _( + "This system lists some UTF-8 supporting locales" + " that you can pick from. The following suitable" + " locales were discovered: {locales}" + ).format(locales=", ".join(sorted(good_locales))) + ) + + bad_locale = None + + for env_locale in os.environ.get("LC_ALL"), os.environ.get("LANG"): + if env_locale and env_locale.lower().endswith((".utf-8", ".utf8")): + bad_locale = env_locale + + if env_locale is not None: + break + + if bad_locale is not None: + extra.append( + _( + "Click discovered that you exported a UTF-8 locale" + " but the locale system could not pick up from it" + " because it does not exist. The exported locale is" + " {locale!r} but it is not supported." + ).format(locale=bad_locale) + ) + + raise RuntimeError("\n\n".join(extra)) diff --git a/venv/lib/python3.9/site-packages/click/_winconsole.py b/venv/lib/python3.9/site-packages/click/_winconsole.py new file mode 100644 index 0000000..6b20df3 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/_winconsole.py @@ -0,0 +1,279 @@ +# This module is based on the excellent work by Adam Bartoš who +# provided a lot of what went into the implementation here in +# the discussion to issue1602 in the Python bug tracker. +# +# There are some general differences in regards to how this works +# compared to the original patches as we do not need to patch +# the entire interpreter but just work in our little world of +# echo and prompt. +import io +import sys +import time +import typing as t +from ctypes import byref +from ctypes import c_char +from ctypes import c_char_p +from ctypes import c_int +from ctypes import c_ssize_t +from ctypes import c_ulong +from ctypes import c_void_p +from ctypes import POINTER +from ctypes import py_object +from ctypes import Structure +from ctypes.wintypes import DWORD +from ctypes.wintypes import HANDLE +from ctypes.wintypes import LPCWSTR +from ctypes.wintypes import LPWSTR + +from ._compat import _NonClosingTextIOWrapper + +assert sys.platform == "win32" +import msvcrt # noqa: E402 +from ctypes import windll # noqa: E402 +from ctypes import WINFUNCTYPE # noqa: E402 + +c_ssize_p = POINTER(c_ssize_t) + +kernel32 = windll.kernel32 +GetStdHandle = kernel32.GetStdHandle +ReadConsoleW = kernel32.ReadConsoleW +WriteConsoleW = kernel32.WriteConsoleW +GetConsoleMode = kernel32.GetConsoleMode +GetLastError = kernel32.GetLastError +GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32)) +CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))( + ("CommandLineToArgvW", windll.shell32) +) +LocalFree = WINFUNCTYPE(c_void_p, c_void_p)(("LocalFree", windll.kernel32)) + +STDIN_HANDLE = GetStdHandle(-10) +STDOUT_HANDLE = GetStdHandle(-11) +STDERR_HANDLE = GetStdHandle(-12) + +PyBUF_SIMPLE = 0 +PyBUF_WRITABLE = 1 + +ERROR_SUCCESS = 0 +ERROR_NOT_ENOUGH_MEMORY = 8 +ERROR_OPERATION_ABORTED = 995 + +STDIN_FILENO = 0 +STDOUT_FILENO = 1 +STDERR_FILENO = 2 + +EOF = b"\x1a" +MAX_BYTES_WRITTEN = 32767 + +try: + from ctypes import pythonapi +except ImportError: + # On PyPy we cannot get buffers so our ability to operate here is + # severely limited. + get_buffer = None +else: + + class Py_buffer(Structure): + _fields_ = [ + ("buf", c_void_p), + ("obj", py_object), + ("len", c_ssize_t), + ("itemsize", c_ssize_t), + ("readonly", c_int), + ("ndim", c_int), + ("format", c_char_p), + ("shape", c_ssize_p), + ("strides", c_ssize_p), + ("suboffsets", c_ssize_p), + ("internal", c_void_p), + ] + + PyObject_GetBuffer = pythonapi.PyObject_GetBuffer + PyBuffer_Release = pythonapi.PyBuffer_Release + + def get_buffer(obj, writable=False): + buf = Py_buffer() + flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE + PyObject_GetBuffer(py_object(obj), byref(buf), flags) + + try: + buffer_type = c_char * buf.len + return buffer_type.from_address(buf.buf) + finally: + PyBuffer_Release(byref(buf)) + + +class _WindowsConsoleRawIOBase(io.RawIOBase): + def __init__(self, handle): + self.handle = handle + + def isatty(self): + super().isatty() + return True + + +class _WindowsConsoleReader(_WindowsConsoleRawIOBase): + def readable(self): + return True + + def readinto(self, b): + bytes_to_be_read = len(b) + if not bytes_to_be_read: + return 0 + elif bytes_to_be_read % 2: + raise ValueError( + "cannot read odd number of bytes from UTF-16-LE encoded console" + ) + + buffer = get_buffer(b, writable=True) + code_units_to_be_read = bytes_to_be_read // 2 + code_units_read = c_ulong() + + rv = ReadConsoleW( + HANDLE(self.handle), + buffer, + code_units_to_be_read, + byref(code_units_read), + None, + ) + if GetLastError() == ERROR_OPERATION_ABORTED: + # wait for KeyboardInterrupt + time.sleep(0.1) + if not rv: + raise OSError(f"Windows error: {GetLastError()}") + + if buffer[0] == EOF: + return 0 + return 2 * code_units_read.value + + +class _WindowsConsoleWriter(_WindowsConsoleRawIOBase): + def writable(self): + return True + + @staticmethod + def _get_error_message(errno): + if errno == ERROR_SUCCESS: + return "ERROR_SUCCESS" + elif errno == ERROR_NOT_ENOUGH_MEMORY: + return "ERROR_NOT_ENOUGH_MEMORY" + return f"Windows error {errno}" + + def write(self, b): + bytes_to_be_written = len(b) + buf = get_buffer(b) + code_units_to_be_written = min(bytes_to_be_written, MAX_BYTES_WRITTEN) // 2 + code_units_written = c_ulong() + + WriteConsoleW( + HANDLE(self.handle), + buf, + code_units_to_be_written, + byref(code_units_written), + None, + ) + bytes_written = 2 * code_units_written.value + + if bytes_written == 0 and bytes_to_be_written > 0: + raise OSError(self._get_error_message(GetLastError())) + return bytes_written + + +class ConsoleStream: + def __init__(self, text_stream: t.TextIO, byte_stream: t.BinaryIO) -> None: + self._text_stream = text_stream + self.buffer = byte_stream + + @property + def name(self) -> str: + return self.buffer.name + + def write(self, x: t.AnyStr) -> int: + if isinstance(x, str): + return self._text_stream.write(x) + try: + self.flush() + except Exception: + pass + return self.buffer.write(x) + + def writelines(self, lines: t.Iterable[t.AnyStr]) -> None: + for line in lines: + self.write(line) + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._text_stream, name) + + def isatty(self) -> bool: + return self.buffer.isatty() + + def __repr__(self): + return f"" + + +def _get_text_stdin(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stdout(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stderr(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +_stream_factories: t.Mapping[int, t.Callable[[t.BinaryIO], t.TextIO]] = { + 0: _get_text_stdin, + 1: _get_text_stdout, + 2: _get_text_stderr, +} + + +def _is_console(f: t.TextIO) -> bool: + if not hasattr(f, "fileno"): + return False + + try: + fileno = f.fileno() + except (OSError, io.UnsupportedOperation): + return False + + handle = msvcrt.get_osfhandle(fileno) + return bool(GetConsoleMode(handle, byref(DWORD()))) + + +def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> t.Optional[t.TextIO]: + if ( + get_buffer is not None + and encoding in {"utf-16-le", None} + and errors in {"strict", None} + and _is_console(f) + ): + func = _stream_factories.get(f.fileno()) + if func is not None: + b = getattr(f, "buffer", None) + + if b is None: + return None + + return func(b) diff --git a/venv/lib/python3.9/site-packages/click/core.py b/venv/lib/python3.9/site-packages/click/core.py new file mode 100644 index 0000000..e2ccf59 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/core.py @@ -0,0 +1,2957 @@ +import enum +import errno +import os +import sys +import typing +import typing as t +from collections import abc +from contextlib import contextmanager +from contextlib import ExitStack +from functools import partial +from functools import update_wrapper +from gettext import gettext as _ +from gettext import ngettext +from itertools import repeat + +from . import types +from ._unicodefun import _verify_python_env +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 _fast_exit(code: int) -> "te.NoReturn": + """Low-level exit that skips Python's cleanup but speeds up exit by + about 10ms for things like shell completion. + + :param code: Exit code. + """ + sys.stdout.flush() + sys.stderr.flush() + os._exit(code) + + +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 defaults for all options. If not set, + defaults to the value from a parent context. Overrides an + option's ``show_default`` argument. + + .. versionchanged:: 8.0 + The ``show_default`` parameter defaults to the value from the + parent context. + + .. versionchanged:: 7.1 + Added the ``show_default`` parameter. + + .. versionchanged:: 4.0 + Added the ``color``, ``ignore_unknown_options``, and + ``max_content_width`` parameters. + + .. versionchanged:: 3.0 + Added the ``allow_extra_args`` and ``allow_interspersed_args`` + parameters. + + .. versionchanged:: 2.0 + Added the ``resilient_parsing``, ``help_option_names``, and + ``token_normalize_func`` parameters. + """ + + #: The formatter class to create with :meth:`make_formatter`. + #: + #: .. versionadded:: 8.0 + formatter_class: t.Type["HelpFormatter"] = HelpFormatter + + def __init__( + self, + command: "Command", + parent: t.Optional["Context"] = None, + info_name: t.Optional[str] = None, + obj: t.Optional[t.Any] = None, + auto_envvar_prefix: t.Optional[str] = None, + default_map: t.Optional[t.Dict[str, t.Any]] = None, + terminal_width: t.Optional[int] = None, + max_content_width: t.Optional[int] = None, + resilient_parsing: bool = False, + allow_extra_args: t.Optional[bool] = None, + allow_interspersed_args: t.Optional[bool] = None, + ignore_unknown_options: t.Optional[bool] = None, + help_option_names: t.Optional[t.List[str]] = None, + token_normalize_func: t.Optional[t.Callable[[str], str]] = None, + color: t.Optional[bool] = None, + show_default: t.Optional[bool] = None, + ) -> None: + #: the parent context or `None` if none exists. + self.parent = parent + #: the :class:`Command` for this context. + self.command = command + #: the descriptive information name + self.info_name = info_name + #: Map of parameter names to their parsed values. Parameters + #: with ``expose_value=False`` are not stored. + self.params: t.Dict[str, t.Any] = {} + #: the leftover arguments. + self.args: t.List[str] = [] + #: protected arguments. These are arguments that are prepended + #: to `args` when certain parsing scenarios are encountered but + #: must be never propagated to another arguments. This is used + #: to implement nested parsing. + self.protected_args: t.List[str] = [] + + if obj is None and parent is not None: + obj = parent.obj + + #: the user object stored. + self.obj: t.Any = obj + self._meta: t.Dict[str, t.Any] = getattr(parent, "meta", {}) + + #: A dictionary (-like object) with defaults for parameters. + if ( + default_map is None + and info_name is not None + and parent is not None + and parent.default_map is not None + ): + default_map = parent.default_map.get(info_name) + + self.default_map: t.Optional[t.Dict[str, t.Any]] = default_map + + #: This flag indicates if a subcommand is going to be executed. A + #: group callback can use this information to figure out if it's + #: being executed directly or because the execution flow passes + #: onwards to a subcommand. By default it's None, but it can be + #: the name of the subcommand to execute. + #: + #: If chaining is enabled this will be set to ``'*'`` in case + #: any commands are executed. It is however not possible to + #: figure out which ones. If you require this knowledge you + #: should use a :func:`result_callback`. + self.invoked_subcommand: t.Optional[str] = None + + if terminal_width is None and parent is not None: + terminal_width = parent.terminal_width + + #: The width of the terminal (None is autodetection). + self.terminal_width: t.Optional[int] = terminal_width + + if max_content_width is None and parent is not None: + max_content_width = parent.max_content_width + + #: The maximum width of formatted content (None implies a sensible + #: default which is 80 for most things). + self.max_content_width: t.Optional[int] = max_content_width + + if allow_extra_args is None: + allow_extra_args = command.allow_extra_args + + #: Indicates if the context allows extra args or if it should + #: fail on parsing. + #: + #: .. versionadded:: 3.0 + self.allow_extra_args = allow_extra_args + + if allow_interspersed_args is None: + allow_interspersed_args = command.allow_interspersed_args + + #: Indicates if the context allows mixing of arguments and + #: options or not. + #: + #: .. versionadded:: 3.0 + self.allow_interspersed_args: bool = allow_interspersed_args + + if ignore_unknown_options is None: + ignore_unknown_options = command.ignore_unknown_options + + #: Instructs click to ignore options that a command does not + #: understand and will store it on the context for later + #: processing. This is primarily useful for situations where you + #: want to call into external programs. Generally this pattern is + #: strongly discouraged because it's not possibly to losslessly + #: forward all arguments. + #: + #: .. versionadded:: 4.0 + self.ignore_unknown_options: bool = ignore_unknown_options + + if help_option_names is None: + if parent is not None: + help_option_names = parent.help_option_names + else: + help_option_names = ["--help"] + + #: The names for the help options. + self.help_option_names: t.List[str] = help_option_names + + if token_normalize_func is None and parent is not None: + token_normalize_func = parent.token_normalize_func + + #: An optional normalization function for tokens. This is + #: options, choices, commands etc. + self.token_normalize_func: t.Optional[ + t.Callable[[str], str] + ] = token_normalize_func + + #: Indicates if resilient parsing is enabled. In that case Click + #: will do its best to not cause any failures and default values + #: will be ignored. Useful for completion. + self.resilient_parsing: bool = resilient_parsing + + # If there is no envvar prefix yet, but the parent has one and + # the command on this level has a name, we can expand the envvar + # prefix automatically. + if auto_envvar_prefix is None: + if ( + parent is not None + and parent.auto_envvar_prefix is not None + and self.info_name is not None + ): + auto_envvar_prefix = ( + f"{parent.auto_envvar_prefix}_{self.info_name.upper()}" + ) + else: + auto_envvar_prefix = auto_envvar_prefix.upper() + + if auto_envvar_prefix is not None: + auto_envvar_prefix = auto_envvar_prefix.replace("-", "_") + + self.auto_envvar_prefix: t.Optional[str] = auto_envvar_prefix + + if color is None and parent is not None: + color = parent.color + + #: Controls if styling output is wanted or not. + self.color: t.Optional[bool] = color + + if show_default is None and parent is not None: + show_default = parent.show_default + + #: Show option default values when formatting help text. + self.show_default: t.Optional[bool] = show_default + + self._close_callbacks: t.List[t.Callable[[], t.Any]] = [] + self._depth = 0 + self._parameter_source: t.Dict[str, ParameterSource] = {} + self._exit_stack = ExitStack() + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire CLI + structure. + + .. code-block:: python + + with Context(cli) as ctx: + info = ctx.to_info_dict() + + .. versionadded:: 8.0 + """ + return { + "command": self.command.to_info_dict(self), + "info_name": self.info_name, + "allow_extra_args": self.allow_extra_args, + "allow_interspersed_args": self.allow_interspersed_args, + "ignore_unknown_options": self.ignore_unknown_options, + "auto_envvar_prefix": self.auto_envvar_prefix, + } + + def __enter__(self) -> "Context": + self._depth += 1 + push_context(self) + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self._depth -= 1 + if self._depth == 0: + self.close() + pop_context() + + @contextmanager + def scope(self, cleanup: bool = True) -> t.Iterator["Context"]: + """This helper method can be used with the context object to promote + it to the current thread local (see :func:`get_current_context`). + The default behavior of this is to invoke the cleanup functions which + can be disabled by setting `cleanup` to `False`. The cleanup + functions are typically used for things such as closing file handles. + + If the cleanup is intended the context object can also be directly + used as a context manager. + + Example usage:: + + with ctx.scope(): + assert get_current_context() is ctx + + This is equivalent:: + + with ctx: + assert get_current_context() is ctx + + .. versionadded:: 5.0 + + :param cleanup: controls if the cleanup functions should be run or + not. The default is to run these functions. In + some situations the context only wants to be + temporarily pushed in which case this can be disabled. + Nested pushes automatically defer the cleanup. + """ + if not cleanup: + self._depth += 1 + try: + with self as rv: + yield rv + finally: + if not cleanup: + self._depth -= 1 + + @property + def meta(self) -> t.Dict[str, t.Any]: + """This is a dictionary which is shared with all the contexts + that are nested. It exists so that click utilities can store some + state here if they need to. It is however the responsibility of + that code to manage this dictionary well. + + The keys are supposed to be unique dotted strings. For instance + module paths are a good choice for it. What is stored in there is + irrelevant for the operation of click. However what is important is + that code that places data here adheres to the general semantics of + the system. + + Example usage:: + + LANG_KEY = f'{__name__}.lang' + + def set_language(value): + ctx = get_current_context() + ctx.meta[LANG_KEY] = value + + def get_language(): + return get_current_context().meta.get(LANG_KEY, 'en_US') + + .. versionadded:: 5.0 + """ + return self._meta + + def make_formatter(self) -> HelpFormatter: + """Creates the :class:`~click.HelpFormatter` for the help and + usage output. + + To quickly customize the formatter class used without overriding + this method, set the :attr:`formatter_class` attribute. + + .. versionchanged:: 8.0 + Added the :attr:`formatter_class` attribute. + """ + return self.formatter_class( + width=self.terminal_width, max_width=self.max_content_width + ) + + def with_resource(self, context_manager: t.ContextManager[V]) -> V: + """Register a resource as if it were used in a ``with`` + statement. The resource will be cleaned up when the context is + popped. + + Uses :meth:`contextlib.ExitStack.enter_context`. It calls the + resource's ``__enter__()`` method and returns the result. When + the context is popped, it closes the stack, which calls the + resource's ``__exit__()`` method. + + To register a cleanup function for something that isn't a + context manager, use :meth:`call_on_close`. Or use something + from :mod:`contextlib` to turn it into a context manager first. + + .. code-block:: python + + @click.group() + @click.option("--name") + @click.pass_context + def cli(ctx): + ctx.obj = ctx.with_resource(connect_db(name)) + + :param context_manager: The context manager to enter. + :return: Whatever ``context_manager.__enter__()`` returns. + + .. versionadded:: 8.0 + """ + return self._exit_stack.enter_context(context_manager) + + def call_on_close(self, f: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]: + """Register a function to be called when the context tears down. + + This can be used to close resources opened during the script + execution. Resources that support Python's context manager + protocol which would be used in a ``with`` statement should be + registered with :meth:`with_resource` instead. + + :param f: The function to execute on teardown. + """ + return self._exit_stack.callback(f) + + def close(self) -> None: + """Invoke all close callbacks registered with + :meth:`call_on_close`, and exit all context managers entered + with :meth:`with_resource`. + """ + self._exit_stack.close() + # In case the context is reused, create a new exit stack. + self._exit_stack = ExitStack() + + @property + def command_path(self) -> str: + """The computed command path. This is used for the ``usage`` + information on the help page. It's automatically created by + combining the info names of the chain of contexts to the root. + """ + rv = "" + if self.info_name is not None: + rv = self.info_name + if self.parent is not None: + parent_command_path = [self.parent.command_path] + + if isinstance(self.parent.command, Command): + for param in self.parent.command.get_params(self): + parent_command_path.extend(param.get_usage_pieces(self)) + + rv = f"{' '.join(parent_command_path)} {rv}" + return rv.lstrip() + + def find_root(self) -> "Context": + """Finds the outermost context.""" + node = self + while node.parent is not None: + node = node.parent + return node + + def find_object(self, object_type: t.Type[V]) -> t.Optional[V]: + """Finds the closest object of a given type.""" + node: t.Optional["Context"] = self + + while node is not None: + if isinstance(node.obj, object_type): + return node.obj + + node = node.parent + + return None + + def ensure_object(self, object_type: t.Type[V]) -> V: + """Like :meth:`find_object` but sets the innermost object to a + new instance of `object_type` if it does not exist. + """ + rv = self.find_object(object_type) + if rv is None: + self.obj = rv = object_type() + return rv + + @typing.overload + def lookup_default( + self, name: str, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @typing.overload + def lookup_default( + self, name: str, call: "te.Literal[False]" = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def lookup_default(self, name: str, call: bool = True) -> t.Optional[t.Any]: + """Get the default for a parameter from :attr:`default_map`. + + :param name: Name of the parameter. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + if self.default_map is not None: + value = self.default_map.get(name) + + if call and callable(value): + return value() + + return value + + return None + + def fail(self, message: str) -> "te.NoReturn": + """Aborts the execution of the program with a specific error + message. + + :param message: the error message to fail with. + """ + raise UsageError(message, self) + + def abort(self) -> "te.NoReturn": + """Aborts the script.""" + raise Abort() + + def exit(self, code: int = 0) -> "te.NoReturn": + """Exits the application with a given exit code.""" + raise Exit(code) + + def get_usage(self) -> str: + """Helper method to get formatted usage string for the current + context and command. + """ + return self.command.get_usage(self) + + def get_help(self) -> str: + """Helper method to get formatted help page for the current + context and command. + """ + return self.command.get_help(self) + + def _make_sub_context(self, command: "Command") -> "Context": + """Create a new context of the same type as this context, but + for a new command. + + :meta private: + """ + return type(self)(command, info_name=command.name, parent=self) + + def invoke( + __self, # noqa: B902 + __callback: t.Union["Command", t.Callable[..., t.Any]], + *args: t.Any, + **kwargs: t.Any, + ) -> t.Any: + """Invokes a command callback in exactly the way it expects. There + are two ways to invoke this method: + + 1. the first argument can be a callback and all other arguments and + keyword arguments are forwarded directly to the function. + 2. the first argument is a click command object. In that case all + arguments are forwarded as well but proper click parameters + (options and click arguments) must be keyword arguments and Click + will fill in defaults. + + Note that before Click 3.2 keyword arguments were not properly filled + in against the intention of this code and no context was created. For + more information about this change and why it was done in a bugfix + release see :ref:`upgrade-to-3.2`. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if :meth:`forward` is called at multiple levels. + """ + if isinstance(__callback, Command): + other_cmd = __callback + + if other_cmd.callback is None: + raise TypeError( + "The given command does not have a callback that can be invoked." + ) + else: + __callback = other_cmd.callback + + ctx = __self._make_sub_context(other_cmd) + + for param in other_cmd.params: + if param.name not in kwargs and param.expose_value: + kwargs[param.name] = param.get_default(ctx) # type: ignore + + # Track all kwargs as params, so that forward() will pass + # them on in subsequent calls. + ctx.params.update(kwargs) + else: + ctx = __self + + with augment_usage_errors(__self): + with ctx: + return __callback(*args, **kwargs) + + def forward( + __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any # noqa: B902 + ) -> t.Any: + """Similar to :meth:`invoke` but fills in default keyword + arguments from the current context if the other command expects + it. This cannot invoke callbacks directly, only other commands. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if ``forward`` is called at multiple levels. + """ + # Can only forward to other commands, not direct callbacks. + if not isinstance(__cmd, Command): + raise TypeError("Callback is not a command.") + + for param in __self.params: + if param not in kwargs: + kwargs[param] = __self.params[param] + + return __self.invoke(__cmd, *args, **kwargs) + + def set_parameter_source(self, name: str, source: ParameterSource) -> None: + """Set the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + :param name: The name of the parameter. + :param source: A member of :class:`~click.core.ParameterSource`. + """ + self._parameter_source[name] = source + + def get_parameter_source(self, name: str) -> t.Optional[ParameterSource]: + """Get the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + This can be useful for determining when a user specified a value + on the command line that is the same as the default value. It + will be :attr:`~click.core.ParameterSource.DEFAULT` only if the + value was actually taken from the default. + + :param name: The name of the parameter. + :rtype: ParameterSource + + .. versionchanged:: 8.0 + Returns ``None`` if the parameter was not provided from any + source. + """ + return self._parameter_source.get(name) + + +class BaseCommand: + """The base command implements the minimal API contract of commands. + Most code will never use this as it does not implement a lot of useful + functionality but it can act as the direct subclass of alternative + parsing methods that do not depend on the Click parser. + + For instance, this can be used to bridge Click and other systems like + argparse or docopt. + + Because base commands do not implement a lot of the API that other + parts of Click take for granted, they are not supported for all + operations. For instance, they cannot be used with the decorators + usually and they have no built-in callback system. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + """ + + #: The context class to create with :meth:`make_context`. + #: + #: .. versionadded:: 8.0 + context_class: t.Type[Context] = Context + #: the default for the :attr:`Context.allow_extra_args` flag. + allow_extra_args = False + #: the default for the :attr:`Context.allow_interspersed_args` flag. + allow_interspersed_args = True + #: the default for the :attr:`Context.ignore_unknown_options` flag. + ignore_unknown_options = False + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.Dict[str, t.Any]] = None, + ) -> None: + #: the name the command thinks it has. Upon registering a command + #: on a :class:`Group` the group will default the command name + #: with this information. You should instead use the + #: :class:`Context`\'s :attr:`~Context.info_name` attribute. + self.name = name + + if context_settings is None: + context_settings = {} + + #: an optional dictionary with defaults passed to the context. + self.context_settings: t.Dict[str, t.Any] = context_settings + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire structure + below this command. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + :param ctx: A :class:`Context` representing this command. + + .. versionadded:: 8.0 + """ + return {"name": self.name} + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def get_usage(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get usage") + + def get_help(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get help") + + def make_context( + self, + info_name: t.Optional[str], + args: t.List[str], + parent: t.Optional[Context] = None, + **extra: t.Any, + ) -> Context: + """This function when given an info name and arguments will kick + off the parsing and create a new :class:`Context`. It does not + invoke the actual command callback though. + + To quickly customize the context class used without overriding + this method, set the :attr:`context_class` attribute. + + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it's usually + the name of the script, for commands below it it's + the name of the command. + :param args: the arguments to parse as list of strings. + :param parent: the parent context if available. + :param extra: extra keyword arguments forwarded to the context + constructor. + + .. versionchanged:: 8.0 + Added the :attr:`context_class` attribute. + """ + for key, value in self.context_settings.items(): + if key not in extra: + extra[key] = value + + ctx = self.context_class( + self, info_name=info_name, parent=parent, **extra # type: ignore + ) + + with ctx.scope(cleanup=False): + self.parse_args(ctx, args) + return ctx + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + """Given a context and a list of arguments this creates the parser + and parses the arguments, then modifies the context as necessary. + This is automatically invoked by :meth:`make_context`. + """ + raise NotImplementedError("Base commands do not know how to parse arguments.") + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the command. The default + implementation is raising a not implemented error. + """ + raise NotImplementedError("Base commands are not invokable by default") + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of chained multi-commands. + + Any command could be part of a chained multi-command, so sibling + commands are valid at any point during command completion. Other + command classes will return more completions. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + while ctx.parent is not None: + ctx = ctx.parent + + if isinstance(ctx.command, MultiCommand) and ctx.command.chain: + results.extend( + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + if name not in ctx.protected_args + ) + + return results + + @typing.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": + ... + + @typing.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. + """ + # Verify that the environment is configured correctly, or reject + # further execution to avoid a broken script. + _verify_python_env() + + if args is None: + args = sys.argv[1:] + + if os.name == "nt" and windows_expand_args: + args = _expand_args(args) + else: + args = list(args) + + if prog_name is None: + prog_name = _detect_program_name() + + # Process shell completion requests and exit early. + self._main_shell_completion(extra, prog_name, complete_var) + + try: + try: + with self.make_context(prog_name, args, **extra) as ctx: + rv = self.invoke(ctx) + if not standalone_mode: + return rv + # it's not safe to `ctx.exit(rv)` here! + # note that `rv` may actually contain data like "1" which + # has obvious effects + # more subtle case: `rv=[None, None]` can come out of + # chained commands which all returned `None` -- so it's not + # even always obvious that `rv` indicates success/failure + # by its truthiness/falsiness + ctx.exit() + except (EOFError, KeyboardInterrupt): + echo(file=sys.stderr) + raise Abort() + except ClickException as e: + if not standalone_mode: + raise + e.show() + sys.exit(e.exit_code) + except OSError as e: + if e.errno == errno.EPIPE: + sys.stdout = t.cast(t.TextIO, PacifyFlushWrapper(sys.stdout)) + sys.stderr = t.cast(t.TextIO, PacifyFlushWrapper(sys.stderr)) + sys.exit(1) + else: + raise + except Exit as e: + if standalone_mode: + sys.exit(e.exit_code) + else: + # in non-standalone mode, return the exit code + # note that this is only reached if `self.invoke` above raises + # an Exit explicitly -- thus bypassing the check there which + # would return its result + # the results of non-standalone execution may therefore be + # somewhat ambiguous: if there are codepaths which lead to + # `ctx.exit(1)` and to `return 1`, the caller won't be able to + # tell the difference between the two + return e.exit_code + except Abort: + if not standalone_mode: + raise + echo(_("Aborted!"), file=sys.stderr) + sys.exit(1) + + def _main_shell_completion( + self, + ctx_args: t.Dict[str, t.Any], + prog_name: str, + complete_var: t.Optional[str] = None, + ) -> None: + """Check if the shell is asking for tab completion, process + that, then exit early. Called from :meth:`main` before the + program is invoked. + + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. Defaults to + ``_{PROG_NAME}_COMPLETE``. + """ + if complete_var is None: + complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").upper() + + instruction = os.environ.get(complete_var) + + if not instruction: + return + + from .shell_completion import shell_complete + + rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) + _fast_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. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + .. versionchanged:: 8.0 + Added repr showing the command name + .. versionchanged:: 7.1 + Added the `no_args_is_help` 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. + :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. + """ + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.Dict[str, t.Any]] = None, + callback: t.Optional[t.Callable[..., t.Any]] = None, + params: t.Optional[t.List["Parameter"]] = None, + help: t.Optional[str] = None, + epilog: t.Optional[str] = None, + short_help: t.Optional[str] = None, + options_metavar: t.Optional[str] = "[OPTIONS]", + add_help_option: bool = True, + no_args_is_help: bool = False, + hidden: bool = False, + deprecated: bool = False, + ) -> None: + super().__init__(name, context_settings) + #: the callback to execute when the command fires. This might be + #: `None` in which case nothing happens. + self.callback = callback + #: the list of parameters for this command in the order they + #: should show up in the help page and execute. Eager parameters + #: will automatically be handled before non eager ones. + self.params: t.List["Parameter"] = params or [] + + # if a form feed (page break) is found in the help text, truncate help + # text to the content preceding the first form feed + if help and "\f" in help: + help = help.split("\f", 1)[0] + + 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. + """ + text = self.short_help or "" + + if not text and self.help: + text = make_default_short_help(self.help, limit) + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + return text.strip() + + def format_help(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help into the formatter if it exists. + + This is a low-level method called by :meth:`get_help`. + + This calls the following methods: + + - :meth:`format_usage` + - :meth:`format_help_text` + - :meth:`format_options` + - :meth:`format_epilog` + """ + self.format_usage(ctx, formatter) + self.format_help_text(ctx, formatter) + self.format_options(ctx, formatter) + self.format_epilog(ctx, formatter) + + def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help text to the formatter if it exists.""" + text = self.help or "" + + 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: + formatter.write_paragraph() + with formatter.indentation(): + formatter.write_text(self.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 + return args + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the attached callback (if it exists) + in the right way. + """ + if self.deprecated: + message = _( + "DeprecationWarning: The command {name!r} is deprecated." + ).format(name=self.name) + echo(style(message, fg="red"), err=True) + + if self.callback is not None: + return ctx.invoke(self.callback, **ctx.params) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options and chained multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + if incomplete and not incomplete[0].isalnum(): + for param in self.get_params(ctx): + if ( + not isinstance(param, Option) + or param.hidden + or ( + not param.multiple + and ctx.get_parameter_source(param.name) # type: ignore + is ParameterSource.COMMANDLINE + ) + ): + continue + + results.extend( + CompletionItem(name, help=param.help) + for name in [*param.opts, *param.secondary_opts] + if name.startswith(incomplete) + ) + + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class MultiCommand(Command): + """A multi command is the basic implementation of a command that + dispatches to subcommands. The most common version is the + :class:`Group`. + + :param invoke_without_command: this controls how the multi command itself + is invoked. By default it's only invoked + if a subcommand is provided. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is enabled by default if + `invoke_without_command` is disabled or disabled + if it's enabled. If enabled this will add + ``--help`` as argument if no arguments are + passed. + :param subcommand_metavar: the string that is used in the documentation + to indicate the subcommand place. + :param chain: if this is set to `True` chaining of multiple subcommands + is enabled. This restricts the form of commands in that + they cannot have optional arguments but it allows + multiple commands to be chained together. + :param result_callback: The result callback to attach to this multi + command. This can be set or changed later with the + :meth:`result_callback` decorator. + """ + + allow_extra_args = True + allow_interspersed_args = False + + def __init__( + self, + name: t.Optional[str] = None, + invoke_without_command: bool = False, + no_args_is_help: t.Optional[bool] = None, + subcommand_metavar: t.Optional[str] = None, + chain: bool = False, + result_callback: t.Optional[t.Callable[..., t.Any]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if no_args_is_help is None: + no_args_is_help = not invoke_without_command + + self.no_args_is_help = no_args_is_help + self.invoke_without_command = invoke_without_command + + if subcommand_metavar is None: + if chain: + subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..." + else: + subcommand_metavar = "COMMAND [ARGS]..." + + self.subcommand_metavar = subcommand_metavar + self.chain = chain + # The result callback that is stored. This can be set or + # overridden with the :func:`result_callback` decorator. + self._result_callback = result_callback + + if self.chain: + for param in self.params: + if isinstance(param, Argument) and not param.required: + raise RuntimeError( + "Multi commands in chain mode cannot have" + " optional arguments." + ) + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + commands = {} + + for name in self.list_commands(ctx): + command = self.get_command(ctx, name) + + if command is None: + continue + + sub_ctx = ctx._make_sub_context(command) + + with sub_ctx.scope(cleanup=False): + commands[name] = command.to_info_dict(sub_ctx) + + info_dict.update(commands=commands, chain=self.chain) + return info_dict + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + rv = super().collect_usage_pieces(ctx) + rv.append(self.subcommand_metavar) + return rv + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + super().format_options(ctx, formatter) + self.format_commands(ctx, formatter) + + def result_callback(self, replace: bool = False) -> t.Callable[[F], F]: + """Adds a result callback to the command. By default if a + result callback is already registered this will chain them but + this can be disabled with the `replace` parameter. The result + callback is invoked with the return value of the subcommand + (or the list of return values from all subcommands if chaining + is enabled) as well as the parameters as they would be passed + to the main callback. + + Example:: + + @click.group() + @click.option('-i', '--input', default=23) + def cli(input): + return 42 + + @cli.result_callback() + def process_result(result, input): + return result + input + + :param replace: if set to `True` an already existing result + callback will be removed. + + .. versionchanged:: 8.0 + Renamed from ``resultcallback``. + + .. versionadded:: 3.0 + """ + + def decorator(f: F) -> F: + old_callback = self._result_callback + + if old_callback is None or replace: + self._result_callback = f + return f + + def function(__value, *args, **kwargs): # type: ignore + inner = old_callback(__value, *args, **kwargs) # type: ignore + return f(inner, *args, **kwargs) + + self._result_callback = rv = update_wrapper(t.cast(F, function), f) + return rv + + return decorator + + def resultcallback(self, replace: bool = False) -> t.Callable[[F], F]: + import warnings + + warnings.warn( + "'resultcallback' has been renamed to 'result_callback'." + " The old name will be removed in Click 8.1.", + DeprecationWarning, + stacklevel=2, + ) + return self.result_callback(replace=replace) + + 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 None for regular groups, or an empty list + # for chained groups. + with ctx: + super().invoke(ctx) + return _process_result([] if self.chain else None) + ctx.fail(_("Missing command.")) + + # Fetch args back out + args = [*ctx.protected_args, *ctx.args] + ctx.args = [] + ctx.protected_args = [] + + # If we're not in chain mode, we only allow the invocation of a + # single command but we also inform the current context about the + # name of the command to invoke. + if not self.chain: + # Make sure the context is entered so we do not clean up + # resources until the result processor has worked. + with ctx: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + ctx.invoked_subcommand = cmd_name + super().invoke(ctx) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) + with sub_ctx: + return _process_result(sub_ctx.command.invoke(sub_ctx)) + + # In chain mode we create the contexts step by step, but after the + # base command has been invoked. Because at that point we do not + # know the subcommands yet, the invoked subcommand attribute is + # set to ``*`` to inform the command that subcommands are executed + # but nothing else. + with ctx: + ctx.invoked_subcommand = "*" if args else None + super().invoke(ctx) + + # Otherwise we make every single context and invoke them in a + # chain. In that case the return value to the result processor + # is the list of all invoked subcommand's results. + contexts = [] + while args: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + sub_ctx = cmd.make_context( + cmd_name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + ) + contexts.append(sub_ctx) + args, sub_ctx.args = sub_ctx.args, [] + + rv = [] + for sub_ctx in contexts: + with sub_ctx: + rv.append(sub_ctx.command.invoke(sub_ctx)) + return _process_result(rv) + + def resolve_command( + self, ctx: Context, args: t.List[str] + ) -> t.Tuple[t.Optional[str], t.Optional[Command], t.List[str]]: + cmd_name = make_str(args[0]) + original_cmd_name = cmd_name + + # Get the command + cmd = self.get_command(ctx, cmd_name) + + # If we can't find the command but there is a normalization + # function available, we try with that one. + if cmd is None and ctx.token_normalize_func is not None: + cmd_name = ctx.token_normalize_func(cmd_name) + cmd = self.get_command(ctx, cmd_name) + + # If we don't find the command we want to show an error message + # to the user that it was not provided. However, there is + # something else we should do: if the first argument looks like + # an option we want to kick off parsing again for arguments to + # resolve things like --help which now should go to the main + # place. + if cmd is None and not ctx.resilient_parsing: + if split_opt(cmd_name)[0]: + self.parse_args(ctx, ctx.args) + ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name)) + return cmd_name if cmd else None, cmd, args[1:] + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + """Given a context and a command name, this returns a + :class:`Command` object if it exists or returns `None`. + """ + raise NotImplementedError + + def list_commands(self, ctx: Context) -> t.List[str]: + """Returns a list of subcommand names in the order they should + appear. + """ + return [] + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options, subcommands, and chained + multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results = [ + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + ] + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class Group(MultiCommand): + """A group allows a command to have subcommands attached. This is + the most common way to implement nesting in Click. + + :param name: The name of the group command. + :param commands: A dict mapping names to :class:`Command` objects. + Can also be a list of :class:`Command`, which will use + :attr:`Command.name` to create the dict. + :param attrs: Other command arguments described in + :class:`MultiCommand`, :class:`Command`, and + :class:`BaseCommand`. + + .. versionchanged:: 8.0 + The ``commmands`` argument can be a list of command objects. + """ + + #: If set, this is used by the group's :meth:`command` decorator + #: as the default :class:`Command` class. This is useful to make all + #: subcommands use a custom command class. + #: + #: .. versionadded:: 8.0 + command_class: t.Optional[t.Type[Command]] = None + + #: If set, this is used by the group's :meth:`group` decorator + #: as the default :class:`Group` class. This is useful to make all + #: subgroups use a custom group class. + #: + #: If set to the special value :class:`type` (literally + #: ``group_class = type``), this group's class will be used as the + #: default class. This makes a custom group class continue to make + #: custom groups. + #: + #: .. versionadded:: 8.0 + group_class: t.Optional[t.Union[t.Type["Group"], t.Type[type]]] = None + # Literal[type] isn't valid, so use Type[type] + + def __init__( + self, + name: t.Optional[str] = None, + commands: t.Optional[t.Union[t.Dict[str, Command], t.Sequence[Command]]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if commands is None: + commands = {} + elif isinstance(commands, abc.Sequence): + commands = {c.name: c for c in commands if c.name is not None} + + #: The registered subcommands by their exported names. + self.commands: t.Dict[str, Command] = commands + + def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: + """Registers another :class:`Command` with this group. If the name + is not provided, the name of the command is used. + """ + name = name or cmd.name + if name is None: + raise TypeError("Command has no name.") + _check_multicommand(self, name, cmd, register=True) + self.commands[name] = cmd + + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], 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.0 + Added the :attr:`command_class` attribute. + """ + from .decorators import command + + if self.command_class is not None and "cls" not in kwargs: + kwargs["cls"] = self.command_class + + def decorator(f: t.Callable[..., t.Any]) -> Command: + cmd = command(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + return decorator + + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], "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.0 + Added the :attr:`group_class` attribute. + """ + from .decorators import group + + if self.group_class is not None and "cls" not in kwargs: + 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(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + return decorator + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + return self.commands.get(cmd_name) + + def list_commands(self, ctx: Context) -> t.List[str]: + return sorted(self.commands) + + +class CommandCollection(MultiCommand): + """A command collection is a multi command that merges multiple multi + commands together into one. This is a straightforward implementation + that accepts a list of different multi commands as sources and + provides all the commands for each of them. + """ + + def __init__( + self, + name: t.Optional[str] = None, + sources: t.Optional[t.List[MultiCommand]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + #: The list of registered multi commands. + self.sources: t.List[MultiCommand] = sources or [] + + def add_source(self, multi_cmd: MultiCommand) -> None: + """Adds a new multi command to the chain dispatcher.""" + self.sources.append(multi_cmd) + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + for source in self.sources: + rv = source.get_command(ctx, cmd_name) + + if rv is not None: + if self.chain: + _check_multicommand(self, cmd_name, rv) + + return rv + + return None + + def list_commands(self, ctx: Context) -> t.List[str]: + rv: t.Set[str] = set() + + for source in self.sources: + rv.update(source.list_commands(ctx)) + + return sorted(rv) + + +def _check_iter(value: t.Any) -> t.Iterator[t.Any]: + """Check if the value is iterable but not a string. Raises a type + error, or return an iterator over the value. + """ + if isinstance(value, str): + raise TypeError + + return iter(value) + + +class Parameter: + r"""A parameter to a command comes in two versions: they are either + :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently + not supported by design as some of the internals for parsing are + intentionally not finalized. + + Some settings are supported by both options and arguments. + + :param param_decls: the parameter declarations for this option or + argument. This is a list of flags or argument + names. + :param type: the type that should be used. Either a :class:`ParamType` + or a Python type. The later is converted into the former + automatically if supported. + :param required: controls if this is optional or not. + :param default: the default value if omitted. This can also be a callable, + in which case it's invoked when the default is needed + without any arguments. + :param callback: A function to further process or validate the value + after type conversion. It is called as ``f(ctx, param, value)`` + and must return the value. It is called for all sources, + including prompts. + :param nargs: the number of arguments to match. If not ``1`` the return + value is a tuple instead of single value. The default for + nargs is ``1`` (except if the type is a tuple, then it's + the arity of the tuple). If ``nargs=-1``, all remaining + parameters are collected. + :param metavar: how the value is represented in the help page. + :param expose_value: if this is `True` then the value is passed onwards + to the command callback and stored on the context, + otherwise it's skipped. + :param is_eager: eager values are processed before non eager ones. This + should not be set for arguments or it will inverse the + order of processing. + :param envvar: a string or list of strings that are environment variables + that should be checked. + :param shell_complete: A function that returns custom shell + completions. Used instead of the param's type completion if + given. Takes ``ctx, param, incomplete`` and must return a list + of :class:`~click.shell_completion.CompletionItem` or a list of + strings. + + .. versionchanged:: 8.0 + ``process_value`` validates required parameters and bounded + ``nargs``, and invokes the parameter callback before returning + the value. This allows the callback to validate prompts. + ``full_process_value`` is removed. + + .. versionchanged:: 8.0 + ``autocompletion`` is renamed to ``shell_complete`` and has new + semantics described above. The old name is deprecated and will + be removed in 8.1, until then it will be wrapped to match the + new requirements. + + .. versionchanged:: 8.0 + For ``multiple=True, nargs>1``, the default must be a list of + tuples. + + .. versionchanged:: 8.0 + Setting a default is no longer required for ``nargs>1``, it will + default to ``None``. ``multiple=True`` or ``nargs=-1`` will + default to ``()``. + + .. versionchanged:: 7.1 + Empty environment variables are ignored rather than taking the + empty string value. This makes it possible for scripts to clear + variables if they can't unset them. + + .. versionchanged:: 2.0 + Changed signature for parameter callback to also be passed the + parameter. The old callback format will still work, but it will + raise a warning to give you a chance to migrate the code easier. + """ + + param_type_name = "parameter" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + required: bool = False, + default: t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]] = None, + callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]] = None, + nargs: t.Optional[int] = None, + multiple: bool = False, + metavar: t.Optional[str] = None, + expose_value: bool = True, + is_eager: bool = False, + envvar: t.Optional[t.Union[str, t.Sequence[str]]] = None, + shell_complete: t.Optional[ + t.Callable[ + [Context, "Parameter", str], + t.Union[t.List["CompletionItem"], t.List[str]], + ] + ] = None, + autocompletion: t.Optional[ + t.Callable[ + [Context, t.List[str], str], t.List[t.Union[t.Tuple[str, str], str]] + ] + ] = None, + ) -> None: + self.name, self.opts, self.secondary_opts = self._parse_decls( + param_decls or (), expose_value + ) + self.type = types.convert_type(type, default) + + # Default nargs to what the type tells us if we have that + # information available. + if nargs is None: + if self.type.is_composite: + nargs = self.type.arity + else: + nargs = 1 + + self.required = required + self.callback = callback + self.nargs = nargs + self.multiple = multiple + self.expose_value = expose_value + self.default = default + self.is_eager = is_eager + self.metavar = metavar + self.envvar = envvar + + if autocompletion is not None: + import warnings + + warnings.warn( + "'autocompletion' is renamed to 'shell_complete'. The old name is" + " deprecated and will be removed in Click 8.1. See the docs about" + " 'Parameter' for information about new behavior.", + DeprecationWarning, + stacklevel=2, + ) + + def shell_complete( + ctx: Context, param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + from click.shell_completion import CompletionItem + + out = [] + + for c in autocompletion(ctx, [], incomplete): # type: ignore + if isinstance(c, tuple): + c = CompletionItem(c[0], help=c[1]) + elif isinstance(c, str): + c = CompletionItem(c) + + if c.value.startswith(incomplete): + out.append(c) + + return out + + 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 + + @typing.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @typing.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_value` 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.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 callable(value): + if not call: + # Don't type cast the callable. + return value + + value = value() + + try: + return self.type_cast_value(ctx, value) + except BadParameter: + if ctx.resilient_parsing: + return value + + raise + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + raise NotImplementedError() + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, t.Any] + ) -> t.Tuple[t.Any, ParameterSource]: + value = opts.get(self.name) # type: ignore + source = ParameterSource.COMMANDLINE + + if value is None: + value = self.value_from_envvar(ctx) + source = ParameterSource.ENVIRONMENT + + if value is None: + value = ctx.lookup_default(self.name) # type: ignore + source = ParameterSource.DEFAULT_MAP + + if value is None: + value = self.get_default(ctx) + source = ParameterSource.DEFAULT + + return value, source + + def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any: + """Convert and validate a value against the option's + :attr:`type`, :attr:`multiple`, and :attr:`nargs`. + """ + if value is None: + return () if self.multiple or self.nargs == -1 else None + + def check_iter(value: t.Any) -> t.Iterator: + try: + return _check_iter(value) + except TypeError: + # This should only happen when passing in args manually, + # the parser should construct an iterable when parsing + # the command line. + raise BadParameter( + _("Value must be an iterable."), ctx=ctx, param=self + ) from None + + if self.nargs == 1 or self.type.is_composite: + convert: t.Callable[[t.Any], t.Any] = partial( + self.type, param=self, ctx=ctx + ) + elif self.nargs == -1: + + def convert(value: t.Any) -> t.Tuple: + return tuple(self.type(x, self, ctx) for x in check_iter(value)) + + else: # nargs > 1 + + def convert(value: t.Any) -> t.Tuple: + value = tuple(check_iter(value)) + + if len(value) != self.nargs: + raise BadParameter( + ngettext( + "Takes {nargs} values but 1 was given.", + "Takes {nargs} values but {len} were given.", + len(value), + ).format(nargs=self.nargs, len=len(value)), + ctx=ctx, + param=self, + ) + + return tuple(self.type(x, self, ctx) for x in value) + + if self.multiple: + return tuple(convert(x) for x in check_iter(value)) + + return convert(value) + + def value_is_missing(self, value: t.Any) -> bool: + if value is None: + return True + + if (self.nargs != 1 or self.multiple) and value == (): + return True + + return False + + def process_value(self, ctx: Context, value: t.Any) -> t.Any: + if value is not None: + 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: controls if the default value should be shown on the + help page. Normally, defaults are not shown. If this + value is a string, it shows the string instead of the + value. This is particularly useful for dynamic options. + :param show_envvar: controls if an environment variable should be shown on + the help page. Normally, environment variables + are not shown. + :param prompt: if set to `True` or a non empty string then the user will be + prompted for input. If set to `True` the prompt will be the + option name capitalized. + :param confirmation_prompt: Prompt a second time to confirm the + value if it was prompted for. Can be set to a string instead of + ``True`` to customize the message. + :param prompt_required: If set to ``False``, the user will be + prompted for input only when the option was specified as a flag + without a value. + :param hide_input: if this is `True` then the input on the prompt will be + hidden from the user. This is useful for password + input. + :param is_flag: forces this option to act as a flag. The default is + auto detection. + :param flag_value: which value should be used for this flag if it's + enabled. This is set to a boolean automatically if + the option string contains a slash to mark two options. + :param multiple: if this is set to `True` then the argument is accepted + multiple times and recorded. This is similar to ``nargs`` + in how it works but supports arbitrary number of + arguments. + :param count: this flag makes an option increment an integer. + :param allow_from_autoenv: if this is enabled then the value of this + parameter will be pulled from an environment + variable in case a prefix is defined on the + context. + :param help: the help string. + :param hidden: hide this option from help outputs. + + .. versionchanged:: 8.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: bool = False, + 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: + 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 = t.cast(str, prompt) + + self.prompt = prompt_text + self.confirmation_prompt = confirmation_prompt + self.prompt_required = prompt_required + self.hide_input = hide_input + self.hidden = hidden + + # If prompt is enabled but not required, then the option can be + # used as a flag to indicate using prompt or flag_value. + self._flag_needs_value = self.prompt is not None and not self.prompt_required + + if is_flag is None: + if flag_value is not None: + # Implicitly a flag because flag_value was set. + is_flag = True + elif self._flag_needs_value: + # Not a flag, but when used as a flag it shows a prompt. + is_flag = False + else: + # Implicitly a flag because flag options were given. + is_flag = bool(self.secondary_opts) + elif is_flag is False and not self._flag_needs_value: + # Not a flag, and prompt is not enabled, can be used as a + # flag if flag_value is set. + self._flag_needs_value = flag_value is not None + + if is_flag and default_is_missing: + self.default: t.Union[t.Any, t.Callable[[], t.Any]] = False + + if flag_value is None: + flag_value = not self.default + + if is_flag and type is None: + # Re-guess the type from the flag value instead of the + # default. + self.type = types.convert_type(None, flag_value) + + self.is_flag: bool = is_flag + self.is_bool_flag = 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("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_is_str = isinstance(self.show_default, str) + + if show_default_is_str or ( + default_value is not None and (self.show_default or ctx.show_default) + ): + 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 callable(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] + else: + default_string = str(default_value) + + extra.append(_("default: {default}").format(default=default_string)) + + if isinstance(self.type, types._NumberRangeBase): + 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 + + @typing.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @typing.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 the default one in which case we return the flag + # value as default. + if self.is_flag and not self.is_bool_flag: + for param in ctx.command.params: + if param.name == self.name and param.default: + return param.flag_value # type: ignore + + return None + + return super().get_default(ctx, call=call) + + def prompt_for_value(self, ctx: Context) -> t.Any: + """This is an alternative flow that can be activated in the full + value processing if a value does not exist. It will prompt the + user until a valid value exists and then returns the processed + value as result. + """ + assert self.prompt is not None + + # Calculate the default before prompting anything to be stable. + default = self.get_default(ctx) + + # If this is a prompt for a flag we need to handle this + # differently. + if self.is_bool_flag: + return confirm(self.prompt, default) + + return prompt( + self.prompt, + default=default, + type=self.type, + hide_input=self.hide_input, + show_choices=self.show_choices, + confirmation_prompt=self.confirmation_prompt, + value_proc=lambda x: self.process_value(ctx, x), + ) + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + rv = super().resolve_envvar_value(ctx) + + if rv is not None: + return rv + + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + rv = os.environ.get(envvar) + + return rv + + 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 + + # The value wasn't set, or used the param's default, prompt if + # prompting is enabled. + elif ( + source in {None, ParameterSource.DEFAULT} + and self.prompt is not None + and (self.required or self.prompt_required) + and not ctx.resilient_parsing + ): + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + + return value, source + + +class Argument(Parameter): + """Arguments are positional parameters to a command. They generally + provide fewer features than options but can have infinite ``nargs`` + and are required by default. + + All parameters are passed onwards to the parameter constructor. + """ + + param_type_name = "argument" + + def __init__( + self, + param_decls: t.Sequence[str], + required: t.Optional[bool] = None, + **attrs: t.Any, + ) -> None: + if required is None: + if attrs.get("default") is not None: + required = False + else: + required = attrs.get("nargs", 1) > 0 + + if "multiple" in attrs: + raise TypeError("__init__() got an unexpected keyword argument 'multiple'.") + + super().__init__(param_decls, required=required, **attrs) + + if __debug__: + if self.default is not None and self.nargs == -1: + raise TypeError("'default' is not supported for nargs=-1.") + + @property + def human_readable_name(self) -> str: + if self.metavar is not None: + return self.metavar + return self.name.upper() # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + var = self.type.get_metavar(self) + if not var: + var = self.name.upper() # type: ignore + if not self.required: + var = f"[{var}]" + if self.nargs != 1: + var += "..." + return var + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + if not decls: + if not expose_value: + return None, [], [] + raise TypeError("Could not determine name for argument") + if len(decls) == 1: + name = arg = decls[0] + name = name.replace("-", "_").lower() + else: + raise TypeError( + "Arguments take exactly one parameter declaration, got" + f" {len(decls)}." + ) + return name, [arg], [] + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [self.make_metavar()] + + def get_error_hint(self, ctx: Context) -> str: + return f"'{self.make_metavar()}'" + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + parser.add_argument(dest=self.name, nargs=self.nargs, obj=self) diff --git a/venv/lib/python3.9/site-packages/click/decorators.py b/venv/lib/python3.9/site-packages/click/decorators.py new file mode 100644 index 0000000..5940e69 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/decorators.py @@ -0,0 +1,437 @@ +import inspect +import types +import typing as t +from functools import update_wrapper +from gettext import gettext as _ + +from .core import Argument +from .core import Command +from .core import Context +from .core import Group +from .core import Option +from .core import Parameter +from .globals import get_current_context +from .utils import echo + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +FC = t.TypeVar("FC", t.Callable[..., t.Any], Command) + + +def pass_context(f: F) -> F: + """Marks a callback as wanting to receive the current context + object as first argument. + """ + + def new_func(*args, **kwargs): # type: ignore + return f(get_current_context(), *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def pass_obj(f: F) -> F: + """Similar to :func:`pass_context`, but only pass the object on the + context onwards (:attr:`Context.obj`). This is useful if that object + represents the state of a nested system. + """ + + def new_func(*args, **kwargs): # type: ignore + return f(get_current_context().obj, *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def make_pass_decorator( + object_type: t.Type, ensure: bool = False +) -> "t.Callable[[F], F]": + """Given an object type this creates a decorator that will work + similar to :func:`pass_obj` but instead of passing the object of the + current context, it will find the innermost context of type + :func:`object_type`. + + This generates a decorator that works roughly like this:: + + from functools import update_wrapper + + def decorator(f): + @pass_context + def new_func(ctx, *args, **kwargs): + obj = ctx.find_object(object_type) + return ctx.invoke(f, obj, *args, **kwargs) + return update_wrapper(new_func, f) + return decorator + + :param object_type: the type of the object to pass. + :param ensure: if set to `True`, a new object will be created and + remembered on the context if it's not there yet. + """ + + def decorator(f: F) -> F: + def new_func(*args, **kwargs): # type: ignore + ctx = get_current_context() + + if ensure: + obj = ctx.ensure_object(object_type) + else: + obj = ctx.find_object(object_type) + + if obj is None: + raise RuntimeError( + "Managed to invoke callback without a context" + f" object of type {object_type.__name__!r}" + " existing." + ) + + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + return decorator + + +def pass_meta_key( + key: str, *, doc_description: t.Optional[str] = None +) -> "t.Callable[[F], F]": + """Create a decorator that passes a key from + :attr:`click.Context.meta` as the first argument to the decorated + function. + + :param key: Key in ``Context.meta`` to pass. + :param doc_description: Description of the object being passed, + inserted into the decorator's docstring. Defaults to "the 'key' + key from Context.meta". + + .. versionadded:: 8.0 + """ + + def decorator(f: F) -> F: + def new_func(*args, **kwargs): # type: ignore + ctx = get_current_context() + obj = ctx.meta[key] + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + if doc_description is None: + doc_description = f"the {key!r} key from :attr:`click.Context.meta`" + + decorator.__doc__ = ( + f"Decorator that passes {doc_description} as the first argument" + " to the decorated function." + ) + return decorator + + +def _make_command( + f: F, + name: t.Optional[str], + attrs: t.MutableMapping[str, t.Any], + cls: t.Type[Command], +) -> Command: + if isinstance(f, Command): + raise TypeError("Attempted to convert a callback into a command twice.") + + try: + params = f.__click_params__ # type: ignore + params.reverse() + del f.__click_params__ # type: ignore + except AttributeError: + params = [] + + help = attrs.get("help") + + if help is None: + help = inspect.getdoc(f) + else: + help = inspect.cleandoc(help) + + attrs["help"] = help + return cls( + name=name or f.__name__.lower().replace("_", "-"), + callback=f, + params=params, + **attrs, + ) + + +def command( + name: t.Optional[str] = None, + cls: t.Optional[t.Type[Command]] = None, + **attrs: t.Any, +) -> t.Callable[[F], Command]: + r"""Creates a new :class:`Command` and uses the decorated function as + callback. This will also automatically attach all decorated + :func:`option`\s and :func:`argument`\s as parameters to the command. + + The name of the command defaults to the name of the function with + underscores replaced by dashes. If you want to change that, you can + pass the intended name as the first argument. + + All keyword arguments are forwarded to the underlying command class. + + 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`. + """ + if cls is None: + cls = Command + + def decorator(f: t.Callable[..., t.Any]) -> Command: + cmd = _make_command(f, name, attrs, cls) # type: ignore + cmd.__doc__ = f.__doc__ + return cmd + + return decorator + + +def group(name: t.Optional[str] = None, **attrs: t.Any) -> t.Callable[[F], Group]: + """Creates a new :class:`Group` with a function as callback. This + works otherwise the same as :func:`command` just that the `cls` + parameter is set to :class:`Group`. + """ + attrs.setdefault("cls", Group) + return t.cast(Group, command(name, **attrs)) + + +def _param_memo(f: FC, param: Parameter) -> None: + if isinstance(f, Command): + f.params.append(param) + else: + if not hasattr(f, "__click_params__"): + f.__click_params__ = [] # type: ignore + + f.__click_params__.append(param) # type: ignore + + +def argument(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]: + """Attaches an argument to the command. All positional arguments are + passed as parameter declarations to :class:`Argument`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Argument` instance manually + and attaching it to the :attr:`Command.params` list. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + """ + + def decorator(f: FC) -> FC: + ArgumentClass = attrs.pop("cls", Argument) + _param_memo(f, ArgumentClass(param_decls, **attrs)) + return f + + return decorator + + +def option(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]: + """Attaches an option to the command. All positional arguments are + passed as parameter declarations to :class:`Option`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Option` instance manually + and attaching it to the :attr:`Command.params` list. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + """ + + def decorator(f: FC) -> FC: + # Issue 926, copy attrs, so pre-defined options can re-use the same cls= + option_attrs = attrs.copy() + + if "help" in option_attrs: + option_attrs["help"] = inspect.cleandoc(option_attrs["help"]) + OptionClass = option_attrs.pop("cls", Option) + _param_memo(f, OptionClass(param_decls, **option_attrs)) + return f + + return decorator + + +def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--yes`` option which shows a prompt before continuing if + not passed. If the prompt is declined, the program will exit. + + :param param_decls: One or more option names. Defaults to the single + value ``"--yes"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value: + ctx.abort() + + if not param_decls: + param_decls = ("--yes",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("callback", callback) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("prompt", "Do you want to continue?") + kwargs.setdefault("help", "Confirm the action without prompting.") + return option(*param_decls, **kwargs) + + +def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--password`` option which prompts for a password, hiding + input and asking to enter the value again for confirmation. + + :param param_decls: One or more option names. Defaults to the single + value ``"--password"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + if not param_decls: + param_decls = ("--password",) + + kwargs.setdefault("prompt", True) + kwargs.setdefault("confirmation_prompt", True) + kwargs.setdefault("hide_input", True) + return option(*param_decls, **kwargs) + + +def version_option( + version: t.Optional[str] = None, + *param_decls: str, + package_name: t.Optional[str] = None, + prog_name: t.Optional[str] = None, + message: t.Optional[str] = None, + **kwargs: t.Any, +) -> t.Callable[[FC], FC]: + """Add a ``--version`` option which immediately prints the version + number and exits the program. + + If ``version`` is not provided, Click will try to detect it using + :func:`importlib.metadata.version` to get the version for the + ``package_name``. On Python < 3.8, the ``importlib_metadata`` + backport must be installed. + + If ``package_name`` is not provided, Click will try to detect it by + inspecting the stack frames. This will be used to detect the + version, so it must match the name of the installed package. + + :param version: The version number to show. If not provided, Click + will try to detect it. + :param param_decls: One or more option names. Defaults to the single + value ``"--version"``. + :param package_name: The package name to detect the version from. If + not provided, Click will try to detect it. + :param prog_name: The name of the CLI to show in the message. If not + provided, it will be detected from the command. + :param message: The message to show. The values ``%(prog)s``, + ``%(package)s``, and ``%(version)s`` are available. Defaults to + ``"%(prog)s, version %(version)s"``. + :param kwargs: Extra arguments are passed to :func:`option`. + :raise RuntimeError: ``version`` could not be detected. + + .. versionchanged:: 8.0 + Add the ``package_name`` parameter, and the ``%(package)s`` + value for messages. + + .. versionchanged:: 8.0 + Use :mod:`importlib.metadata` instead of ``pkg_resources``. The + version is detected based on the package name, not the entry + point name. The Python package name must match the installed + package name, or be passed with ``package_name=``. + """ + if message is None: + message = _("%(prog)s, version %(version)s") + + if version is None and package_name is None: + frame = inspect.currentframe() + assert frame is not None + assert frame.f_back is not None + f_globals = frame.f_back.f_globals if frame 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." + ) + + if version is None: + raise RuntimeError( + f"Could not determine the version for {package_name!r} automatically." + ) + + echo( + t.cast(str, message) + % {"prog": prog_name, "package": package_name, "version": version}, + color=ctx.color, + ) + ctx.exit() + + if not param_decls: + param_decls = ("--version",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show the version and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) + + +def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--help`` option which immediately prints the help page + and exits the program. + + This is usually unnecessary, as the ``--help`` option is added to + each command automatically unless ``add_help_option=False`` is + passed. + + :param param_decls: One or more option names. Defaults to the single + value ``"--help"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + if not param_decls: + param_decls = ("--help",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show this message and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) diff --git a/venv/lib/python3.9/site-packages/click/exceptions.py b/venv/lib/python3.9/site-packages/click/exceptions.py new file mode 100644 index 0000000..9e20b3e --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/exceptions.py @@ -0,0 +1,287 @@ +import os +import typing as t +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import get_text_stderr +from .utils import echo + +if t.TYPE_CHECKING: + from .core import Context + from .core import Parameter + + +def _join_param_hints( + param_hint: t.Optional[t.Union[t.Sequence[str], str]] +) -> t.Optional[str]: + if param_hint is not None and not isinstance(param_hint, str): + return " / ".join(repr(x) for x in param_hint) + + return param_hint + + +class ClickException(Exception): + """An exception that Click can handle and show to the user.""" + + #: The exit code for this exception. + exit_code = 1 + + def __init__(self, message: str) -> None: + super().__init__(message) + self.message = message + + def format_message(self) -> str: + return self.message + + def __str__(self) -> str: + return self.message + + def show(self, file: t.Optional[t.IO] = None) -> None: + if file is None: + file = get_text_stderr() + + echo(_("Error: {message}").format(message=self.format_message()), file=file) + + +class UsageError(ClickException): + """An internal exception that signals a usage error. This typically + aborts any further handling. + + :param message: the error message to display. + :param ctx: optionally the context that caused this error. Click will + fill in the context automatically in some situations. + """ + + exit_code = 2 + + def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None: + super().__init__(message) + self.ctx = ctx + self.cmd = self.ctx.command if self.ctx else None + + def show(self, file: t.Optional[t.IO] = None) -> None: + if file is None: + file = get_text_stderr() + color = None + hint = "" + if ( + self.ctx is not None + and self.ctx.command.get_help_option(self.ctx) is not None + ): + hint = _("Try '{command} {option}' for help.").format( + command=self.ctx.command_path, option=self.ctx.help_option_names[0] + ) + hint = f"{hint}\n" + if self.ctx is not None: + color = self.ctx.color + echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color) + echo( + _("Error: {message}").format(message=self.format_message()), + file=file, + color=color, + ) + + +class BadParameter(UsageError): + """An exception that formats out a standardized error message for a + bad parameter. This is useful when thrown from a callback or type as + Click will attach contextual information to it (for instance, which + parameter it is). + + .. versionadded:: 2.0 + + :param param: the parameter object that caused this error. This can + be left out, and Click will attach this info itself + if possible. + :param param_hint: a string that shows up as parameter name. This + can be used as alternative to `param` in cases + where custom validation should happen. If it is + a string it's used as such, if it's a list then + each item is quoted and separated. + """ + + def __init__( + self, + message: str, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + ) -> None: + super().__init__(message, ctx) + self.param = param + self.param_hint = param_hint + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + return _("Invalid value: {message}").format(message=self.message) + + return _("Invalid value for {param_hint}: {message}").format( + param_hint=_join_param_hints(param_hint), message=self.message + ) + + +class MissingParameter(BadParameter): + """Raised if click required an option or argument but it was not + provided when invoking the script. + + .. versionadded:: 4.0 + + :param param_type: a string that indicates the type of the parameter. + The default is to inherit the parameter type from + the given `param`. Valid values are ``'parameter'``, + ``'option'`` or ``'argument'``. + """ + + def __init__( + self, + message: t.Optional[str] = None, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + param_type: t.Optional[str] = None, + ) -> None: + super().__init__(message or "", ctx, param, param_hint) + self.param_type = param_type + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint: t.Optional[str] = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + param_hint = None + + param_hint = _join_param_hints(param_hint) + param_hint = f" {param_hint}" if param_hint else "" + + param_type = self.param_type + if param_type is None and self.param is not None: + param_type = self.param.param_type_name + + msg = self.message + if self.param is not None: + msg_extra = self.param.type.get_missing_message(self.param) + if msg_extra: + if msg: + msg += f". {msg_extra}" + else: + msg = msg_extra + + msg = f" {msg}" if msg else "" + + # Translate param_type for known types. + if param_type == "argument": + missing = _("Missing argument") + elif param_type == "option": + missing = _("Missing option") + elif param_type == "parameter": + missing = _("Missing parameter") + else: + missing = _("Missing {param_type}").format(param_type=param_type) + + return f"{missing}{param_hint}.{msg}" + + def __str__(self) -> str: + if not self.message: + param_name = self.param.name if self.param else None + return _("Missing parameter: {param_name}").format(param_name=param_name) + else: + return self.message + + +class NoSuchOption(UsageError): + """Raised if click attempted to handle an option that does not + exist. + + .. versionadded:: 4.0 + """ + + def __init__( + self, + option_name: str, + message: t.Optional[str] = None, + possibilities: t.Optional[t.Sequence[str]] = None, + ctx: t.Optional["Context"] = None, + ) -> None: + if message is None: + message = _("No such option: {name}").format(name=option_name) + + super().__init__(message, ctx) + self.option_name = option_name + self.possibilities = possibilities + + def format_message(self) -> str: + if not self.possibilities: + return self.message + + possibility_str = ", ".join(sorted(self.possibilities)) + suggest = ngettext( + "Did you mean {possibility}?", + "(Possible options: {possibilities})", + len(self.possibilities), + ).format(possibility=possibility_str, possibilities=possibility_str) + return f"{self.message} {suggest}" + + +class BadOptionUsage(UsageError): + """Raised if an option is generally supplied but the use of the option + was incorrect. This is for instance raised if the number of arguments + for an option is not correct. + + .. versionadded:: 4.0 + + :param option_name: the name of the option being used incorrectly. + """ + + def __init__( + self, option_name: str, message: str, ctx: t.Optional["Context"] = None + ) -> None: + super().__init__(message, ctx) + self.option_name = option_name + + +class BadArgumentUsage(UsageError): + """Raised if an argument is generally supplied but the use of the argument + was incorrect. This is for instance raised if the number of values + for an argument is not correct. + + .. versionadded:: 6.0 + """ + + +class FileError(ClickException): + """Raised if a file cannot be opened.""" + + def __init__(self, filename: str, hint: t.Optional[str] = None) -> None: + if hint is None: + hint = _("unknown error") + + super().__init__(hint) + self.ui_filename = os.fsdecode(filename) + self.filename = filename + + def format_message(self) -> str: + return _("Could not open file {filename!r}: {message}").format( + filename=self.ui_filename, message=self.message + ) + + +class Abort(RuntimeError): + """An internal signalling exception that signals Click to abort.""" + + +class Exit(RuntimeError): + """An exception that indicates that the application should exit with some + status code. + + :param code: the status code to exit with. + """ + + __slots__ = ("exit_code",) + + def __init__(self, code: int = 0) -> None: + self.exit_code = code diff --git a/venv/lib/python3.9/site-packages/click/formatting.py b/venv/lib/python3.9/site-packages/click/formatting.py new file mode 100644 index 0000000..ddd2a2f --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/formatting.py @@ -0,0 +1,301 @@ +import typing as t +from contextlib import contextmanager +from gettext import gettext as _ + +from ._compat import term_len +from .parser import split_opt + +# Can force a width. This is used by the test system +FORCED_WIDTH: t.Optional[int] = None + + +def measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]: + widths: t.Dict[int, int] = {} + + for row in rows: + for idx, col in enumerate(row): + widths[idx] = max(widths.get(idx, 0), term_len(col)) + + return tuple(y for x, y in sorted(widths.items())) + + +def iter_rows( + rows: t.Iterable[t.Tuple[str, str]], col_count: int +) -> t.Iterator[t.Tuple[str, ...]]: + for row in rows: + yield row + ("",) * (col_count - len(row)) + + +def wrap_text( + text: str, + width: int = 78, + initial_indent: str = "", + subsequent_indent: str = "", + preserve_paragraphs: bool = False, +) -> str: + """A helper function that intelligently wraps text. By default, it + assumes that it operates on a single paragraph of text but if the + `preserve_paragraphs` parameter is provided it will intelligently + handle paragraphs (defined by two empty lines). + + If paragraphs are handled, a paragraph can be prefixed with an empty + line containing the ``\\b`` character (``\\x08``) to indicate that + no rewrapping should happen in that block. + + :param text: the text that should be rewrapped. + :param width: the maximum width for the text. + :param initial_indent: the initial indent that should be placed on the + first line as a string. + :param subsequent_indent: the indent string that should be placed on + each consecutive line. + :param preserve_paragraphs: if this flag is set then the wrapping will + intelligently handle paragraphs. + """ + from ._textwrap import TextWrapper + + text = text.expandtabs() + wrapper = TextWrapper( + width, + initial_indent=initial_indent, + subsequent_indent=subsequent_indent, + replace_whitespace=False, + ) + if not preserve_paragraphs: + return wrapper.fill(text) + + p: t.List[t.Tuple[int, bool, str]] = [] + buf: t.List[str] = [] + indent = None + + def _flush_par() -> None: + if not buf: + return + if buf[0].strip() == "\b": + p.append((indent or 0, True, "\n".join(buf[1:]))) + else: + p.append((indent or 0, False, " ".join(buf))) + del buf[:] + + for line in text.splitlines(): + if not line: + _flush_par() + indent = None + else: + if indent is None: + orig_len = term_len(line) + line = line.lstrip() + indent = orig_len - term_len(line) + buf.append(line) + _flush_par() + + rv = [] + for indent, raw, text in p: + with wrapper.extra_indent(" " * indent): + if raw: + rv.append(wrapper.indent_only(text)) + else: + rv.append(wrapper.fill(text)) + + return "\n\n".join(rv) + + +class HelpFormatter: + """This class helps with formatting text-based help pages. It's + usually just needed for very special internal cases, but it's also + exposed so that developers can write their own fancy outputs. + + At present, it always writes into memory. + + :param indent_increment: the additional increment for each level. + :param width: the width for the text. This defaults to the terminal + width clamped to a maximum of 78. + """ + + def __init__( + self, + indent_increment: int = 2, + width: t.Optional[int] = None, + max_width: t.Optional[int] = None, + ) -> None: + import shutil + + self.indent_increment = indent_increment + if max_width is None: + max_width = 80 + if width is None: + width = FORCED_WIDTH + if width is None: + width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50) + self.width = width + self.current_indent = 0 + self.buffer: t.List[str] = [] + + def write(self, string: str) -> None: + """Writes a unicode string into the internal buffer.""" + self.buffer.append(string) + + def indent(self) -> None: + """Increases the indentation.""" + self.current_indent += self.indent_increment + + def dedent(self) -> None: + """Decreases the indentation.""" + self.current_indent -= self.indent_increment + + def write_usage( + self, prog: str, args: str = "", prefix: t.Optional[str] = None + ) -> None: + """Writes a usage line into the buffer. + + :param prog: the program name. + :param args: whitespace separated list of arguments. + :param prefix: The prefix for the first line. Defaults to + ``"Usage: "``. + """ + if prefix is None: + prefix = f"{_('Usage:')} " + + usage_prefix = f"{prefix:>{self.current_indent}}{prog} " + text_width = self.width - self.current_indent + + if text_width >= (term_len(usage_prefix) + 20): + # The arguments will fit to the right of the prefix. + indent = " " * term_len(usage_prefix) + self.write( + wrap_text( + args, + text_width, + initial_indent=usage_prefix, + subsequent_indent=indent, + ) + ) + else: + # The prefix is too long, put the arguments on the next line. + self.write(usage_prefix) + self.write("\n") + indent = " " * (max(self.current_indent, term_len(prefix)) + 4) + self.write( + wrap_text( + args, text_width, initial_indent=indent, subsequent_indent=indent + ) + ) + + self.write("\n") + + def write_heading(self, heading: str) -> None: + """Writes a heading into the buffer.""" + self.write(f"{'':>{self.current_indent}}{heading}:\n") + + def write_paragraph(self) -> None: + """Writes a paragraph into the buffer.""" + if self.buffer: + self.write("\n") + + def write_text(self, text: str) -> None: + """Writes re-indented text into the buffer. This rewraps and + preserves paragraphs. + """ + indent = " " * self.current_indent + self.write( + wrap_text( + text, + self.width, + initial_indent=indent, + subsequent_indent=indent, + preserve_paragraphs=True, + ) + ) + self.write("\n") + + def write_dl( + self, + rows: t.Sequence[t.Tuple[str, str]], + col_max: int = 30, + col_spacing: int = 2, + ) -> None: + """Writes a definition list into the buffer. This is how options + and commands are usually formatted. + + :param rows: a list of two item tuples for the terms and values. + :param col_max: the maximum width of the first column. + :param col_spacing: the number of spaces between the first and + second column. + """ + rows = list(rows) + widths = measure_table(rows) + if len(widths) != 2: + raise TypeError("Expected two columns for definition list") + + first_col = min(widths[0], col_max) + col_spacing + + for first, second in iter_rows(rows, len(widths)): + self.write(f"{'':>{self.current_indent}}{first}") + if not second: + self.write("\n") + continue + if term_len(first) <= first_col - col_spacing: + self.write(" " * (first_col - term_len(first))) + else: + self.write("\n") + self.write(" " * (first_col + self.current_indent)) + + text_width = max(self.width - first_col - 2, 10) + wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True) + lines = wrapped_text.splitlines() + + if lines: + self.write(f"{lines[0]}\n") + + for line in lines[1:]: + self.write(f"{'':>{first_col + self.current_indent}}{line}\n") + else: + self.write("\n") + + @contextmanager + def section(self, name: str) -> t.Iterator[None]: + """Helpful context manager that writes a paragraph, a heading, + and the indents. + + :param name: the section name that is written as heading. + """ + self.write_paragraph() + self.write_heading(name) + self.indent() + try: + yield + finally: + self.dedent() + + @contextmanager + def indentation(self) -> t.Iterator[None]: + """A context manager that increases the indentation.""" + self.indent() + try: + yield + finally: + self.dedent() + + def getvalue(self) -> str: + """Returns the buffer contents.""" + return "".join(self.buffer) + + +def join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]: + """Given a list of option strings this joins them in the most appropriate + way and returns them in the form ``(formatted_string, + any_prefix_is_slash)`` where the second item in the tuple is a flag that + indicates if any of the option prefixes was a slash. + """ + rv = [] + any_prefix_is_slash = False + + for opt in options: + prefix = split_opt(opt)[0] + + if prefix == "/": + any_prefix_is_slash = True + + rv.append((len(prefix), opt)) + + rv.sort(key=lambda x: x[0]) + return ", ".join(x[1] for x in rv), any_prefix_is_slash diff --git a/venv/lib/python3.9/site-packages/click/globals.py b/venv/lib/python3.9/site-packages/click/globals.py new file mode 100644 index 0000000..cfcade1 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/globals.py @@ -0,0 +1,69 @@ +import typing +import typing as t +from threading import local + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + +_local = local() + + +@typing.overload +def get_current_context(silent: "te.Literal[False]" = False) -> "Context": + ... + + +@typing.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): + if not silent: + raise RuntimeError("There is no active click context.") + + return None + + +def push_context(ctx: "Context") -> None: + """Pushes a new context to the current stack.""" + _local.__dict__.setdefault("stack", []).append(ctx) + + +def pop_context() -> None: + """Removes the top level from the stack.""" + _local.stack.pop() + + +def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]: + """Internal helper to get the default value of the color flag. If a + value is passed it's returned unchanged, otherwise it's looked up from + the current context. + """ + if color is not None: + return color + + ctx = get_current_context(silent=True) + + if ctx is not None: + return ctx.color + + return None diff --git a/venv/lib/python3.9/site-packages/click/parser.py b/venv/lib/python3.9/site-packages/click/parser.py new file mode 100644 index 0000000..7d995f7 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/parser.py @@ -0,0 +1,529 @@ +""" +This module started out as largely a copy paste from the stdlib's +optparse module with the features removed that we do not need from +optparse because we implement them in Click on a higher level (for +instance type handling, help formatting and a lot more). + +The plan is to remove more and more from here over time. + +The reason this is a different module and not optparse from the stdlib +is that there are differences in 2.x and 3.x about the error messages +generated and optparse in the stdlib uses gettext for no good reason +and might cause us issues. + +Click uses parts of optparse written by Gregory P. Ward and maintained +by the Python Software Foundation. This is limited to code in parser.py. + +Copyright 2001-2006 Gregory P. Ward. All rights reserved. +Copyright 2002-2006 Python Software Foundation. All rights reserved. +""" +# This code uses parts of optparse written by Gregory P. Ward and +# maintained by the Python Software Foundation. +# Copyright 2001-2006 Gregory P. Ward +# Copyright 2002-2006 Python Software Foundation +import typing as t +from collections import deque +from gettext import gettext as _ +from gettext import ngettext + +from .exceptions import BadArgumentUsage +from .exceptions import BadOptionUsage +from .exceptions import NoSuchOption +from .exceptions import UsageError + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Argument as CoreArgument + from .core import Context + from .core import Option as CoreOption + from .core import Parameter as CoreParameter + +V = t.TypeVar("V") + +# Sentinel value that indicates an option was passed as a flag without a +# value but is not a flag option. Option.consume_value uses this to +# prompt or use the flag_value. +_flag_needs_value = object() + + +def _unpack_args( + args: t.Sequence[str], nargs_spec: t.Sequence[int] +) -> t.Tuple[t.Sequence[t.Union[str, t.Sequence[t.Optional[str]], None]], t.List[str]]: + """Given an iterable of arguments and an iterable of nargs specifications, + it returns a tuple with all the unpacked arguments at the first index + and all remaining arguments as the second. + + The nargs specification is the number of arguments that should be consumed + or `-1` to indicate that this position should eat up all the remainders. + + Missing items are filled with `None`. + """ + args = deque(args) + nargs_spec = deque(nargs_spec) + rv: t.List[t.Union[str, t.Tuple[t.Optional[str], ...], None]] = [] + spos: t.Optional[int] = None + + def _fetch(c: "te.Deque[V]") -> t.Optional[V]: + try: + if spos is None: + return c.popleft() + else: + return c.pop() + except IndexError: + return None + + while nargs_spec: + nargs = _fetch(nargs_spec) + + if nargs is None: + continue + + if nargs == 1: + rv.append(_fetch(args)) + elif nargs > 1: + x = [_fetch(args) for _ in range(nargs)] + + # If we're reversed, we're pulling in the arguments in reverse, + # so we need to turn them around. + if spos is not None: + x.reverse() + + rv.append(tuple(x)) + elif nargs < 0: + if spos is not None: + raise TypeError("Cannot have two nargs < 0") + + spos = len(rv) + rv.append(None) + + # spos is the position of the wildcard (star). If it's not `None`, + # we fill it with the remainder. + if spos is not None: + rv[spos] = tuple(args) + args = [] + rv[spos + 1 :] = reversed(rv[spos + 1 :]) + + return tuple(rv), list(args) + + +def split_opt(opt: str) -> t.Tuple[str, str]: + first = opt[:1] + if first.isalnum(): + return "", opt + if opt[1:2] == first: + return opt[:2], opt[2:] + return first, opt[1:] + + +def normalize_opt(opt: str, ctx: t.Optional["Context"]) -> str: + if ctx is None or ctx.token_normalize_func is None: + return opt + prefix, opt = split_opt(opt) + return f"{prefix}{ctx.token_normalize_func(opt)}" + + +def split_arg_string(string: str) -> t.List[str]: + """Split an argument string as with :func:`shlex.split`, but don't + fail if the string is incomplete. Ignores a missing closing quote or + incomplete escape sequence and uses the partial token as-is. + + .. code-block:: python + + split_arg_string("example 'my file") + ["example", "my file"] + + split_arg_string("example my\\") + ["example", "my"] + + :param string: String to split. + """ + import shlex + + lex = shlex.shlex(string, posix=True) + lex.whitespace_split = True + lex.commenters = "" + out = [] + + try: + for token in lex: + out.append(token) + except ValueError: + # Raised when end-of-string is reached in an invalid state. Use + # the partial token as-is. The quote or escape character is in + # lex.state, not lex.token. + out.append(lex.token) + + return out + + +class Option: + def __init__( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ): + self._short_opts = [] + self._long_opts = [] + self.prefixes = set() + + for opt in opts: + prefix, value = split_opt(opt) + if not prefix: + raise ValueError(f"Invalid start character for option ({opt})") + self.prefixes.add(prefix[0]) + if len(prefix) == 1 and len(value) == 1: + self._short_opts.append(opt) + else: + self._long_opts.append(opt) + self.prefixes.add(prefix) + + if action is None: + action = "store" + + self.dest = dest + self.action = action + self.nargs = nargs + self.const = const + self.obj = obj + + @property + def takes_value(self) -> bool: + return self.action in ("store", "append") + + def process(self, value: str, state: "ParsingState") -> None: + if self.action == "store": + state.opts[self.dest] = value # type: ignore + elif self.action == "store_const": + state.opts[self.dest] = self.const # type: ignore + elif self.action == "append": + state.opts.setdefault(self.dest, []).append(value) # type: ignore + elif self.action == "append_const": + state.opts.setdefault(self.dest, []).append(self.const) # type: ignore + elif self.action == "count": + state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 # type: ignore + else: + raise ValueError(f"unknown action '{self.action}'") + state.order.append(self.obj) + + +class Argument: + def __init__(self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1): + self.dest = dest + self.nargs = nargs + self.obj = obj + + def process( + self, + value: t.Union[t.Optional[str], t.Sequence[t.Optional[str]]], + state: "ParsingState", + ) -> None: + if self.nargs > 1: + assert value is not None + holes = sum(1 for x in value if x is None) + if holes == len(value): + value = None + elif holes != 0: + raise BadArgumentUsage( + _("Argument {name!r} takes {nargs} values.").format( + name=self.dest, nargs=self.nargs + ) + ) + + if self.nargs == -1 and self.obj.envvar is not None and value == (): + # Replace empty tuple with None so that a value from the + # environment may be tried. + value = None + + state.opts[self.dest] = value # type: ignore + state.order.append(self.obj) + + +class ParsingState: + def __init__(self, rargs: t.List[str]) -> None: + self.opts: t.Dict[str, t.Any] = {} + self.largs: t.List[str] = [] + self.rargs = rargs + self.order: t.List["CoreParameter"] = [] + + +class OptionParser: + """The option parser is an internal class that is ultimately used to + parse options and arguments. It's modelled after optparse and brings + a similar but vastly simplified API. It should generally not be used + directly as the high level Click classes wrap it for you. + + It's not nearly as extensible as optparse or argparse as it does not + implement features that are implemented on a higher level (such as + types or defaults). + + :param ctx: optionally the :class:`~click.Context` where this parser + should go with. + """ + + def __init__(self, ctx: t.Optional["Context"] = None) -> None: + #: The :class:`~click.Context` for this parser. This might be + #: `None` for some advanced use cases. + self.ctx = ctx + #: This controls how the parser deals with interspersed arguments. + #: If this is set to `False`, the parser will stop on the first + #: non-option. Click uses this to implement nested subcommands + #: safely. + self.allow_interspersed_args = True + #: This tells the parser how to deal with unknown options. By + #: default it will error out (which is sensible), but there is a + #: second mode where it will ignore it and continue processing + #: after shifting all the unknown options into the resulting args. + self.ignore_unknown_options = False + + if ctx is not None: + self.allow_interspersed_args = ctx.allow_interspersed_args + self.ignore_unknown_options = ctx.ignore_unknown_options + + self._short_opt: t.Dict[str, Option] = {} + self._long_opt: t.Dict[str, Option] = {} + self._opt_prefixes = {"-", "--"} + self._args: t.List[Argument] = [] + + def add_option( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ) -> None: + """Adds a new option named `dest` to the parser. The destination + is not inferred (unlike with optparse) and needs to be explicitly + provided. Action can be any of ``store``, ``store_const``, + ``append``, ``appnd_const`` or ``count``. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + opts = [normalize_opt(opt, self.ctx) for opt in opts] + option = Option(obj, opts, dest, action=action, nargs=nargs, const=const) + self._opt_prefixes.update(option.prefixes) + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + def add_argument( + self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1 + ) -> None: + """Adds a positional argument named `dest` to the parser. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + self._args.append(Argument(obj, dest=dest, nargs=nargs)) + + def parse_args( + self, args: t.List[str] + ) -> t.Tuple[t.Dict[str, t.Any], t.List[str], t.List["CoreParameter"]]: + """Parses positional arguments and returns ``(values, args, order)`` + for the parsed options and arguments as well as the leftover + arguments if there are any. The order is a list of objects as they + appear on the command line. If arguments appear multiple times they + will be memorized multiple times as well. + """ + state = ParsingState(args) + try: + self._process_args_for_options(state) + self._process_args_for_args(state) + except UsageError: + if self.ctx is None or not self.ctx.resilient_parsing: + raise + return state.opts, state.largs, state.order + + def _process_args_for_args(self, state: ParsingState) -> None: + pargs, args = _unpack_args( + state.largs + state.rargs, [x.nargs for x in self._args] + ) + + for idx, arg in enumerate(self._args): + arg.process(pargs[idx], state) + + state.largs = args + state.rargs = [] + + def _process_args_for_options(self, state: ParsingState) -> None: + while state.rargs: + arg = state.rargs.pop(0) + arglen = len(arg) + # Double dashes always handled explicitly regardless of what + # prefixes are valid. + if arg == "--": + return + elif arg[:1] in self._opt_prefixes and arglen > 1: + self._process_opts(arg, state) + elif self.allow_interspersed_args: + state.largs.append(arg) + else: + state.rargs.insert(0, arg) + return + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # The while loop will usually consume 1 or more arguments per pass. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt( + self, opt: str, explicit_value: t.Optional[str], state: ParsingState + ) -> None: + if opt not in self._long_opt: + from difflib import get_close_matches + + possibilities = get_close_matches(opt, self._long_opt) + raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx) + + option = self._long_opt[opt] + if option.takes_value: + # At this point it's safe to modify rargs by injecting the + # explicit value, because no exception is raised in this + # branch. This means that the inserted value will be fully + # consumed. + if explicit_value is not None: + state.rargs.insert(0, explicit_value) + + value = self._get_value_from_state(opt, option, state) + + elif explicit_value is not None: + raise BadOptionUsage( + opt, _("Option {name!r} does not take a value.").format(name=opt) + ) + + else: + value = None + + option.process(value, state) + + def _match_short_opt(self, arg: str, state: ParsingState) -> None: + stop = False + i = 1 + prefix = arg[0] + unknown_options = [] + + for ch in arg[1:]: + opt = normalize_opt(f"{prefix}{ch}", self.ctx) + option = self._short_opt.get(opt) + i += 1 + + if not option: + if self.ignore_unknown_options: + unknown_options.append(ch) + continue + raise NoSuchOption(opt, ctx=self.ctx) + if option.takes_value: + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + state.rargs.insert(0, arg[i:]) + stop = True + + value = self._get_value_from_state(opt, option, state) + + else: + value = None + + option.process(value, state) + + if stop: + break + + # If we got any unknown options we re-combinate the string of the + # remaining options and re-attach the prefix, then report that + # to the state as new larg. This way there is basic combinatorics + # that can be achieved while still ignoring unknown arguments. + if self.ignore_unknown_options and unknown_options: + state.largs.append(f"{prefix}{''.join(unknown_options)}") + + def _get_value_from_state( + self, option_name: str, option: Option, state: ParsingState + ) -> t.Any: + nargs = option.nargs + + if len(state.rargs) < nargs: + if option.obj._flag_needs_value: + # Option allows omitting the value. + value = _flag_needs_value + else: + raise BadOptionUsage( + option_name, + ngettext( + "Option {name!r} requires an argument.", + "Option {name!r} requires {nargs} arguments.", + nargs, + ).format(name=option_name, nargs=nargs), + ) + elif nargs == 1: + next_rarg = state.rargs[0] + + if ( + option.obj._flag_needs_value + and isinstance(next_rarg, str) + and next_rarg[:1] in self._opt_prefixes + and len(next_rarg) > 1 + ): + # The next arg looks like the start of an option, don't + # use it as the value if omitting the value is allowed. + value = _flag_needs_value + else: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + return value + + def _process_opts(self, arg: str, state: ParsingState) -> None: + explicit_value = None + # Long option handling happens in two parts. The first part is + # supporting explicitly attached values. In any case, we will try + # to long match the option first. + if "=" in arg: + long_opt, explicit_value = arg.split("=", 1) + else: + long_opt = arg + norm_long_opt = normalize_opt(long_opt, self.ctx) + + # At this point we will match the (assumed) long option through + # the long option matching code. Note that this allows options + # like "-foo" to be matched as long options. + try: + self._match_long_opt(norm_long_opt, explicit_value, state) + except NoSuchOption: + # At this point the long option matching failed, and we need + # to try with short options. However there is a special rule + # which says, that if we have a two character options prefix + # (applies to "--foo" for instance), we do not dispatch to the + # short option code and will instead raise the no option + # error. + if arg[:2] not in self._opt_prefixes: + self._match_short_opt(arg, state) + return + + if not self.ignore_unknown_options: + raise + + state.largs.append(arg) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/build/__init__.py b/venv/lib/python3.9/site-packages/click/py.typed similarity index 100% rename from venv/lib/python3.8/site-packages/pip/_internal/operations/build/__init__.py rename to venv/lib/python3.9/site-packages/click/py.typed diff --git a/venv/lib/python3.9/site-packages/click/shell_completion.py b/venv/lib/python3.9/site-packages/click/shell_completion.py new file mode 100644 index 0000000..706fb69 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/shell_completion.py @@ -0,0 +1,574 @@ +import os +import re +import typing as t +from gettext import gettext as _ + +from .core import Argument +from .core import BaseCommand +from .core import Context +from .core import MultiCommand +from .core import Option +from .core import Parameter +from .core import ParameterSource +from .parser import split_arg_string +from .utils import echo + + +def shell_complete( + cli: BaseCommand, + ctx_args: t.Dict[str, t.Any], + prog_name: str, + complete_var: str, + instruction: str, +) -> int: + """Perform shell completion for the given CLI program. + + :param cli: Command being called. + :param ctx_args: Extra arguments to pass to + ``cli.make_context``. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + :param instruction: Value of ``complete_var`` with the completion + instruction and shell, in the form ``instruction_shell``. + :return: Status code to exit with. + """ + shell, _, instruction = instruction.partition("_") + comp_cls = get_completion_class(shell) + + if comp_cls is None: + return 1 + + comp = comp_cls(cli, ctx_args, prog_name, complete_var) + + if instruction == "source": + echo(comp.source()) + return 0 + + if instruction == "complete": + echo(comp.complete()) + return 0 + + return 1 + + +class CompletionItem: + """Represents a completion value and metadata about the value. The + default metadata is ``type`` to indicate special shell handling, + and ``help`` if a shell supports showing a help string next to the + value. + + Arbitrary parameters can be passed when creating the object, and + accessed using ``item.attr``. If an attribute wasn't passed, + accessing it returns ``None``. + + :param value: The completion suggestion. + :param type: Tells the shell script to provide special completion + support for the type. Click uses ``"dir"`` and ``"file"``. + :param help: String shown next to the value if supported. + :param kwargs: Arbitrary metadata. The built-in implementations + don't use this, but custom type completions paired with custom + shell support could use it. + """ + + __slots__ = ("value", "type", "help", "_info") + + def __init__( + self, + value: t.Any, + type: str = "plain", + help: t.Optional[str] = None, + **kwargs: t.Any, + ) -> None: + self.value = value + self.type = type + self.help = help + self._info = kwargs + + def __getattr__(self, name: str) -> t.Any: + return self._info.get(name) + + +# Only Bash >= 4.4 has the nosort option. +_SOURCE_BASH = """\ +%(complete_func)s() { + local IFS=$'\\n' + local response + + response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \ +%(complete_var)s=bash_complete $1) + + for completion in $response; do + IFS=',' read type value <<< "$completion" + + if [[ $type == 'dir' ]]; then + COMREPLY=() + compopt -o dirnames + elif [[ $type == 'file' ]]; then + COMREPLY=() + compopt -o default + elif [[ $type == 'plain' ]]; then + COMPREPLY+=($value) + fi + done + + return 0 +} + +%(complete_func)s_setup() { + complete -o nosort -F %(complete_func)s %(prog_name)s +} + +%(complete_func)s_setup; +""" + +_SOURCE_ZSH = """\ +#compdef %(prog_name)s + +%(complete_func)s() { + local -a completions + local -a completions_with_descriptions + local -a response + (( ! $+commands[%(prog_name)s] )) && return 1 + + response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \ +%(complete_var)s=zsh_complete %(prog_name)s)}") + + for type key descr in ${response}; do + if [[ "$type" == "plain" ]]; then + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + elif [[ "$type" == "dir" ]]; then + _path_files -/ + elif [[ "$type" == "file" ]]; then + _path_files -f + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -a completions + fi +} + +compdef %(complete_func)s %(prog_name)s; +""" + +_SOURCE_FISH = """\ +function %(complete_func)s; + set -l response; + + for value in (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ +COMP_CWORD=(commandline -t) %(prog_name)s); + set response $response $value; + end; + + for completion in $response; + set -l metadata (string split "," $completion); + + if test $metadata[1] = "dir"; + __fish_complete_directories $metadata[2]; + else if test $metadata[1] = "file"; + __fish_complete_path $metadata[2]; + else if test $metadata[1] = "plain"; + echo $metadata[2]; + end; + end; +end; + +complete --no-files --command %(prog_name)s --arguments \ +"(%(complete_func)s)"; +""" + + +class ShellComplete: + """Base class for providing shell completion support. A subclass for + a given shell will override attributes and methods to implement the + completion instructions (``source`` and ``complete``). + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + + .. versionadded:: 8.0 + """ + + name: t.ClassVar[str] + """Name to register the shell as with :func:`add_completion_class`. + This is used in completion instructions (``{name}_source`` and + ``{name}_complete``). + """ + + source_template: t.ClassVar[str] + """Completion script template formatted by :meth:`source`. This must + be provided by subclasses. + """ + + def __init__( + self, + cli: BaseCommand, + ctx_args: t.Dict[str, t.Any], + prog_name: str, + complete_var: str, + ) -> None: + self.cli = cli + self.ctx_args = ctx_args + self.prog_name = prog_name + self.complete_var = complete_var + + @property + def func_name(self) -> str: + """The name of the shell function defined by the completion + script. + """ + safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), re.ASCII) + return f"_{safe_name}_completion" + + def source_vars(self) -> t.Dict[str, t.Any]: + """Vars for formatting :attr:`source_template`. + + By default this provides ``complete_func``, ``complete_var``, + and ``prog_name``. + """ + return { + "complete_func": self.func_name, + "complete_var": self.complete_var, + "prog_name": self.prog_name, + } + + def source(self) -> str: + """Produce the shell script that defines the completion + function. By default this ``%``-style formats + :attr:`source_template` with the dict returned by + :meth:`source_vars`. + """ + return self.source_template % self.source_vars() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + """Use the env vars defined by the shell script to return a + tuple of ``args, incomplete``. This must be implemented by + subclasses. + """ + raise NotImplementedError + + def get_completions( + self, args: t.List[str], incomplete: str + ) -> t.List[CompletionItem]: + """Determine the context and last complete command or parameter + from the complete args. Call that object's ``shell_complete`` + method to get the completions for the incomplete value. + + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args) + obj, incomplete = _resolve_incomplete(ctx, args, incomplete) + return obj.shell_complete(ctx, incomplete) + + def format_completion(self, item: CompletionItem) -> str: + """Format a completion item into the form recognized by the + shell script. This must be implemented by subclasses. + + :param item: Completion item to format. + """ + raise NotImplementedError + + def complete(self) -> str: + """Produce the completion data to send back to the shell. + + By default this calls :meth:`get_completion_args`, gets the + completions, then calls :meth:`format_completion` for each + completion. + """ + args, incomplete = self.get_completion_args() + completions = self.get_completions(args, incomplete) + out = [self.format_completion(item) for item in completions] + return "\n".join(out) + + +class BashComplete(ShellComplete): + """Shell completion for Bash.""" + + name = "bash" + source_template = _SOURCE_BASH + + def _check_version(self) -> None: + import subprocess + + output = subprocess.run(["bash", "--version"], stdout=subprocess.PIPE) + match = re.search(r"version (\d)\.(\d)\.\d", output.stdout.decode()) + + if match is not None: + major, minor = match.groups() + + if major < "4" or major == "4" and minor < "4": + raise RuntimeError( + _( + "Shell completion is not supported for Bash" + " versions older than 4.4." + ) + ) + else: + raise RuntimeError( + _("Couldn't detect Bash version, shell completion is not supported.") + ) + + def source(self) -> str: + self._check_version() + return super().source() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type},{item.value}" + + +class ZshComplete(ShellComplete): + """Shell completion for Zsh.""" + + name = "zsh" + source_template = _SOURCE_ZSH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}" + + +class FishComplete(ShellComplete): + """Shell completion for Fish.""" + + name = "fish" + source_template = _SOURCE_FISH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + incomplete = os.environ["COMP_CWORD"] + args = cwords[1:] + + # Fish stores the partial word in both COMP_WORDS and + # COMP_CWORD, remove it from complete args. + if incomplete and args and args[-1] == incomplete: + args.pop() + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + if item.help: + return f"{item.type},{item.value}\t{item.help}" + + return f"{item.type},{item.value}" + + +_available_shells: t.Dict[str, t.Type[ShellComplete]] = { + "bash": BashComplete, + "fish": FishComplete, + "zsh": ZshComplete, +} + + +def add_completion_class( + cls: t.Type[ShellComplete], name: t.Optional[str] = None +) -> None: + """Register a :class:`ShellComplete` subclass under the given name. + The name will be provided by the completion instruction environment + variable during completion. + + :param cls: The completion class that will handle completion for the + shell. + :param name: Name to register the class under. Defaults to the + class's ``name`` attribute. + """ + if name is None: + name = cls.name + + _available_shells[name] = cls + + +def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]: + """Look up a registered :class:`ShellComplete` subclass by the name + provided by the completion instruction environment variable. If the + name isn't registered, returns ``None``. + + :param shell: Name the class is registered under. + """ + return _available_shells.get(shell) + + +def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: + """Determine if the given parameter is an argument that can still + accept values. + + :param ctx: Invocation context for the command represented by the + parsed complete args. + :param param: Argument object being checked. + """ + if not isinstance(param, Argument): + return False + + assert param.name is not None + value = ctx.params[param.name] + return ( + param.nargs == -1 + or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE + or ( + param.nargs > 1 + and isinstance(value, (tuple, list)) + and len(value) < param.nargs + ) + ) + + +def _start_of_option(value: str) -> bool: + """Check if the value looks like the start of an option.""" + return not value[0].isalnum() if value else False + + +def _is_incomplete_option(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: + return False + + last_option = None + + for index, arg in enumerate(reversed(args)): + if index + 1 > param.nargs: + break + + if _start_of_option(arg): + last_option = arg + + return last_option is not None and last_option in param.opts + + +def _resolve_context( + cli: BaseCommand, ctx_args: t.Dict[str, t.Any], prog_name: str, args: t.List[str] +) -> Context: + """Produce the context hierarchy starting with the command and + traversing the complete arguments. This only follows the commands, + it doesn't trigger input prompts or callbacks. + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param args: List of complete args before the incomplete value. + """ + ctx_args["resilient_parsing"] = True + ctx = cli.make_context(prog_name, args.copy(), **ctx_args) + args = ctx.protected_args + ctx.args + + while args: + command = ctx.command + + if isinstance(command, MultiCommand): + if not command.chain: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True) + args = ctx.protected_args + ctx.args + else: + while args: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + sub_ctx = cmd.make_context( + name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + resilient_parsing=True, + ) + args = sub_ctx.args + + ctx = sub_ctx + args = [*sub_ctx.protected_args, *sub_ctx.args] + else: + break + + return ctx + + +def _resolve_incomplete( + ctx: Context, args: t.List[str], incomplete: str +) -> t.Tuple[t.Union[BaseCommand, Parameter], str]: + """Find the Click object that will handle the completion of the + incomplete value. Return the object and the incomplete value. + + :param ctx: Invocation context for the command represented by + the parsed complete args. + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + # Different shells treat an "=" between a long option name and + # value differently. Might keep the value joined, return the "=" + # as a separate item, or return the split name and value. Always + # split and discard the "=" to make completion easier. + if incomplete == "=": + incomplete = "" + elif "=" in incomplete and _start_of_option(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(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(args, param): + return param, incomplete + + # It's not an option name or value. The first argument without a + # parsed value will provide value completions. + for param in params: + if _is_incomplete_argument(ctx, param): + return param, incomplete + + # There were no unparsed arguments, the command may be a group that + # will provide command name completions. + return ctx.command, incomplete diff --git a/venv/lib/python3.9/site-packages/click/termui.py b/venv/lib/python3.9/site-packages/click/termui.py new file mode 100644 index 0000000..034fe6e --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/termui.py @@ -0,0 +1,807 @@ +import inspect +import io +import itertools +import os +import sys +import typing +import typing as t +from gettext import gettext as _ + +from ._compat import isatty +from ._compat import strip_ansi +from ._compat import WIN +from .exceptions import Abort +from .exceptions import UsageError +from .globals import resolve_color_default +from .types import Choice +from .types import convert_type +from .types import ParamType +from .utils import echo +from .utils import LazyFile + +if t.TYPE_CHECKING: + from ._termui_impl import ProgressBar + +V = t.TypeVar("V") + +# The prompt functions to use. The doc tools currently override these +# functions to customize how they work. +visible_prompt_func: t.Callable[[str], str] = input + +_ansi_colors = { + "black": 30, + "red": 31, + "green": 32, + "yellow": 33, + "blue": 34, + "magenta": 35, + "cyan": 36, + "white": 37, + "reset": 39, + "bright_black": 90, + "bright_red": 91, + "bright_green": 92, + "bright_yellow": 93, + "bright_blue": 94, + "bright_magenta": 95, + "bright_cyan": 96, + "bright_white": 97, +} +_ansi_reset_all = "\033[0m" + + +def hidden_prompt_func(prompt: str) -> str: + import getpass + + return getpass.getpass(prompt) + + +def _build_prompt( + text: str, + suffix: str, + show_default: bool = False, + default: t.Optional[t.Any] = None, + show_choices: bool = True, + type: t.Optional[ParamType] = None, +) -> str: + prompt = text + if type is not None and show_choices and isinstance(type, Choice): + prompt += f" ({', '.join(map(str, type.choices))})" + if default is not None and show_default: + prompt = f"{prompt} [{_format_default(default)}]" + return f"{prompt}{suffix}" + + +def _format_default(default: t.Any) -> t.Any: + if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): + return default.name # type: ignore + + return default + + +def prompt( + text: str, + default: t.Optional[t.Any] = None, + hide_input: bool = False, + confirmation_prompt: t.Union[bool, str] = False, + type: t.Optional[ParamType] = 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 a 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() + + 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 = t.cast(str, confirmation_prompt) + 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: + confirmation_prompt = t.cast(str, confirmation_prompt) + value2 = prompt_func(confirmation_prompt) + if value2: + 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, nl=False, err=err) + value = visible_prompt_func("").lower().strip() + except (KeyboardInterrupt, EOFError): + raise Abort() + 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 get_terminal_size() -> os.terminal_size: + """Returns the current size of the terminal as tuple in the form + ``(width, height)`` in columns and rows. + + .. deprecated:: 8.0 + Will be removed in Click 8.1. Use + :func:`shutil.get_terminal_size` instead. + """ + import shutil + import warnings + + warnings.warn( + "'click.get_terminal_size()' is deprecated and will be removed" + " in Click 8.1. Use 'shutil.get_terminal_size()' instead.", + DeprecationWarning, + stacklevel=2, + ) + return shutil.get_terminal_size() + + +def echo_via_pager( + text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], + color: t.Optional[bool] = None, +) -> None: + """This function takes a text and shows it via an environment specific + pager on stdout. + + .. versionchanged:: 3.0 + Added the `color` flag. + + :param text_or_generator: the text to page, or alternatively, a + generator emitting the text to page. + :param color: controls if the pager supports ANSI colors or not. The + default is autodetection. + """ + color = resolve_color_default(color) + + if inspect.isgeneratorfunction(text_or_generator): + i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)() + elif isinstance(text_or_generator, str): + i = [text_or_generator] + else: + i = iter(t.cast(t.Iterable[str], text_or_generator)) + + # convert every element of i to a text type if necessary + text_generator = (el if isinstance(el, str) else str(el) for el in i) + + from ._termui_impl import pager + + return pager(itertools.chain(text_generator, "\n"), color) + + +def progressbar( + iterable: t.Optional[t.Iterable[V]] = None, + length: t.Optional[int] = None, + label: t.Optional[str] = None, + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + fill_char: str = "#", + empty_char: str = "-", + bar_template: str = "%(label)s [%(bar)s] %(info)s", + info_sep: str = " ", + width: int = 36, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, +) -> "ProgressBar[V]": + """This function creates an iterable context manager that can be used + to iterate over something while showing a progress bar. It will + either iterate over the `iterable` or `length` items (that are counted + up). While iteration happens, this function will print a rendered + progress bar to the given `file` (defaults to stdout) and will attempt + to calculate remaining time and more. By default, this progress bar + will not be rendered if the file is not a terminal. + + The context manager creates the progress bar. When the context + manager is entered the progress bar is already created. With every + iteration over the progress bar, the iterable passed to the bar is + advanced and the bar is updated. When the context manager exits, + a newline is printed and the progress bar is finalized on screen. + + Note: The progress bar is currently designed for use cases where the + total progress can be expected to take at least several seconds. + Because of this, the ProgressBar class object won't display + progress that is considered too fast, and progress where the time + between steps is less than a second. + + No printing must happen or the progress bar will be unintentionally + destroyed. + + Example usage:: + + with progressbar(items) as bar: + for item in bar: + do_something_with(item) + + Alternatively, if no iterable is specified, one can manually update the + progress bar through the `update()` method instead of directly + iterating over the progress bar. The update method accepts the number + of steps to increment the bar with:: + + with progressbar(length=chunks.total_bytes) as bar: + for chunk in chunks: + process_chunk(chunk) + bar.update(chunks.bytes) + + The ``update()`` method also takes an optional value specifying the + ``current_item`` at the new position. This is useful when used + together with ``item_show_func`` to customize the output for each + manual step:: + + with click.progressbar( + length=total_size, + label='Unzipping archive', + item_show_func=lambda a: a.filename + ) as bar: + for archive in zip_file: + archive.extract() + bar.update(archive.size, archive) + + :param iterable: an iterable to iterate over. If not provided the length + is required. + :param length: the number of items to iterate over. By default the + progressbar will attempt to ask the iterator about its + length, which might or might not work. If an iterable is + also provided this parameter can be used to override the + length. If an iterable is not provided the progress bar + will iterate over a range of that length. + :param label: the label to show next to the progress bar. + :param show_eta: enables or disables the estimated time display. This is + automatically disabled if the length cannot be + determined. + :param show_percent: enables or disables the percentage display. The + default is `True` if the iterable has a length or + `False` if not. + :param show_pos: enables or disables the absolute position display. The + default is `False`. + :param item_show_func: A function called with the current item which + can return a string to show next to the progress bar. If the + function returns ``None`` nothing is shown. The current item can + be ``None``, such as when entering and exiting the bar. + :param fill_char: the character to use to show the filled part of the + progress bar. + :param empty_char: the character to use to show the non-filled part of + the progress bar. + :param bar_template: the format string to use as template for the bar. + The parameters in it are ``label`` for the label, + ``bar`` for the progress bar and ``info`` for the + info section. + :param info_sep: the separator between multiple info items (eta etc.) + :param width: the width of the progress bar in characters, 0 means full + terminal width + :param file: The file to write to. If this is not a terminal then + only the label is printed. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are included anywhere in the progress bar output + which is not the case by default. + :param update_min_steps: Render only when this many updates have + completed. This allows tuning for very fast iterators. + + .. versionchanged:: 8.0 + Output is shown even if execution time is less than 0.5 seconds. + + .. versionchanged:: 8.0 + ``item_show_func`` shows the current item, not the previous one. + + .. versionchanged:: 8.0 + Labels are echoed if the output is not a TTY. Reverts a change + in 7.0 that removed all output. + + .. versionadded:: 8.0 + Added the ``update_min_steps`` parameter. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. Added the ``update`` method to + the object. + + .. versionadded:: 2.0 + """ + from ._termui_impl import ProgressBar + + color = resolve_color_default(color) + return ProgressBar( + iterable=iterable, + length=length, + show_eta=show_eta, + show_percent=show_percent, + show_pos=show_pos, + item_show_func=item_show_func, + fill_char=fill_char, + empty_char=empty_char, + bar_template=bar_template, + info_sep=info_sep, + file=file, + label=label, + width=width, + color=color, + update_min_steps=update_min_steps, + ) + + +def clear() -> None: + """Clears the terminal screen. This will have the effect of clearing + the whole visible space of the terminal and moving the cursor to the + top left. This does not do anything if not connected to a terminal. + + .. versionadded:: 2.0 + """ + if not isatty(sys.stdout): + return + if WIN: + os.system("cls") + else: + sys.stdout.write("\033[2J\033[1;1H") + + +def _interpret_color( + color: t.Union[int, t.Tuple[int, int, int], str], offset: int = 0 +) -> str: + if isinstance(color, int): + return f"{38 + offset};5;{color:d}" + + if isinstance(color, (tuple, list)): + r, g, b = color + return f"{38 + offset};2;{r:d};{g:d};{b:d}" + + return str(_ansi_colors[color] + offset) + + +def style( + text: t.Any, + fg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bold: t.Optional[bool] = None, + dim: t.Optional[bool] = None, + underline: t.Optional[bool] = None, + overline: t.Optional[bool] = None, + italic: t.Optional[bool] = None, + blink: t.Optional[bool] = None, + reverse: t.Optional[bool] = None, + strikethrough: t.Optional[bool] = None, + reset: bool = True, +) -> str: + """Styles a text with ANSI styles and returns the new string. By + default the styling is self contained which means that at the end + of the string a reset code is issued. This can be prevented by + passing ``reset=False``. + + Examples:: + + click.echo(click.style('Hello World!', fg='green')) + click.echo(click.style('ATTENTION!', blink=True)) + click.echo(click.style('Some things', reverse=True, fg='cyan')) + click.echo(click.style('More colors', fg=(255, 12, 128), bg=117)) + + Supported color names: + + * ``black`` (might be a gray) + * ``red`` + * ``green`` + * ``yellow`` (might be an orange) + * ``blue`` + * ``magenta`` + * ``cyan`` + * ``white`` (might be light gray) + * ``bright_black`` + * ``bright_red`` + * ``bright_green`` + * ``bright_yellow`` + * ``bright_blue`` + * ``bright_magenta`` + * ``bright_cyan`` + * ``bright_white`` + * ``reset`` (reset the color code only) + + If the terminal supports it, color may also be specified as: + + - An integer in the interval [0, 255]. The terminal must support + 8-bit/256-color mode. + - An RGB tuple of three integers in [0, 255]. The terminal must + support 24-bit/true-color mode. + + See https://en.wikipedia.org/wiki/ANSI_color and + https://gist.github.com/XVilka/8346728 for more information. + + :param text: the string to style with ansi codes. + :param fg: if provided this will become the foreground color. + :param bg: if provided this will become the background color. + :param bold: if provided this will enable or disable bold mode. + :param dim: if provided this will enable or disable dim mode. This is + badly supported. + :param underline: if provided this will enable or disable underline. + :param overline: if provided this will enable or disable overline. + :param italic: if provided this will enable or disable italic. + :param blink: if provided this will enable or disable blinking. + :param reverse: if provided this will enable or disable inverse + rendering (foreground becomes background and the + other way round). + :param strikethrough: if provided this will enable or disable + striking through text. + :param reset: by default a reset-all code is added at the end of the + string which means that styles do not carry over. This + can be disabled to compose styles. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. + + .. versionchanged:: 8.0 + Added support for 256 and RGB color codes. + + .. versionchanged:: 8.0 + Added the ``strikethrough``, ``italic``, and ``overline`` + parameters. + + .. versionchanged:: 7.0 + Added support for bright colors. + + .. versionadded:: 2.0 + """ + if not isinstance(text, str): + text = str(text) + + bits = [] + + if fg: + try: + bits.append(f"\033[{_interpret_color(fg)}m") + except KeyError: + raise TypeError(f"Unknown color {fg!r}") + + if bg: + try: + bits.append(f"\033[{_interpret_color(bg, 10)}m") + except KeyError: + raise TypeError(f"Unknown color {bg!r}") + + 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 underline else 55}m") + if italic is not None: + bits.append(f"\033[{5 if underline 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] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, + **styles: t.Any, +) -> None: + """This function combines :func:`echo` and :func:`style` into one + call. As such the following two calls are the same:: + + click.secho('Hello World!', fg='green') + click.echo(click.style('Hello World!', fg='green')) + + All keyword arguments are forwarded to the underlying functions + depending on which one they go with. + + Non-string types will be converted to :class:`str`. However, + :class:`bytes` are passed directly to :meth:`echo` without applying + style. If you want to style bytes that represent text, call + :meth:`bytes.decode` first. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. Bytes are + passed through without style applied. + + .. versionadded:: 2.0 + """ + if message is not None and not isinstance(message, (bytes, bytearray)): + message = style(message, **styles) + + return echo(message, file=file, nl=nl, err=err, color=color) + + +def edit( + text: t.Optional[t.AnyStr] = None, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + filename: t.Optional[str] = None, +) -> t.Optional[t.AnyStr]: + r"""Edits the given text in the defined editor. If an editor is given + (should be the full path to the executable but the regular operating + system search path is used for finding the executable) it overrides + the detected editor. Optionally, some environment variables can be + used. If the editor is closed without changes, `None` is returned. In + case a file is edited directly the return value is always `None` and + `require_save` and `extension` are ignored. + + If the editor cannot be opened a :exc:`UsageError` is raised. + + Note for Windows: to simplify cross-platform usage, the newlines are + automatically converted from POSIX to Windows and vice versa. As such, + the message here will have ``\n`` as newline markers. + + :param text: the text to edit. + :param editor: optionally the editor to use. Defaults to automatic + detection. + :param env: environment variables to forward to the editor. + :param require_save: if this is true, then not saving in the editor + will make the return value become `None`. + :param extension: the extension to tell the editor about. This defaults + to `.txt` but changing this might change syntax + highlighting. + :param filename: if provided it will edit this file instead of the + provided text contents. It will not use a temporary + file as an indirection in that case. + """ + from ._termui_impl import Editor + + ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension) + + if filename is None: + return ed.edit(text) + + ed.edit_file(filename) + return None + + +def launch(url: str, wait: bool = False, locate: bool = False) -> int: + """This function launches the given URL (or filename) in the default + viewer application for this file type. If this is an executable, it + might launch the executable in a new session. The return value is + the exit code of the launched application. Usually, ``0`` indicates + success. + + Examples:: + + click.launch('https://click.palletsprojects.com/') + click.launch('/my/downloaded/file', locate=True) + + .. versionadded:: 2.0 + + :param url: URL or filename of the thing to launch. + :param wait: Wait for the program to exit before returning. This + only works if the launched program blocks. In particular, + ``xdg-open`` on Linux does not block. + :param locate: if this is set to `True` then instead of launching the + application associated with the URL it will attempt to + launch a file manager with the file located. This + might have weird effects if the URL does not point to + the filesystem. + """ + from ._termui_impl import open_url + + return open_url(url, wait=wait, locate=locate) + + +# If this is provided, getchar() calls into this instead. This is used +# for unittesting purposes. +_getchar: t.Optional[t.Callable[[bool], str]] = None + + +def getchar(echo: bool = False) -> str: + """Fetches a single character from the terminal and returns it. This + will always return a unicode character and under certain rare + circumstances this might return more than one character. The + situations which more than one character is returned is when for + whatever reason multiple characters end up in the terminal buffer or + standard input was not actually a terminal. + + Note that this will always read from the terminal, even if something + is piped into the standard input. + + Note for Windows: in rare cases when typing non-ASCII characters, this + function might wait for a second character and then return both at once. + This is because certain Unicode characters look like special-key markers. + + .. versionadded:: 2.0 + + :param echo: if set to `True`, the character read will also show up on + the terminal. The default is to not show it. + """ + global _getchar + + if _getchar is None: + from ._termui_impl import getchar as f + + _getchar = f + + return _getchar(echo) + + +def raw_terminal() -> t.ContextManager[int]: + from ._termui_impl import raw_terminal as f + + return f() + + +def pause(info: t.Optional[str] = None, err: bool = False) -> None: + """This command stops execution and waits for the user to press any + key to continue. This is similar to the Windows batch "pause" + command. If the program is not run through a terminal, this command + will instead do nothing. + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param info: The message to print before pausing. Defaults to + ``"Press any key to continue..."``. + :param err: if set to message goes to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + if not isatty(sys.stdin) or not isatty(sys.stdout): + return + + if info is None: + info = _("Press any key to continue...") + + try: + if info: + echo(info, nl=False, err=err) + try: + getchar() + except (KeyboardInterrupt, EOFError): + pass + finally: + if info: + echo(err=err) diff --git a/venv/lib/python3.9/site-packages/click/testing.py b/venv/lib/python3.9/site-packages/click/testing.py new file mode 100644 index 0000000..d19b850 --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/testing.py @@ -0,0 +1,479 @@ +import contextlib +import io +import os +import shlex +import shutil +import sys +import tempfile +import typing as t +from types import TracebackType + +from . import formatting +from . import termui +from . import utils +from ._compat import _find_binary_reader + +if t.TYPE_CHECKING: + from .core import BaseCommand + + +class EchoingStdin: + def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None: + self._input = input + self._output = output + self._paused = False + + def __getattr__(self, x: str) -> t.Any: + return getattr(self._input, x) + + def _echo(self, rv: bytes) -> bytes: + if not self._paused: + self._output.write(rv) + + return rv + + def read(self, n: int = -1) -> bytes: + return self._echo(self._input.read(n)) + + def read1(self, n: int = -1) -> bytes: + return self._echo(self._input.read1(n)) # type: ignore + + def readline(self, n: int = -1) -> bytes: + return self._echo(self._input.readline(n)) + + def readlines(self) -> t.List[bytes]: + return [self._echo(x) for x in self._input.readlines()] + + def __iter__(self) -> t.Iterator[bytes]: + return iter(self._echo(x) for x in self._input) + + def __repr__(self) -> str: + return repr(self._input) + + +@contextlib.contextmanager +def _pause_echo(stream: t.Optional[EchoingStdin]) -> t.Iterator[None]: + if stream is None: + yield + else: + stream._paused = True + yield + stream._paused = False + + +class _NamedTextIOWrapper(io.TextIOWrapper): + def __init__( + self, buffer: t.BinaryIO, name: str, mode: str, **kwargs: t.Any + ) -> None: + super().__init__(buffer, **kwargs) + self._name = name + self._mode = mode + + @property + def name(self) -> str: + return self._name + + @property + def mode(self) -> str: + return self._mode + + +def make_input_stream( + input: t.Optional[t.Union[str, bytes, t.IO]], charset: str +) -> t.BinaryIO: + # Is already an input stream. + if hasattr(input, "read"): + rv = _find_binary_reader(t.cast(t.IO, input)) + + if rv is not None: + return rv + + raise TypeError("Could not find binary reader for input stream.") + + if input is None: + input = b"" + elif isinstance(input, str): + input = input.encode(charset) + + return io.BytesIO(t.cast(bytes, input)) + + +class Result: + """Holds the captured result of an invoked CLI script.""" + + def __init__( + self, + runner: "CliRunner", + stdout_bytes: bytes, + stderr_bytes: t.Optional[bytes], + return_value: t.Any, + exit_code: int, + exception: t.Optional[BaseException], + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ] = None, + ): + #: The runner that created the result + self.runner = runner + #: The standard output as bytes. + self.stdout_bytes = stdout_bytes + #: The standard error as bytes, or None if not available + self.stderr_bytes = stderr_bytes + #: The value returned from the invoked command. + #: + #: .. versionadded:: 8.0 + self.return_value = return_value + #: The exit code as integer. + self.exit_code = exit_code + #: The exception that happened if one did. + self.exception = exception + #: The traceback + self.exc_info = exc_info + + @property + def output(self) -> str: + """The (standard) output as unicode string.""" + return self.stdout + + @property + def stdout(self) -> str: + """The standard output as unicode string.""" + return self.stdout_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + @property + def stderr(self) -> str: + """The standard error as unicode string.""" + if self.stderr_bytes is None: + raise ValueError("stderr not separately captured") + return self.stderr_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + def __repr__(self) -> str: + exc_str = repr(self.exception) if self.exception else "okay" + return f"<{type(self).__name__} {exc_str}>" + + +class CliRunner: + """The CLI runner provides functionality to invoke a Click command line + script for unittesting purposes in a isolated environment. This only + works in single-threaded systems without any concurrency as it changes the + global interpreter state. + + :param charset: the character set for the input and output data. + :param env: a dictionary with environment variables for overriding. + :param echo_stdin: if this is set to `True`, then reading from stdin writes + to stdout. This is useful for showing examples in + some circumstances. Note that regular prompts + will automatically echo the input. + :param mix_stderr: if this is set to `False`, then stdout and stderr are + preserved as independent streams. This is useful for + Unix-philosophy apps that have predictable stdout and + noisy stderr, such that each may be measured + independently + """ + + def __init__( + self, + charset: str = "utf-8", + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + echo_stdin: bool = False, + mix_stderr: bool = True, + ) -> None: + self.charset = charset + self.env = env or {} + self.echo_stdin = echo_stdin + self.mix_stderr = mix_stderr + + def get_default_prog_name(self, cli: "BaseCommand") -> str: + """Given a command object it will return the default program name + for it. The default is the `name` attribute or ``"root"`` if not + set. + """ + return cli.name or "root" + + def make_env( + self, overrides: t.Optional[t.Mapping[str, t.Optional[str]]] = None + ) -> t.Mapping[str, t.Optional[str]]: + """Returns the environment overrides for invoking a script.""" + rv = dict(self.env) + if overrides: + rv.update(overrides) + return rv + + @contextlib.contextmanager + def isolation( + self, + input: t.Optional[t.Union[str, bytes, t.IO]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + color: bool = False, + ) -> t.Iterator[t.Tuple[io.BytesIO, t.Optional[io.BytesIO]]]: + """A context manager that sets up the isolation for invoking of a + command line tool. This sets up stdin with the given input data + and `os.environ` with the overrides from the given dictionary. + This also rebinds some internals in Click to be mocked (like the + prompt functionality). + + This is automatically done in the :meth:`invoke` method. + + :param input: the input stream to put into sys.stdin. + :param env: the environment overrides as dictionary. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + ``stderr`` is opened with ``errors="backslashreplace"`` + instead of the default ``"strict"``. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + """ + bytes_input = make_input_stream(input, self.charset) + echo_input = None + + old_stdin = sys.stdin + old_stdout = sys.stdout + old_stderr = sys.stderr + old_forced_width = formatting.FORCED_WIDTH + formatting.FORCED_WIDTH = 80 + + env = self.make_env(env) + + bytes_output = io.BytesIO() + + if self.echo_stdin: + bytes_input = echo_input = t.cast( + t.BinaryIO, EchoingStdin(bytes_input, bytes_output) + ) + + sys.stdin = text_input = _NamedTextIOWrapper( + bytes_input, encoding=self.charset, name="", mode="r" + ) + + if self.echo_stdin: + # Force unbuffered reads, otherwise TextIOWrapper reads a + # large chunk which is echoed early. + text_input._CHUNK_SIZE = 1 # type: ignore + + sys.stdout = _NamedTextIOWrapper( + bytes_output, encoding=self.charset, name="", mode="w" + ) + + bytes_error = None + if self.mix_stderr: + sys.stderr = sys.stdout + else: + bytes_error = io.BytesIO() + sys.stderr = _NamedTextIOWrapper( + bytes_error, + encoding=self.charset, + name="", + mode="w", + errors="backslashreplace", + ) + + @_pause_echo(echo_input) # type: ignore + def visible_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(prompt or "") + val = text_input.readline().rstrip("\r\n") + sys.stdout.write(f"{val}\n") + sys.stdout.flush() + return val + + @_pause_echo(echo_input) # type: ignore + def hidden_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(f"{prompt or ''}\n") + sys.stdout.flush() + return text_input.readline().rstrip("\r\n") + + @_pause_echo(echo_input) # type: ignore + def _getchar(echo: bool) -> str: + char = sys.stdin.read(1) + + if echo: + sys.stdout.write(char) + + sys.stdout.flush() + return char + + default_color = color + + def should_strip_ansi( + stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None + ) -> bool: + if color is None: + return not default_color + return not color + + old_visible_prompt_func = termui.visible_prompt_func + old_hidden_prompt_func = termui.hidden_prompt_func + old__getchar_func = termui._getchar + old_should_strip_ansi = utils.should_strip_ansi # type: ignore + termui.visible_prompt_func = visible_input + termui.hidden_prompt_func = hidden_input + termui._getchar = _getchar + utils.should_strip_ansi = should_strip_ansi # type: ignore + + old_env = {} + try: + for key, value in env.items(): + old_env[key] = os.environ.get(key) + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + yield (bytes_output, bytes_error) + finally: + for key, value in old_env.items(): + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + sys.stdout = old_stdout + sys.stderr = old_stderr + sys.stdin = old_stdin + termui.visible_prompt_func = old_visible_prompt_func + termui.hidden_prompt_func = old_hidden_prompt_func + termui._getchar = old__getchar_func + utils.should_strip_ansi = old_should_strip_ansi # type: ignore + formatting.FORCED_WIDTH = old_forced_width + + def invoke( + self, + cli: "BaseCommand", + args: t.Optional[t.Union[str, t.Sequence[str]]] = None, + input: t.Optional[t.Union[str, bytes, t.IO]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + catch_exceptions: bool = True, + color: bool = False, + **extra: t.Any, + ) -> Result: + """Invokes a command in an isolated environment. The arguments are + forwarded directly to the command line script, the `extra` keyword + arguments are passed to the :meth:`~clickpkg.Command.main` function of + the command. + + This returns a :class:`Result` object. + + :param cli: the command to invoke + :param args: the arguments to invoke. It may be given as an iterable + or a string. When given as string it will be interpreted + as a Unix shell command. More details at + :func:`shlex.split`. + :param input: the input data for `sys.stdin`. + :param env: the environment overrides. + :param catch_exceptions: Whether to catch any other exceptions than + ``SystemExit``. + :param extra: the keyword arguments to pass to :meth:`main`. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + The result object has the ``return_value`` attribute with + the value returned from the invoked command. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionchanged:: 3.0 + Added the ``catch_exceptions`` parameter. + + .. versionchanged:: 3.0 + The result object has the ``exc_info`` attribute with the + traceback if available. + """ + exc_info = None + with self.isolation(input=input, env=env, color=color) as outstreams: + return_value = None + exception: t.Optional[BaseException] = None + exit_code = 0 + + if isinstance(args, str): + args = shlex.split(args) + + try: + prog_name = extra.pop("prog_name") + except KeyError: + prog_name = self.get_default_prog_name(cli) + + try: + return_value = cli.main(args=args or (), prog_name=prog_name, **extra) + except SystemExit as e: + exc_info = sys.exc_info() + e_code = t.cast(t.Optional[t.Union[int, t.Any]], e.code) + + if e_code is None: + e_code = 0 + + if e_code != 0: + exception = e + + if not isinstance(e_code, int): + sys.stdout.write(str(e_code)) + sys.stdout.write("\n") + e_code = 1 + + exit_code = e_code + + except Exception as e: + if not catch_exceptions: + raise + exception = e + exit_code = 1 + exc_info = sys.exc_info() + finally: + sys.stdout.flush() + stdout = outstreams[0].getvalue() + if self.mix_stderr: + stderr = None + else: + stderr = outstreams[1].getvalue() # type: ignore + + return Result( + runner=self, + stdout_bytes=stdout, + stderr_bytes=stderr, + return_value=return_value, + exit_code=exit_code, + exception=exception, + exc_info=exc_info, # type: ignore + ) + + @contextlib.contextmanager + def isolated_filesystem( + self, temp_dir: t.Optional[t.Union[str, os.PathLike]] = None + ) -> t.Iterator[str]: + """A context manager that creates a temporary directory and + changes the current working directory to it. This isolates tests + that affect the contents of the CWD to prevent them from + interfering with each other. + + :param temp_dir: Create the temporary directory under this + directory. If given, the created directory is not removed + when exiting. + + .. versionchanged:: 8.0 + Added the ``temp_dir`` parameter. + """ + cwd = os.getcwd() + t = tempfile.mkdtemp(dir=temp_dir) + os.chdir(t) + + try: + yield t + finally: + os.chdir(cwd) + + if temp_dir is None: + try: + shutil.rmtree(t) + except OSError: # noqa: B014 + pass diff --git a/venv/lib/python3.9/site-packages/click/types.py b/venv/lib/python3.9/site-packages/click/types.py new file mode 100644 index 0000000..21f0e4f --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/types.py @@ -0,0 +1,1052 @@ +import os +import stat +import typing as t +from datetime import datetime +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import _get_argv_encoding +from ._compat import get_filesystem_encoding +from ._compat import open_stream +from .exceptions import BadParameter +from .utils import LazyFile +from .utils import safecall + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + from .core import Parameter + from .shell_completion import CompletionItem + + +class ParamType: + """Represents the type of a parameter. Validates and converts values + from the command line or Python into the correct type. + + To implement a custom type, subclass and implement at least the + following: + + - The :attr:`name` class attribute must be set. + - Calling an instance of the type with ``None`` must return + ``None``. This is already implemented by default. + - :meth:`convert` must convert string values to the correct type. + - :meth:`convert` must accept values that are already the correct + type. + - It must be able to convert a value if the ``ctx`` and ``param`` + arguments are ``None``. This can occur when converting prompt + input. + """ + + is_composite: t.ClassVar[bool] = False + arity: t.ClassVar[int] = 1 + + #: the descriptive name of this type + name: str + + #: if a list of this type is expected and the value is pulled from a + #: string environment variable, this is what splits it up. `None` + #: means any whitespace. For all parameters the general rule is that + #: whitespace splits them up. The exception are paths and files which + #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on + #: Windows). + envvar_list_splitter: t.ClassVar[t.Optional[str]] = None + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + # The class name without the "ParamType" suffix. + param_type = type(self).__name__.partition("ParamType")[0] + param_type = param_type.partition("ParameterType")[0] + return {"param_type": param_type, "name": self.name} + + def __call__( + self, + value: t.Any, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> t.Any: + if value is not None: + return self.convert(value, param, ctx) + + def get_metavar(self, param: "Parameter") -> t.Optional[str]: + """Returns the metavar default for this param if it provides one.""" + + def get_missing_message(self, param: "Parameter") -> t.Optional[str]: + """Optionally might return extra information about a missing + parameter. + + .. versionadded:: 2.0 + """ + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + """Convert the value to the correct type. This is not called if + the value is ``None`` (the missing value). + + This must accept string values from the command line, as well as + values that are already the correct type. It may also convert + other compatible types. + + The ``param`` and ``ctx`` arguments may be ``None`` in certain + situations, such as when converting prompt input. + + If the value cannot be converted, call :meth:`fail` with a + descriptive message. + + :param value: The value to convert. + :param param: The parameter that is using this type to convert + its value. May be ``None``. + :param ctx: The current context that arrived at this value. May + be ``None``. + """ + return value + + def split_envvar_value(self, rv: str) -> t.Sequence[str]: + """Given a value from an environment variable this splits it up + into small chunks depending on the defined envvar list splitter. + + If the splitter is set to `None`, which means that whitespace splits, + then leading and trailing whitespace is ignored. Otherwise, leading + and trailing splitters usually lead to empty items being included. + """ + return (rv or "").split(self.envvar_list_splitter) + + def fail( + self, + message: str, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> "t.NoReturn": + """Helper method to fail with an invalid value message.""" + raise BadParameter(message, ctx=ctx, param=param) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a list of + :class:`~click.shell_completion.CompletionItem` objects for the + incomplete value. Most types do not provide completions, but + some do, and this allows custom types to provide custom + completions as well. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + return [] + + +class CompositeParamType(ParamType): + is_composite = True + + @property + def arity(self) -> int: # type: ignore + raise NotImplementedError() + + +class FuncParamType(ParamType): + def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None: + self.name = func.__name__ + self.func = func + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["func"] = self.func + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self.func(value) + except ValueError: + try: + value = str(value) + except UnicodeError: + value = value.decode("utf-8", "replace") + + self.fail(value, param, ctx) + + +class UnprocessedParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + return value + + def __repr__(self) -> str: + return "UNPROCESSED" + + +class StringParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, bytes): + enc = _get_argv_encoding() + try: + value = value.decode(enc) + except UnicodeError: + fs_enc = get_filesystem_encoding() + if fs_enc != enc: + try: + value = value.decode(fs_enc) + except UnicodeError: + value = value.decode("utf-8", "replace") + else: + value = value.decode("utf-8", "replace") + return value + return str(value) + + def __repr__(self) -> str: + return "STRING" + + +class Choice(ParamType): + """The choice type allows a value to be checked against a fixed set + of supported values. All of these values have to be strings. + + You should only pass a list or tuple of choices. Other iterables + (like generators) may lead to surprising results. + + The resulting value will always be one of the originally passed choices + regardless of ``case_sensitive`` or any ``ctx.token_normalize_func`` + being specified. + + See :ref:`choice-opts` for an example. + + :param case_sensitive: Set to false to make choices case + insensitive. Defaults to true. + """ + + name = "choice" + + def __init__(self, choices: t.Sequence[str], case_sensitive: bool = True) -> None: + self.choices = choices + self.case_sensitive = case_sensitive + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["choices"] = self.choices + info_dict["case_sensitive"] = self.case_sensitive + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + choices_str = "|".join(self.choices) + + # Use curly braces to indicate a required argument. + if param.required and param.param_type_name == "argument": + return f"{{{choices_str}}}" + + # Use square braces to indicate an option or optional argument. + return f"[{choices_str}]" + + def get_missing_message(self, param: "Parameter") -> str: + return _("Choose from:\n\t{choices}").format(choices=",\n\t".join(self.choices)) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + # Match through normalization and case sensitivity + # first do token_normalize_func, then lowercase + # preserve original `value` to produce an accurate message in + # `self.fail` + normed_value = value + normed_choices = {choice: choice for choice in self.choices} + + if ctx is not None and ctx.token_normalize_func is not None: + normed_value = ctx.token_normalize_func(value) + normed_choices = { + ctx.token_normalize_func(normed_choice): original + for normed_choice, original in normed_choices.items() + } + + if not self.case_sensitive: + normed_value = normed_value.casefold() + normed_choices = { + normed_choice.casefold(): original + for normed_choice, original in normed_choices.items() + } + + if normed_value in normed_choices: + return normed_choices[normed_value] + + choices_str = ", ".join(map(repr, self.choices)) + self.fail( + ngettext( + "{value!r} is not {choice}.", + "{value!r} is not one of {choices}.", + len(self.choices), + ).format(value=value, choice=choices_str, choices=choices_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return f"Choice({list(self.choices)})" + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Complete choices that start with the incomplete value. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + str_choices = map(str, self.choices) + + if self.case_sensitive: + matched = (c for c in str_choices if c.startswith(incomplete)) + else: + incomplete = incomplete.lower() + matched = (c for c in str_choices if c.lower().startswith(incomplete)) + + return [CompletionItem(c) for c in matched] + + +class DateTime(ParamType): + """The DateTime type converts date strings into `datetime` objects. + + The format strings which are checked are configurable, but default to some + common (non-timezone aware) ISO 8601 formats. + + When specifying *DateTime* formats, you should only pass a list or a tuple. + Other iterables, like generators, may lead to surprising results. + + The format strings are processed using ``datetime.strptime``, and this + consequently defines the format strings which are allowed. + + Parsing is tried using each format, in order, and the first format which + parses successfully is used. + + :param formats: A list or tuple of date format strings, in the order in + which they should be tried. Defaults to + ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, + ``'%Y-%m-%d %H:%M:%S'``. + """ + + name = "datetime" + + def __init__(self, formats: t.Optional[t.Sequence[str]] = None): + self.formats = formats or ["%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S"] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["formats"] = self.formats + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + return f"[{'|'.join(self.formats)}]" + + def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]: + try: + return datetime.strptime(value, format) + except ValueError: + return None + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, datetime): + return value + + for format in self.formats: + converted = self._try_to_convert_date(value, format) + + if converted is not None: + return converted + + formats_str = ", ".join(map(repr, self.formats)) + self.fail( + ngettext( + "{value!r} does not match the format {format}.", + "{value!r} does not match the formats {formats}.", + len(self.formats), + ).format(value=value, format=formats_str, formats=formats_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return "DateTime" + + +class _NumberParamTypeBase(ParamType): + _number_class: t.ClassVar[t.Type] + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self._number_class(value) + except ValueError: + self.fail( + _("{value!r} is not a valid {number_type}.").format( + value=value, number_type=self.name + ), + param, + ctx, + ) + + +class _NumberRangeBase(_NumberParamTypeBase): + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + self.min = min + self.max = max + self.min_open = min_open + self.max_open = max_open + self.clamp = clamp + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + min=self.min, + max=self.max, + min_open=self.min_open, + max_open=self.max_open, + clamp=self.clamp, + ) + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import operator + + rv = super().convert(value, param, ctx) + lt_min: bool = self.min is not None and ( + operator.le if self.min_open else operator.lt + )(rv, self.min) + gt_max: bool = self.max is not None and ( + operator.ge if self.max_open else operator.gt + )(rv, self.max) + + if self.clamp: + if lt_min: + return self._clamp(self.min, 1, self.min_open) # type: ignore + + if gt_max: + return self._clamp(self.max, -1, self.max_open) # type: ignore + + if lt_min or gt_max: + self.fail( + _("{value} is not in the range {range}.").format( + value=rv, range=self._describe_range() + ), + param, + ctx, + ) + + return rv + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + """Find the valid value to clamp to bound in the given + direction. + + :param bound: The boundary value. + :param dir: 1 or -1 indicating the direction to move. + :param open: If true, the range does not include the bound. + """ + raise NotImplementedError + + def _describe_range(self) -> str: + """Describe the range for use in help text.""" + if self.min is None: + op = "<" if self.max_open else "<=" + return f"x{op}{self.max}" + + if self.max is None: + op = ">" if self.min_open else ">=" + return f"x{op}{self.min}" + + lop = "<" if self.min_open else "<=" + rop = "<" if self.max_open else "<=" + return f"{self.min}{lop}x{rop}{self.max}" + + def __repr__(self) -> str: + clamp = " clamped" if self.clamp else "" + return f"<{type(self).__name__} {self._describe_range()}{clamp}>" + + +class IntParamType(_NumberParamTypeBase): + name = "integer" + _number_class = int + + def __repr__(self) -> str: + return "INT" + + +class IntRange(_NumberRangeBase, IntParamType): + """Restrict an :data:`click.INT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "integer range" + + def _clamp( # type: ignore + self, bound: int, dir: "te.Literal[1, -1]", open: bool + ) -> int: + if not open: + return bound + + return bound + dir + + +class FloatParamType(_NumberParamTypeBase): + name = "float" + _number_class = float + + def __repr__(self) -> str: + return "FLOAT" + + +class FloatRange(_NumberRangeBase, FloatParamType): + """Restrict a :data:`click.FLOAT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. This is not supported if either + boundary is marked ``open``. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "float range" + + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + super().__init__( + min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp + ) + + if (min_open or max_open) and clamp: + raise TypeError("Clamping is not supported for open bounds.") + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + if not open: + return bound + + # Could use Python 3.9's math.nextafter here, but clamping an + # open float range doesn't seem to be particularly useful. It's + # left up to the user to write a callback to do it if needed. + raise RuntimeError("Clamping is not supported for open bounds.") + + +class BoolParamType(ParamType): + name = "boolean" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if value in {False, True}: + return bool(value) + + norm = value.strip().lower() + + if norm in {"1", "true", "t", "yes", "y", "on"}: + return True + + if norm in {"0", "false", "f", "no", "n", "off"}: + return False + + self.fail( + _("{value!r} is not a valid boolean.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "BOOL" + + +class UUIDParameterType(ParamType): + name = "uuid" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import uuid + + if isinstance(value, uuid.UUID): + return value + + value = value.strip() + + try: + return uuid.UUID(value) + except ValueError: + self.fail( + _("{value!r} is not a valid UUID.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "UUID" + + +class File(ParamType): + """Declares a parameter to be a file for reading or writing. The file + is automatically closed once the context tears down (after the command + finished working). + + Files can be opened for reading or writing. The special value ``-`` + indicates stdin or stdout depending on the mode. + + By default, the file is opened for reading text data, but it can also be + opened in binary mode or for writing. The encoding parameter can be used + to force a specific encoding. + + The `lazy` flag controls if the file should be opened immediately or upon + first IO. The default is to be non-lazy for standard input and output + streams as well as files opened for reading, `lazy` otherwise. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. + + Starting with Click 2.0, files can also be opened atomically in which + case all writes go into a separate file in the same folder and upon + completion the file will be moved over to the original location. This + is useful if a file regularly read by other users is modified. + + See :ref:`file-args` for more information. + """ + + name = "filename" + envvar_list_splitter = os.path.pathsep + + def __init__( + self, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: t.Optional[bool] = None, + atomic: bool = False, + ) -> None: + self.mode = mode + self.encoding = encoding + self.errors = errors + self.lazy = lazy + self.atomic = atomic + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update(mode=self.mode, encoding=self.encoding) + return info_dict + + def resolve_lazy_flag(self, value: t.Any) -> bool: + if self.lazy is not None: + return self.lazy + if value == "-": + return False + elif "w" in self.mode: + return True + return False + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + if hasattr(value, "read") or hasattr(value, "write"): + return value + + lazy = self.resolve_lazy_flag(value) + + if lazy: + f: t.IO = t.cast( + t.IO, + LazyFile( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ), + ) + + if ctx is not None: + ctx.call_on_close(f.close_intelligently) # type: ignore + + return f + + f, should_close = open_stream( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + # If a context is provided, we automatically close the file + # at the end of the context execution (or flush out). If a + # context does not exist, it's the caller's responsibility to + # properly close the file. This for instance happens when the + # type is used with prompts. + if ctx is not None: + if should_close: + ctx.call_on_close(safecall(f.close)) + else: + ctx.call_on_close(safecall(f.flush)) + + return f + except OSError as e: # noqa: B014 + self.fail(f"{os.fsdecode(value)!r}: {e.strerror}", param, ctx) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide file path completions. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + return [CompletionItem(incomplete, type="file")] + + +class Path(ParamType): + """The path type is similar to the :class:`File` type but it performs + different checks. First of all, instead of returning an open file + handle it returns just the filename. Secondly, it can perform various + basic checks about what the file or directory should be. + + :param exists: if set to true, the file or directory needs to exist for + this value to be valid. If this is not required and a + file does indeed not exist, then all further checks are + silently skipped. + :param file_okay: controls if a file is a possible value. + :param dir_okay: controls if a directory is a possible value. + :param writable: if true, a writable check is performed. + :param readable: if true, a readable check is performed. + :param resolve_path: if this is true, then the path is fully resolved + before the value is passed onwards. This means + that it's absolute and symlinks are resolved. It + will not expand a tilde-prefix, as this is + supposed to be done by the shell only. + :param allow_dash: If this is set to `True`, a single dash to indicate + standard streams is permitted. + :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.0 + Allow passing ``type=pathlib.Path``. + + .. versionchanged:: 6.0 + Added the ``allow_dash`` parameter. + """ + + envvar_list_splitter = os.path.pathsep + + def __init__( + self, + exists: bool = False, + file_okay: bool = True, + dir_okay: bool = True, + writable: bool = False, + readable: bool = True, + resolve_path: bool = False, + allow_dash: bool = False, + path_type: t.Optional[t.Type] = None, + ): + self.exists = exists + self.file_okay = file_okay + self.dir_okay = dir_okay + self.writable = writable + self.readable = readable + self.resolve_path = resolve_path + self.allow_dash = allow_dash + self.type = path_type + + if self.file_okay and not self.dir_okay: + self.name = _("file") + elif self.dir_okay and not self.file_okay: + self.name = _("directory") + else: + self.name = _("path") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + exists=self.exists, + file_okay=self.file_okay, + dir_okay=self.dir_okay, + writable=self.writable, + readable=self.readable, + allow_dash=self.allow_dash, + ) + return info_dict + + def coerce_path_result(self, rv: t.Any) -> t.Any: + if self.type is not None and not isinstance(rv, self.type): + if self.type is str: + rv = os.fsdecode(rv) + elif self.type is bytes: + rv = os.fsencode(rv) + else: + rv = self.type(rv) + + return rv + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + rv = value + + is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") + + if not is_dash: + if self.resolve_path: + # realpath on Windows Python < 3.8 doesn't resolve symlinks + if os.path.islink(rv): + rv = os.readlink(rv) + + rv = os.path.realpath(rv) + + try: + st = os.stat(rv) + except OSError: + if not self.exists: + return self.coerce_path_result(rv) + self.fail( + _("{name} {filename!r} does not exist.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + + if not self.file_okay and stat.S_ISREG(st.st_mode): + self.fail( + _("{name} {filename!r} is a file.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail( + _("{name} {filename!r} is a directory.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + if self.writable and not os.access(value, os.W_OK): + self.fail( + _("{name} {filename!r} is not writable.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + if self.readable and not os.access(value, os.R_OK): + self.fail( + _("{name} {filename!r} is not readable.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + + return self.coerce_path_result(rv) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide path completions for only + directories or any paths. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + type = "dir" if self.dir_okay and not self.file_okay else "file" + return [CompletionItem(incomplete, type=type)] + + +class Tuple(CompositeParamType): + """The default behavior of Click is to apply a type on a value directly. + This works well in most cases, except for when `nargs` is set to a fixed + count and different types should be used for different items. In this + case the :class:`Tuple` type can be used. This type can only be used + if `nargs` is set to a fixed number. + + For more information see :ref:`tuple-type`. + + This can be selected by using a Python tuple literal as a type. + + :param types: a list of types that should be used for the tuple items. + """ + + def __init__(self, types: t.Sequence[t.Union[t.Type, ParamType]]) -> None: + self.types = [convert_type(ty) for ty in types] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["types"] = [t.to_info_dict() for t in self.types] + return info_dict + + @property + def name(self) -> str: # type: ignore + return f"<{' '.join(ty.name for ty in self.types)}>" + + @property + def arity(self) -> int: # type: ignore + return len(self.types) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + len_type = len(self.types) + len_value = len(value) + + if len_value != len_type: + self.fail( + ngettext( + "{len_type} values are required, but {len_value} was given.", + "{len_type} values are required, but {len_value} were given.", + len_value, + ).format(len_type=len_type, len_value=len_value), + param=param, + ctx=ctx, + ) + + return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) + + +def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> ParamType: + """Find the most appropriate :class:`ParamType` for the given Python + type. If the type isn't provided, it can be inferred from a default + value. + """ + guessed_type = False + + if ty is None and default is not None: + if isinstance(default, (tuple, list)): + # If the default is empty, ty will remain None and will + # return STRING. + if default: + item = default[0] + + # A tuple of tuples needs to detect the inner types. + # Can't call convert recursively because that would + # incorrectly unwind the tuple to a single type. + if isinstance(item, (tuple, list)): + ty = tuple(map(type, item)) + else: + ty = type(item) + else: + ty = type(default) + + guessed_type = True + + if isinstance(ty, tuple): + return Tuple(ty) + + if isinstance(ty, ParamType): + return ty + + if ty is str or ty is None: + return STRING + + if ty is int: + return INT + + if ty is float: + return FLOAT + + if ty is bool: + return BOOL + + if guessed_type: + return STRING + + if __debug__: + try: + if issubclass(ty, ParamType): + raise AssertionError( + f"Attempted to use an uninstantiated parameter type ({ty})." + ) + except TypeError: + # ty is an instance (correct), so issubclass fails. + pass + + return FuncParamType(ty) + + +#: A dummy parameter type that just does nothing. From a user's +#: perspective this appears to just be the same as `STRING` but +#: internally no string conversion takes place if the input was bytes. +#: This is usually useful when working with file paths as they can +#: appear in bytes and unicode. +#: +#: For path related uses the :class:`Path` type is a better choice but +#: there are situations where an unprocessed type is useful which is why +#: it is is provided. +#: +#: .. versionadded:: 4.0 +UNPROCESSED = UnprocessedParamType() + +#: A unicode string parameter type which is the implicit default. This +#: can also be selected by using ``str`` as type. +STRING = StringParamType() + +#: An integer parameter. This can also be selected by using ``int`` as +#: type. +INT = IntParamType() + +#: A floating point value parameter. This can also be selected by using +#: ``float`` as type. +FLOAT = FloatParamType() + +#: A boolean parameter. This is the default for boolean flags. This can +#: also be selected by using ``bool`` as a type. +BOOL = BoolParamType() + +#: A UUID parameter. +UUID = UUIDParameterType() diff --git a/venv/lib/python3.9/site-packages/click/utils.py b/venv/lib/python3.9/site-packages/click/utils.py new file mode 100644 index 0000000..91a372d --- /dev/null +++ b/venv/lib/python3.9/site-packages/click/utils.py @@ -0,0 +1,579 @@ +import os +import sys +import typing as t +from functools import update_wrapper +from types import ModuleType + +from ._compat import _default_text_stderr +from ._compat import _default_text_stdout +from ._compat import _find_binary_writer +from ._compat import auto_wrap_for_ansi +from ._compat import binary_streams +from ._compat import get_filesystem_encoding +from ._compat import open_stream +from ._compat import should_strip_ansi +from ._compat import strip_ansi +from ._compat import text_streams +from ._compat import WIN +from .globals import resolve_color_default + +if t.TYPE_CHECKING: + import typing_extensions as te + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def _posixify(name: str) -> str: + return "-".join(name.split()).lower() + + +def safecall(func: F) -> F: + """Wraps a function so that it swallows exceptions.""" + + def wrapper(*args, **kwargs): # type: ignore + try: + return func(*args, **kwargs) + except Exception: + pass + + return update_wrapper(t.cast(F, wrapper), func) + + +def make_str(value: t.Any) -> str: + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(get_filesystem_encoding()) + except UnicodeError: + return value.decode("utf-8", "replace") + return str(value) + + +def make_default_short_help(help: str, max_length: int = 45) -> str: + """Returns a condensed version of help string.""" + # Consider only the first paragraph. + paragraph_end = help.find("\n\n") + + if paragraph_end != -1: + help = help[:paragraph_end] + + # Collapse newlines, tabs, and spaces. + words = help.split() + + if not words: + return "" + + # The first paragraph started with a "no rewrap" marker, ignore it. + if words[0] == "\b": + words = words[1:] + + total_length = 0 + last_index = len(words) - 1 + + for i, word in enumerate(words): + total_length += len(word) + (i > 0) + + if total_length > max_length: # too long, truncate + break + + if word[-1] == ".": # sentence end, truncate without "..." + return " ".join(words[: i + 1]) + + if total_length == max_length and i != last_index: + break # not at sentence end, truncate with "..." + else: + return " ".join(words) # no truncation needed + + # Account for the length of the suffix. + total_length += len("...") + + # remove words until the length is short enough + while i > 0: + total_length -= len(words[i]) + (i > 0) + + if total_length <= max_length: + break + + i -= 1 + + return " ".join(words[:i]) + "..." + + +class LazyFile: + """A lazy file works like a regular file but it does not fully open + the file but it does perform some basic checks early to see if the + filename parameter does make sense. This is useful for safely opening + files for writing. + """ + + def __init__( + self, + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, + ): + self.name = filename + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + self._f: t.Optional[t.IO] + + if filename == "-": + self._f, self.should_close = open_stream(filename, mode, encoding, errors) + else: + if "r" in mode: + # Open and close the file in case we're opening it for + # reading so that we can catch at least some errors in + # some cases early. + open(filename, mode).close() + self._f = None + self.should_close = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self.open(), name) + + def __repr__(self) -> str: + if self._f is not None: + return repr(self._f) + return f"" + + def open(self) -> t.IO: + """Opens the file if it's not yet open. This call might fail with + a :exc:`FileError`. Not handling this error will produce an error + that Click shows. + """ + if self._f is not None: + return self._f + try: + rv, self.should_close = open_stream( + self.name, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + except OSError as e: # noqa: E402 + from .exceptions import FileError + + raise FileError(self.name, hint=e.strerror) + self._f = rv + return rv + + def close(self) -> None: + """Closes the underlying file, no matter what.""" + if self._f is not None: + self._f.close() + + def close_intelligently(self) -> None: + """This function only closes the file if it was opened by the lazy + file wrapper. For instance this will never close stdin. + """ + if self.should_close: + self.close() + + def __enter__(self) -> "LazyFile": + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self.close_intelligently() + + def __iter__(self) -> t.Iterator[t.AnyStr]: + self.open() + return iter(self._f) # type: ignore + + +class KeepOpenFile: + def __init__(self, file: t.IO) -> None: + self._file = file + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._file, name) + + def __enter__(self) -> "KeepOpenFile": + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + pass + + def __repr__(self) -> str: + return repr(self._file) + + def __iter__(self) -> t.Iterator[t.AnyStr]: + return iter(self._file) + + +def echo( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, +) -> None: + """Print a message and newline to stdout or a file. This should be + used instead of :func:`print` because it provides better support + for different data, files, and environments. + + Compared to :func:`print`, this does the following: + + - Ensures that the output encoding is not misconfigured on Linux. + - Supports Unicode in the Windows console. + - Supports writing to binary outputs, and supports writing bytes + to text outputs. + - Supports colors and styles on Windows. + - Removes ANSI color and style codes if the output does not look + like an interactive terminal. + - Always flushes the output. + + :param message: The string or bytes to output. Other objects are + converted to strings. + :param file: The file to write to. Defaults to ``stdout``. + :param err: Write to ``stderr`` instead of ``stdout``. + :param nl: Print a newline after the message. Enabled by default. + :param color: Force showing or hiding colors and other styles. By + default Click will remove color if the output does not look like + an interactive terminal. + + .. versionchanged:: 6.0 + Support Unicode output on the Windows console. Click does not + modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()`` + will still not support Unicode. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionadded:: 3.0 + Added the ``err`` parameter. + + .. versionchanged:: 2.0 + Support colors on Windows if colorama is installed. + """ + if file is None: + if err: + file = _default_text_stderr() + else: + file = _default_text_stdout() + + # Convert non bytes/text into the native string type. + if message is not None and not isinstance(message, (str, bytes, bytearray)): + out: t.Optional[t.Union[str, bytes]] = str(message) + else: + out = message + + if nl: + out = out or "" + if isinstance(out, str): + out += "\n" + else: + out += b"\n" + + if not out: + file.flush() + return + + # If there is a message and the value looks like bytes, we manually + # need to find the binary stream and write the message in there. + # This is done separately so that most stream types will work as you + # would expect. Eg: you can write to StringIO for other cases. + if isinstance(out, (bytes, bytearray)): + binary_file = _find_binary_writer(file) + + if binary_file is not None: + file.flush() + binary_file.write(out) + binary_file.flush() + return + + # ANSI style code support. For no message or bytes, nothing happens. + # When outputting to a file instead of a terminal, strip codes. + else: + color = resolve_color_default(color) + + if should_strip_ansi(file, color): + out = strip_ansi(out) + elif WIN: + if auto_wrap_for_ansi is not None: + file = auto_wrap_for_ansi(file) # type: ignore + elif not color: + out = strip_ansi(out) + + file.write(out) # type: ignore + file.flush() + + +def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO: + """Returns a system stream for byte processing. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + """ + opener = binary_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener() + + +def get_text_stream( + name: "te.Literal['stdin', 'stdout', 'stderr']", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", +) -> t.TextIO: + """Returns a system stream for text processing. This usually returns + a wrapped stream around a binary stream returned from + :func:`get_binary_stream` but it also can take shortcuts for already + correctly configured streams. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + :param encoding: overrides the detected default encoding. + :param errors: overrides the default error mode. + """ + opener = text_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener(encoding, errors) + + +def open_file( + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: bool = False, + atomic: bool = False, +) -> t.IO: + """This is similar to how the :class:`File` works but for manual + usage. Files are opened non lazy by default. This can open regular + files as well as stdin/stdout if ``'-'`` is passed. + + If stdin/stdout is returned the stream is wrapped so that the context + manager will not close the stream accidentally. This makes it possible + to always use the function like this without having to worry to + accidentally close a standard stream:: + + with open_file(filename) as f: + ... + + .. versionadded:: 3.0 + + :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 use. + :param errors: the error handling for this file. + :param lazy: can be flipped to true to open the file lazily. + :param atomic: in atomic mode writes go into a temporary file and it's + moved on close. + """ + if lazy: + return t.cast(t.IO, LazyFile(filename, mode, encoding, errors, atomic=atomic)) + f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic) + if not should_close: + f = t.cast(t.IO, KeepOpenFile(f)) + return f + + +def get_os_args() -> t.Sequence[str]: + """Returns the argument part of ``sys.argv``, removing the first + value which is the name of the script. + + .. deprecated:: 8.0 + Will be removed in Click 8.1. Access ``sys.argv[1:]`` directly + instead. + """ + import warnings + + warnings.warn( + "'get_os_args' is deprecated and will be removed in Click 8.1." + " Access 'sys.argv[1:]' directly instead.", + DeprecationWarning, + stacklevel=2, + ) + return sys.argv[1:] + + +def format_filename( + filename: t.Union[str, bytes, os.PathLike], shorten: bool = False +) -> str: + """Formats a filename for user display. The main purpose of this + function is to ensure that the filename can be displayed at all. This + will decode the filename to unicode if necessary in a way that it will + not fail. Optionally, it can shorten the filename to not include the + full path to the filename. + + :param filename: formats a filename for UI display. This will also convert + the filename into unicode without failing. + :param shorten: this optionally shortens the filename to strip of the + path that leads up to it. + """ + if shorten: + filename = os.path.basename(filename) + + return os.fsdecode(filename) + + +def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str: + r"""Returns the config folder for the application. The default behavior + is to return whatever is most appropriate for the operating system. + + To give you an idea, for an app called ``"Foo Bar"``, something like + the following folders could be returned: + + Mac OS X: + ``~/Library/Application Support/Foo Bar`` + Mac OS X (POSIX): + ``~/.foo-bar`` + Unix: + ``~/.config/foo-bar`` + Unix (POSIX): + ``~/.foo-bar`` + Windows (roaming): + ``C:\Users\\AppData\Roaming\Foo Bar`` + Windows (not roaming): + ``C:\Users\\AppData\Local\Foo Bar`` + + .. versionadded:: 2.0 + + :param app_name: the application name. This should be properly capitalized + and can contain whitespace. + :param roaming: controls if the folder should be roaming or not on Windows. + Has no affect otherwise. + :param force_posix: if this is set to `True` then on any POSIX system the + folder will be stored in the home folder with a leading + dot instead of the XDG config home or darwin's + application support folder. + """ + if WIN: + key = "APPDATA" if roaming else "LOCALAPPDATA" + folder = os.environ.get(key) + if folder is None: + folder = os.path.expanduser("~") + return os.path.join(folder, app_name) + if force_posix: + return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}")) + if sys.platform == "darwin": + return os.path.join( + os.path.expanduser("~/Library/Application Support"), app_name + ) + return os.path.join( + os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")), + _posixify(app_name), + ) + + +class PacifyFlushWrapper: + """This wrapper is used to catch and suppress BrokenPipeErrors resulting + from ``.flush()`` being called on broken pipe during the shutdown/final-GC + of the Python interpreter. Notably ``.flush()`` is always called on + ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any + other cleanup code, and the case where the underlying file is not a broken + pipe, all calls and attributes are proxied. + """ + + def __init__(self, wrapped: t.IO) -> None: + self.wrapped = wrapped + + def flush(self) -> None: + try: + self.wrapped.flush() + except OSError as e: + import errno + + if e.errno != errno.EPIPE: + raise + + def __getattr__(self, attr: str) -> t.Any: + return getattr(self.wrapped, attr) + + +def _detect_program_name( + path: t.Optional[str] = None, _main: ModuleType = sys.modules["__main__"] +) -> 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 not path: + path = sys.argv[0] + + # The value of __package__ indicates how Python was called. It may + # not exist if a setuptools script is installed as an egg. It may be + # set incorrectly for entry points created with pip on Windows. + if getattr(_main, "__package__", None) is None or ( + os.name == "nt" + and _main.__package__ == "" + and not os.path.exists(path) + and os.path.exists(f"{path}.exe") + ): + # Executed a file, like "python app.py". + return os.path.basename(path) + + # Executed a module, like "python -m example". + # Rewritten by Python from "-m script" to "/path/to/script.py". + # Need to look at main module to determine how it was executed. + py_module = t.cast(str, _main.__package__) + name = os.path.splitext(os.path.basename(path))[0] + + # A submodule like "example.cli". + if name != "__main__": + py_module = f"{py_module}.{name}" + + return f"python -m {py_module.lstrip('.')}" + + +def _expand_args( + args: t.Iterable[str], + *, + user: bool = True, + env: bool = True, + glob_recursive: bool = True, +) -> t.List[str]: + """Simulate Unix shell expansion with Python functions. + + See :func:`glob.glob`, :func:`os.path.expanduser`, and + :func:`os.path.expandvars`. + + This 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. + + .. 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) + + matches = glob(arg, recursive=glob_recursive) + + if not matches: + out.append(arg) + else: + out.extend(matches) + + return out diff --git a/venv/lib/python3.8/site-packages/easy_install.py b/venv/lib/python3.9/site-packages/easy_install.py similarity index 100% rename from venv/lib/python3.8/site-packages/easy_install.py rename to venv/lib/python3.9/site-packages/easy_install.py diff --git a/venv/lib/python3.9/site-packages/flask/__init__.py b/venv/lib/python3.9/site-packages/flask/__init__.py new file mode 100644 index 0000000..c5da045 --- /dev/null +++ b/venv/lib/python3.9/site-packages/flask/__init__.py @@ -0,0 +1,46 @@ +from markupsafe import escape +from markupsafe import Markup +from werkzeug.exceptions import abort as abort +from werkzeug.utils import redirect as redirect + +from . import json as json +from .app import Flask as Flask +from .app import Request as Request +from .app import Response as Response +from .blueprints import Blueprint as Blueprint +from .config import Config as Config +from .ctx import after_this_request as after_this_request +from .ctx import copy_current_request_context as copy_current_request_context +from .ctx import has_app_context as has_app_context +from .ctx import has_request_context as has_request_context +from .globals import _app_ctx_stack as _app_ctx_stack +from .globals import _request_ctx_stack as _request_ctx_stack +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 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 safe_join as safe_join +from .helpers import send_file as send_file +from .helpers import send_from_directory as send_from_directory +from .helpers import stream_with_context as stream_with_context +from .helpers import url_for as url_for +from .json import jsonify as jsonify +from .signals import appcontext_popped as appcontext_popped +from .signals import appcontext_pushed as appcontext_pushed +from .signals import appcontext_tearing_down as appcontext_tearing_down +from .signals import before_render_template as before_render_template +from .signals import got_request_exception as got_request_exception +from .signals import message_flashed as message_flashed +from .signals import request_finished as request_finished +from .signals import request_started as request_started +from .signals import request_tearing_down as request_tearing_down +from .signals import signals_available as signals_available +from .signals import template_rendered as template_rendered +from .templating import render_template as render_template +from .templating import render_template_string as render_template_string + +__version__ = "2.0.1" diff --git a/venv/lib/python3.9/site-packages/flask/__main__.py b/venv/lib/python3.9/site-packages/flask/__main__.py new file mode 100644 index 0000000..4e28416 --- /dev/null +++ b/venv/lib/python3.9/site-packages/flask/__main__.py @@ -0,0 +1,3 @@ +from .cli import main + +main() diff --git a/venv/lib/python3.9/site-packages/flask/__pycache__/__init__.cpython-39.pyc b/venv/lib/python3.9/site-packages/flask/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f28046cb4199139c01866f5dc0e0190241cd2bfc GIT binary patch literal 1897 zcmbu9NpCAf5XWsN@i<=NCC|!dw_%xf+skE&_m)-muBo~+w?56aKgN+PQwy+;EZ`6`5exf50Ee5g82~n5-ypK zklWB^K1O!IWj;Z^f-B}zZT6XQH^f-F{gNY-G_+EKth~T`JzmKHh z;P=ubab#$%#c$O}COU{{BKut&^@2W9&FfjIg&hP&=;t49cH`txbVpjt$WDFHjUy`` z==YU@XM~p|Ggh6f$qF-ec^qaRgt1&A5f>!*Ep$N>gsmOG1v3#suSy_Hd&E zoNn}`6+Do>2yx!)OM`xsd@I95c~%O~S{-yomTFK6y`jX%zZAuIJt;oK0ab9($jBGH zKv8IYJkW6{#`TW%BimL>FBJEI9n9>~8EGYYvBn68`VsUfxQct3)J!CCl1TrxIWhw_ zS7suu^sq~P;m7xsRkI^;Vahu4sZo=C;mmSBe(8;T=*q;7D^!^jV_F=HU7B{L7evA2 zp_QqJoza%_XiTkFNmNbHk35Avzw-j+b+|;;X)cr8cm-Vab)L;v7M=v!;KzlV_Er1( zr`8vc5BZ!^Gc;Y0dJYBZ_fii(%2B`lyg8%iX{P)Y>ha^WN$0R2trz9)@ z$WK~;<kh3@bd4|H0UFme~@6-;oKw;LkugV@eyOh@eN_b$N?q2Ck|nPyS}Ef+9jmx zot3O(^^WR(kRN?02%|Z8sf`z{m5e&U8`yAHdShWLy}0JEH?=Q}k_H-HHK1e;w)MhP p^K=1DdOoxCT+$17P$=q3$g=o0%Tn8RgQYg?s`x4{a&f_kd;w0=J7xd? literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/flask/__pycache__/app.cpython-39.pyc b/venv/lib/python3.9/site-packages/flask/__pycache__/app.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e6e08b49780a8acb131ff705d65a13f9bd09742 GIT binary patch literal 63588 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 z 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/flask/__pycache__/blueprints.cpython-39.pyc b/venv/lib/python3.9/site-packages/flask/__pycache__/blueprints.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..89c5eda8b0abab245e13a48511d33ff54f22a847 GIT binary patch literal 21752 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/flask/__pycache__/config.cpython-39.pyc b/venv/lib/python3.9/site-packages/flask/__pycache__/config.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0e469aee64035f7dae4ada3f15b9e0128e6a9808 GIT binary patch literal 11509 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 Hl)Uu6WGe;3 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/flask/__pycache__/debughelpers.cpython-39.pyc b/venv/lib/python3.9/site-packages/flask/__pycache__/debughelpers.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..edc86eba4e5074628d98f2fe75f1ba8e010499cb GIT binary patch literal 6473 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/flask/__pycache__/globals.cpython-39.pyc b/venv/lib/python3.9/site-packages/flask/__pycache__/globals.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ecc0f0bdbb795669538088d88af7dab161911cf4 GIT binary patch literal 1847 zcmcIl&2J+$6u0x8X+FAbnttqp%mIm@C3E0}R3T6)T?ACsrf9`nW}UHcfcb^SU2F6G+1`uT-a^Dv$gnHn83PUM8B!bbub8-8Vmj&nW>H8IO1 z1OQ@5B2Hsi&!{0wnG$LYj}pTfF_NU3lSvu}2C`8Rnq?6ebIv$(XiO-$7MwggKR>(6 zG$iCm#yS-Sf;nL_NFyE_YWE=UX8@_iIFZT;V~|ndqGLc!X7bV|rVAMY0*f?Jax8c> zr0)PT|56}L5&@;;+y4(m0+sQh2L_^vmJ!6#<&d09 zScnC8Y$;EP=7yvRvBdoob+J1*hA{k9Denz{&k^S~tMiacppHaRamcu4aTwU+bN7@$ zDZ@B|p$Q0sF7WsG8osv_slF+h@(un0o60r5MmMDqy2Yo1YPRLC4vim}D_`4FnU#%9 zvexr7Hetk%m69s!JqY7U`H`Mx^(lv58+BXCDlv_?YC+yxq_$xC9xq%Gj@@KwW-|V8_>rqa!#_v>5}k7GPV7hG zPK!@tm@EOikaC_T7MovmI3-*VYcfk_CSU4_U{v?ch_0J_NLHw}Lw!WgDxn!Nz6v)!9)^>#FPG zs#2E!3{O=Z=E0M!X78VPnqiYQ^9x2wp_MJi>s)d*f5p@3P}nO{*#oTX??%=>|Mu+I zKYDh2^yL?)Cu+|+asXvGr}@rVW0g-A2^*IRFma`GG^%6&!`7Ui0A(pvc^Mm4%egrK zE$jL|jbmBdS=#s2W9zpZtGBFp!&0v0O>7)SlBI%wZ2O|$2jSpWsRg5kLE5)esaKpv T9o|L_j^ZZn;}UNC*((19AS(6I literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/flask/__pycache__/helpers.cpython-39.pyc b/venv/lib/python3.9/site-packages/flask/__pycache__/helpers.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..450d4409e95450043eeb869e749da1b3bf9c9337 GIT binary patch literal 27329 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 BbEN

{p zw^_AOAnYujGB1w&U@%n@XNtv#5o>#Z zTDM&YJ_w>g^N~&N9*;yQ6$D4OF`uzR9vRr(M#F8)5Hg!XND;GqU;~UQ0wp~Y&eF}{cPNN2p;$2spq|>gxvqR-+O3w4 zht`~DkCo}AmFcBPVF|E~M+@hw*2t?ooMBRu(Ltc%D9J(1l44r4S41K0?eMqT8pdPU zGQk+CJevf9>!Cbo-IaRJ#FN%`V20Cv>mlUs$6*k+4j^JH4En9f%nak`X7lrw4vhSG z!o58{kUGt`HP3f4OI9xCTt|{2+elT_U~D)^5j_A{5vCq;cYdK6V#&d+Z^Lj*PRJ?w z5uQ)!F;yKyzb8J>R5&ln$8_Y}CC}+|s@4P$7Untq>3#>E`KNThCh|by!qG1qL+S0Y zz(;<L)LjVFUXFyY!0N^oZIZ6$$EB-7qBDln~43Y#s2sbq8^bS$R7QgP_pj`XwL?H z@Cq8-ZU)74nx7=443Am_zx2Qt;4P_i1~QUQCTjgdnEnMfIl4CFx@VnxnOCzDqLk?M z=9&5KR-=$CUr0R3@o1KmGe4bFP!0G1)F3HNpiv^za1=V>xFEt}Euh27r+ zbG?G8<;yhh6xLZhg0UgKMbpST^)ywtB-RA90-G0j}N{$6^}7tc~wd zYv5)>D-?97PYyNff0>5W-hf-TVKC%`9+Q!CN}=XtlvCG`M;gYH0!U*KHQAJofo=L0 ztd&g#SB_DWDgPBnye+ZgC9}edItUC&seMCC zGXPm4w#svnYzuDq8(qD-dFQKb@b)bj&7#<#`x||R#M4%b;uVYxs`H=5Sz}xX z#%7Al$+BO$rvjWoJ@_r0=C_k}L`7^J!@2jRno{K6u)Wcq7Bg zHbUKl@1~Kxv>Klw4N)CQz2?+t%_-BWqprccaYcOq4+a0SkfdlpwWC2oO?UB7s=XsQ z9l+-TnpdH8CZ$0b_o0*14?=zS+lQOIjeDCLU)+DNou-0Kkra2~b94VoE5}K34!9r3 zVT!5#R<+ef=u-pqTefUQs-$xEYLh$%&VFqy!g43=%XL(EjUdVt{u}@Z{awpBbfva( MrAqU({7=5{FYg+|%>V!Z literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/flask/__pycache__/scaffold.cpython-39.pyc b/venv/lib/python3.9/site-packages/flask/__pycache__/scaffold.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..190f931b06fb2a8261fcb66b83c39593fd56c640 GIT binary patch literal 24692 zcmdUXU2GgzmR?u&51SN8QItgeShmZQZIQOzl;wYp?6E9SwrmZhk?6mkne8ri70ITW z-91%BO6*WOyCWrbvYE|fvq7>L4Il*@B;L&r5@3@cSOj@VkOh*L0C}m`cHb{_% zb$0E1-?_JLRg;u$Imkm=>SFb+TleSObIV(`6w+^ixt{#^A5!@fC9+CS|+#jtTmHWM|N7jy2kIDU5tGM=P^-;Oshx^B>kIDTw z?jNr{F8BL!?^GSRKY;rus!z!MLEKMPC*^(u_s6Tp<^B-vpR7J<<^0m>Q$M$YSJB?X zt*6&cR8Jsn>UOR=jVI4|M{s@CJBsVcCHqLud*o+!^*JB^ykmE5?@{luJB4cH?VR_x z=iJG8&TYFo!#Dg>-V=B}=^e-O=e;Mrr|#scr@g1W6ZrcAo=)AhylL+lJblr#uH~km z{bP>e{InJC@%$xsy%l-QMueZE>s`-{{MwDc?RNcu8Q#5idH%fL=y>VRxpwk%>_W5U zU)u~Lf9+DoRawS$kv0Ej!|z7TPCG<7BkwFMT$xK!{uum{Lu&bKxBGU`S?{u@#(EI= z?Wl&T`NFav)q+kZs&(CH1ql?@nnDKx4qg@&{?Z_&A@L& zoq)-Y*OHc?dEFNK)rfBL#fBe-9ro_P*`>%2uKGV-_rvI%+iJOsEg$Lo(5}nDTdj4! z8#LR|dp^rM_?Exa3H)ujKSL>VLC^`_aob+Y4>F~UE%N(s?y5nbc!Q{lG<&t^{b6?nCBz`KljwL2N&^E>zIm;$mmL?R{p))>2#w z{AfLBH%Rv6W8n zROns*5Nr}UuCwMxD;>`XJ5IFXMou$wFf^dm8Xsb`8rPj>+wuIx^<`%boa8i@kkcP> z@L6gGVdMmA2%H-(UTFos>uowKLQtKx%;_bEV4Z7w)IoAd@HwXZCQWMx|(a|w(Q@vev^~Io_E(km$Oa?8g-qe^>%|y zD@|#DC4A3u$t7&@F0D;k=`5@?LuWl)$19uYE@l)sjs#$@(S5!S)^0If%3tvVq>v!% zEnli@cR;+gZYPLXY1;$I8lAueKZi~ya5^X=Fb#BD&1f^*%Ba(E$mNxxg$^2e6E&hm zYwmU53D;3o)X{~5!YyaBvmQ7bP5*{&KzP!@)OQ!%(3df4A%RWsH~e4|CAF6^NGu*L zi#V*9s)5^bFtHlGvnW$zM<2t;4WbZ~4K`E(GSR}yv>lJvnqf^yUR!Fmn<3_OJbE@n zR#Hc16vsUDTT20lG;nbF%nBampWNr}%t~j?pNX1lpvq>q>A5IjW9GacUXME6nYWwK z%KGBW6_9eN(`t5RHvIO+Osly#(?w@G?H4Mq&4kU!f3E8`uDi>AIJ4Ap!|O9)!(GA) zUZuMk4{Iq{BTJk_wV`N3t8Cep{bgaO_k=WGF@NO@#FN_!->78Ynl8px6z9*jH{(LX z4Wr;FiV4W6)3)>^IKhOcczKc+@@>2)Q!bx}Wb0h<*l6%9{x=%yYkW!G8!Awd~QiddDV0Di_d?Y71OOiff(nodr z0MfsY(vvbD@YgHfEmAk%DOUIT1#b`Z(6BcGJv8R;lV79WUi=#O_a`Mu>X^6hPT{sy zJ>VZ$J!qcfy>V!{{pQ(zUB&_LpyZy|R?38TNYW4ahjx^5*gVU&{4jLx5!7+idjzdI zf)*c>-%9fy^&gS8978Vlgj$%beAK%NN{|+h;rlqAPTtLX$Gs=fYe$|uf%Hl5sk;Ty z$%X21$^E3HP9d+-%};GhebzgPRy@5e^*OJC)DzoMXS`ELo!XZAymuO@)7w&C@Lojf zGyb#QHF=`Af^AeaXz2?oLl;`|s{fb}l zzJruA-s?h-8Kj*8>R{R%-ghPKd8D28PfOaH-dRa|0ckJ#FG|{5-Z@Eo3286;FH72a zZ%)!)LE5YStCDuXdt1_8L)yUVEWUgE@1U)RiI>=Z|ID)GpAq!*4(h+?y({@&-!=ak z^zS{;|C0AT$@PZ+-Caw4)6_%SfJ>zOd6a+IyCQF%_3}_93vv0H79j4QLBF2stgS(l zEcz?%MiT-&TyX=)&qY7F;rnf8wgH(F&enfbWKZP+B~YD0S2W(Xr;7;~2`dJd)GI?O zYu63jH7(t1ZFkL|g*t+o6yk)Z2Mltd0%U@ zSvQJ;*?LWiuGQ-3NN2spjzHldW3~|x`BAe`qY(9jS?3DC8#RyXs1&wCWr2!nK|kUd z)dRE^Yv<=8TZ(4jKLjDPQ1SwRVgyCmg!V$suIKGu^?J|}%sA@+F*)4;y}60nl>*mw zOHqC8HW=}NEpGs^xlmQmgh^)AhqURe1sE1RN3O~)J$bj;UUi+8VCApqiNU>U9EpHI z6X;#l{F9~uN=FBN2yG5EEF?9A1hXlf-Q1w|uQ&@(l!P>!4v~fs7g&uW-V7TZD0(s{ z0D$Lo+NKoZmU>;Wk}yC$VY^Dj!8;+;wT#8=taG|@O5TeL$i9w~AXuq!**oZ9vJ|06=7}R*nWez~no4 zj$cF3V6;c>hRxlGxf|u3my7l;TTSaW>l-uA_L;kJF9%tYpKqXPeIFwBYxss`T%ueA zRC^7OXdYOCkKzKYI0YsIQOHFQMfpt2U0d|rH`v|(iEplVJdsqDS`ADc)oLk(Nper` z4^AU*@B%L{^70Zd!@RuA3jtA_Z?u~6D50bvC9(KagT{RtMl}VIgId`28*!o445Rpf z0*p0{`{l(j-Y-CVTjE5dt*HL=U@z-_#Edy-C+w-zybI$)WQ`4)Oh`>_rZ7Ip2Z?c* z0RC{g6dY%#cI&eAb~{lM!ue zjeb!WFZ~6+U-b6v7=meQr(Hvvt%$F%EAgWTYitYbwrc$Xt`xAQ{R>!Wzbw)woB!N8 z^SR}GZoNV99Bp>}xSWXX;5obu1TCH1*%wl%R{K-r3CT@4tFL|PX`jKxhVd&6Q!M#Y zcz>?tf>)3VyLkV6C%OpB+h2pN;Cq7UgZJ<(!=q%+;0av*2fj(gkEDdzVI=Hmf|<$$ z(445AwQdE+B5T#YhsnGulb04NT_589uzM@ij_zXEX;Gsn@k-;>cfdwV&1INNFlR-R zX}wi}44m(@{d(O9Mi{YeD6ecTt+P^vFh5-kXj{j2CyWcMC@!panr$_GcB2L7+W#Ug zL}V3*tZ}et4h9SH@-%H(MAPkmWE8d6>ZWt$VhI>n+?v z3gt!O*z-O6hcnZK;4<>ZrKM1sTY`BWG`rG^&uqm!SCL`+7_!}8;;Y(?2{2~w7%H|( zT12^#3>8iA-uLVEgK!%Y-jS`ZOMOH>lj%}0#?D=17vXyV*1EfZ17uq1~qrr2)*c?0XqVONqk|=cw+1nOdsvC_U*0rkH8T^QRqHOF_76Jqd6= zRe8;jV;&-S4>+lM#PCH;^FRVx;yk?4@krE(+!mZ@BuY4)SCj2yyc+Bxq2q(}sP8E9 zDRMitcW#uhrC|3SGxKlP7lI?m+cy=-{|2F)!VgNna5V9|!Ve31hY2Yjb6cs_6+ zX_zJU&uBR3dw)v0iaRpFV`5qw^H5uh-#|<`XB{OdF&^%E)LElFDn?J>F9Umul>y1o_eQG^y!}y&e}Ts;IL~^O4{or4^3q{^#?Q~ zOqYWXKUx`uuCUb)kra&bGR4a?%#nxs7Af7wA3x&re%Tj~32$U-oHgRPT(ZiA zA^1JVzU&<_?6Ez6pK`>zDO0dHWC~G+PGlK%2zzQZci*OHq^RTzWmkinLWJte|w~ z!;JSl6s8zYgmr?jL}3Qs=TEUNcEc&d(%zbC?j@s_%0t$K-8*OoBAY9=gGFHfa^e$+ z3tVwg2$2&t`SeX%qHwCL4GYU9Feo)VdI2qoYzQPJBEDDCIBFofd+V;t52Y_s8*3`n+_<`_lSNxlP1ExsW0Mw4A zmMSFB)bw;($*gkmB_*ehHBuo-&5l4{J(`u%(MZ9ZE|^R*>&UPsbXAL1AUK~@oXc(a zjr72Qj(z2a>s_^Kb1_T_H2!0tH@3 zZN-IJ_It~|PcUHjet2yK3wM|hGT5_h!E9X`fSJvi22iX>^7;=Z-=15T{E_iVaz>>v zE`e8xUy@JbJl=pCq>GwA)0io3?Y8dc0f9EyX~;b2v)-_gxp=TE2zqd@e)KTCx^ns2 zLw2jcSAqb|3_@PE^`y}4gwd@`S4K=%_~aq`@=zmm<^6~3N*-@KxF`AUdUPk#k#tP( z;34}_dzdjfKX++vVea9Wt)yOhaBoVU--5yS8<`I6H6x>*J!GGLK2Rs`(xMV_5>`!u^SfAKSc^!t5-=cgdxPOA# z$e1LAM!=1?&1`@qOn|=Fz?2shi^@cXd&Ouj%4|_cT5MOGbFdR&1uKCA;ZdUjz-;xz zgoH;3`Y=dA2ds6siI-f2+W?lJBCJ^`m#3J88I1EyfW(^w5hCiQCTAw6O76h_nefi!JFuKPC!G&FLCbq$G6fLVeBYUc(K}m5pPrK%o>O!J6=6?@$*K-( zT0l3jjMaswGE&Qj3V;J@$QoQ?!Y42+yTV9I$~4;;a~jgs>q)TyX##2J>;RnD)lb1@ z7*XH%Lbd_*da4AF{hhh9=aDyAMrC*E^~+ZlE?%C$#&kduQ49UXVP=>TsD)uy%Wrha z39rx-O4Q0S`O!Hw`^-9XHxUv8G%57dZWm1=^NzfiEd1W^gX=wieOX4FMPDVaX(K1C zC!l|;feB?kR7adS`|*`vr%y$Pda$K#S)bag)~DjxUCK9epXP`pENEHk*7>-ci~vAE zzT4@>!&yd$hl~+6!7W^%9R(7Ib`-22I)%nUJZPZDKjTCfXSFqKO<27r%w!i{NmrH3 z8>oX2C@yolNyMFoBB>hwb+$oj`!(LN%AkYG@31m^}08hbkC4=|F8$%?TDlQk=6%c|{qZ0!HCIh_%3sL0M z>!!ED;u`j`e1Jl-JQ~vkCj(m5anc+aVaigeI%=p zuZy6}7*PNJ$Uo<7+mVG+!z@Y2L*O>)IEE}mI7JetNR5<)OfE94B+-8K>Vq-CAEuyW z>SsoVEck6@Y=#xx)(v+P4Pj75zhqS*3Rw|M&SpN-EHf{~O$WcY7Vnv6_H($`fpN*j zjkeE45I1Ntrol(mm?tn5mB;%eLN5{Ckj9#lZJxY3kYNM-nMgCGplKy;#`^k*_l&Fgx`Cw0_QGcMENZ!%+cp94v`uTRPx z0EjR(lK?WIlRQ%<4<99;Z$1+*E^U)N!i`9y^g}GRr|rU!VhKS+O^gT}JP5%IQ?Asu zTt+ox6e-r!Fp2;*ETV&rAv{rcGmTqHD&8sUb@BZzP#!#(%-~j8XfQO=yq7qkvLHoR zZpUiML*s>n_zGPlzZ9#X=UA;#+@)+?5`s)?8pu(i8-=pYhyey`p)c@zW%(G3Oj_}9 zT@gzV$q4iBd9?(D-gEuMNKV9q5Y8dY3y3huulr~+siya}fW_==x+#Gr^>uYe;X6mp z0IRbeX0`~b6v(Mz?ZbJj1HLds!HXcs%A8aiXO{$aw87N){|d^@2j2szNJ32vTnTO? zHMqmeE?$`6CwTC$2z|s2@m9w5n^l3pRfIk}qXF_rO}^nce$cL3g1;AWOJy!rieLAi zpn`8|RVC(t7*%GBlkwHeD0)idZ6fi7qiH9(S&qZZq>MDh>}G%c-%CdSCh$Sh!q+FY zv-xYJW15S+m3$~4^^@I9u|BM#XHHV_H=pyIT!tj9Innqj(>4fFlMnAX$YK&Gx7w%H zD&YSaf&LPdgO~`$DM+mOXPR4%Gr<7+;MehU1Z<{Iwl!q+o-}|y>BKIWUP?&ZtipvX zNR|7Sc_$E_5B?ktRfX>xEo5ShlERg-BaDvR{3OQCIoyYbap9uTJpl4$m^*515$278 z=XGSx!1IJ=6i&f9o&DfkpkXYeCjdReSr@X45V9<&7YIa8pa{Bu!MkRo1bz1io`v~* z5*swkXdx$;Y(!+WI?Gr{CcHo)*u8-`3rPCUsKU`P74g6vh9=r8 zqFykx=hRZLbZI?6b_VT=v8DnFpVL7i<_0VFggbg}4MT1{TJw zk_q)Fo-6J*Q!5_rAGrNymhC@a^$wX?)}O1-S@tk9VeqSGg4)xRod}#G!t`p5HN%;G zLkhBIMpMQ^>0DTv>PLe_X)9I}x$P^7I)#!-n+v8(psa48NH3eDrO|s-);pG!vKIKK2Gv&~czAjH21|0!|ra_2( znZ7lD2E_+TYEYHJ8ie66V^%SuC(EiQ4RvAcVvi-FBM=&}MEEPynHROCE<4iPLx*9g zh<_9GGvjGW6Hkd+iq%+J@tG11koF8Qrr?3!3?cz|f?-z>Jse%PotD#xun!R9rCwwx zp577J7l$>c7QAOOE*Z)f>{4}J7Y7Gcgs}-$l~U8yPxU*6k-5@c4_CG&6N9j<XqHlMj;u^}u zg1FX)rYyvtV7n+IxG+Ibv+gxm9^NdpZxMd~HN1$;i2jBP_cW-Fy^K=xdYE;w$uz?2 z@Y=37unUoUFhS33Al8BoEl*iNO+|O3gGFo#3+e(RDzGII2@P3h-E{Q+4u8|MUDHm& z1@y#jF0Wt}6DtH{3D_G!l-$w)q zCVGpEne28ZZ)2GR!GyxF+2Ul!^D^KCVPqJw3|FFdQA*0sdUKeDn&kJOL$s7FiKCBt z>h&vE=dR6N{a~(k?(+P?+(!$w%k#ClkIv1>`UYk&UYGcF6_U6C&zOpFOymF+!P&1@ z1Y^l4CDP|LqYIvdE=Xg*w&&ZS4)Un%9KPWJTvQC$5gmh`fcD<01hIn^Fl1`8elqj1 zgG+CAH?y?DEiZ4e7Z22A`?TCh_k++fPS-SK4jJ#BgQdCj)rrX5@Uu1QbVo8HP63Yg!8NSi@pdU|WU`z%jEuglfdf`@$ zyx0oq2SHyKGnwcmF<}r{iO?+1!GfZ$-c*hEi13XIPoSj=@T@prYi2>aI<6@T@}9dW zTZqVAM;x>ghl;qAc?u5_`%#-MV-8?Jlb9aJsx2-=&e;r>k{#_r`3Dhz3SMHSWfT&_ zR5|Fx^QNMkxZO&v;cSDss&OdA2(@(j*#T$6gBf>%OU_b2-=?J%!@XnR-p7rxuzT)r z!@|9Pa}FH2NbPGl0m@rgSsOV}*GNeC)?^dt1(KT)>*HJJVuWzb?IwdEYKES?RcP6i zq|PIeVbE--2L^*J1D~QC%7pV@N!no&E9uH#G6XGwplK{+HV;-vAxE%qh)rw;1nll! zlH6tkutuaNEIja_bfOIw$tApgGauv>+ z;oGz6;sF_6z^T|6C=S?I;+-LnOf4!3A_G-rrAaD+MtT4s6|aM2R4ojqUOe?;KMbYg zp^MpBgVsf)EYQr9yzt;ig%bkj_zo1bUe57vqQNIlIw(HX@gD=-Q90stg-oAxOEgOc zi%l%O2b(FS!tJPfXD80<^DgFyUUqhe+ZCILuQ$X`HZp!~&ys?v!nA)#Fre?DZ!euX zmG%u7XWJIqQ&>2e6L?`N3oCsm6ah(bbAG0m+L60M9?Xh# z5{yna6p$bh9|a|qrzTgQdyqr2`-fbUBP9{s(VH@ANBBbbZ8vW)ozRIlSjtYl!GDug(Hk5O zXG^(bYI0>r>R|BAA>6dvl`O*!gY3xTL$r)(| z!vTgU%t){ljy{r=EgER#FgQq4`ES@{J%muraPC*n&)&-mK@%vhUt#FRDXGwB2SV7m zw1InmANKMd=R1Z6<3aNd&iBC!+x%(4&yoH2$=E~%xnb_0;n_i@FAF8x z8po8ft)VZ6N*O$t5U*dx6Ns3qh(@F`nE{jl$p#hbm;=eFr9M204NxU>o) zvo8Tv>4WgVf&;;CV_bqNF9W!cBa^PjgC?h9&cBNcK()Wa%zuX$5zeWE{@Y0VBeK^7 zZpdCkcEPr-!j~o6{-S^lTSIowF*5rBOpZeX@WIO9BFezA6S#jXAoIjSwHojQLJw-S zc(_*kFfZqvIIjSK52$&r) z=7Q&WA#@Jrc)5g2Tv+UMT5=>nT!!f{hy2L~wz!1l7RXuI`6l~^6&YpMTb=KZ@KWN% z#U-{cUXDu`^=sGx*JSFey!@1xE-%x(M7(V9a+8-HFI&8HczKo=uD+|4b*`NUf0Y;N z+TgG8a*&tb;Dw_Q{B>TqNE!T$mqWb#CN6RD{WiRM!7rFVUr6v3P4%aB#rSB5AVFB~o$E{gK9a-ZAa0&LLWzt4w%k~=t> zAI;m=#9+ZX48b!tfcw3?KX!0z9QVV=4o#FM2F$<5?Sho_zg0OyD5qfAe>Qq<{1C*} zL45b(`!t{0UyKguzbI+EY}@13=oh0;+xc;dx<4O%lqrY52-s@y@@@Q47F1Sn@t(p< z1Q*G;1+lblg<}v;vKftzBL*q-!i#jZarf_v-vVzyKEUWv0z)kzX#>wJ^(z&o!oOv5 zCptOt!0FI6s2)nT#)#EwOGmJH*r_Qq2!Eu%GInMF zwr&Nfr(Nk{r6U5d1Aruy>}CzBV$()Qd2fFS4bK8W-)$-y`7E3VA^1`iJ38f`80%|A3c&flEB18mAeK-C-BdodKMdLmCNx;bg86 z*-L7;xj<)0@K0F|&mV|~HR0qSw(V>_&J#azg0GsjlBEdQrjAg8P8r5I1jF#kmGa!@ zT(Tyhy@u>DyNnY;hK1XQ?E{5jC&Qyi#q|FOH)@X|?7jRg2uB=6 z0C5R1nO8f}qvC2w*dl*#U<(WqyowXRFaan|ad1nS>;y}(c&oHkx;Jt-8k<58nBoh*_X`K?uD+H_?ZOEICGB<)NkhcIl0 z71gf#v{E!1&43H*ILpw2BI-CjmpKN#O#sswf@hMAzNq5w<+5H*t`m z{t8KlV*rRMc9R6sPMY3|kYC$9ZZn7b8?Gem#HFY~xfmfSCJ`MX*msSa=%P#85-C+3ND!obYxkY3|t^Y-#x zu_pHMPAm*D55%qzlR|6=niTQK!pB#z^!v`-x%V#4za5wLS;L{6$pT#=M|sABJmm$O zk^ELXKwIkrH&9m3G;5$MLfJKh6iGB9G0 j$NXn!u1Q+|UrP6U$v&DNn;88`F8OzIyj(s~e)0bRK3Mu? literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/flask/__pycache__/sessions.cpython-39.pyc b/venv/lib/python3.9/site-packages/flask/__pycache__/sessions.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e1db424f336ee65f7a4c0e3c42bf6c4c1bf1e5de GIT binary patch literal 13111 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/flask/__pycache__/signals.cpython-39.pyc b/venv/lib/python3.9/site-packages/flask/__pycache__/signals.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..36bf1ecb28731ecdf384f8e5029927fccd3549fd GIT binary patch literal 2378 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/flask/__pycache__/views.cpython-39.pyc b/venv/lib/python3.9/site-packages/flask/__pycache__/views.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34d2ee6c36639cd6c65563b5f68e6b0be3af470a GIT binary patch literal 4922 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 Rw_S(V|Krt8UOoN%e*uYsO=kcA literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/flask/__pycache__/wrappers.cpython-39.pyc b/venv/lib/python3.9/site-packages/flask/__pycache__/wrappers.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c741282d0a1dbee561211cc9ac384e6c041186c3 GIT binary patch literal 5037 zcmai1OOxBi5e7gk$>nn2k}Nri3Q3eGtg=YiPO6kGB^6m-OB>6Svs#xETtE;rB(aMJ zJs9qathG~Rsp4DyK$MDobX9&!jyd3(TwKW^=Tu%_4<7rX9ByG27z}!PzV80I+g)C6 zX!!kI{-gKT%bNBVdN}1A>-cX3Mp&^cI?YuAGhDE%>fXeC&938q zfmMUWuwggUeJxlDn|4#(*MsG7#a_`huJ5mkeI<3xUdR8%U?beLH+AiS#u{wtxyF`w z^;yMUz;lx=<9V6a@myp26RoxK6?D?NEj?|#<+5G=(S#=wPqmZV`Yun#ag^|{bS%X? zb3chA{9p1WLhwjB?s$yH%T6*5eChOq2_Fj|^J7UsT| z#%eEgR%eUP&1bs3k0z&(fi;aM){zULGKP}l!1c0CvH4u3X}#x0Rx;@;vCtA* zl12%aN{KC3N>T2X9V_3{QJ?f^FUS$4kX-#aK#}Z|0~~R2FyoV9`$)j?fKfa5)m|xz zR8eY-MSSQpj_-rOiU)+IMVk5jiNx%OxhOJ$A7Nq~OlYqGU{yLRA<39~{=oOF7)#n} zsw);@*t9+ofg|AE=^~lJfhm%7UBnaVM?;4{_4ru&arC90Rt1+65qT6s#gFa{T=#J$ zS1?FTtVnHNXZkhm3H&{~T9w(IUGB15aTH85ljkSt_1?SpOXvRM?%sBH&v~@neX#ei z*R#Ah8u&x&fKS`@#>ExgmLY1`Ev;q?p`DrVVDP0THZc89w=;@E-jRM7%h7b~GdCIW z!_M10Igs(V^T3y*Nx$=cEaV^#{J3+-qr*<%_dDaM9L3R_?H_j%U-DaH*E?{BJn1Np z>y*|SPt%Ried=I$N$e5uXedWNA`q$=w2G-WjM=NXQQH@nem#iC+CE5RqKgf>+Xu-h zqBC3&t%|}jf+U4V5m%>O{e#^{xieDa?U8RE`EZ~$CZAXl#7Qttc%+z|dB>&I|sSmOpWj`c%L+&I=h*O~E!PQ;$u#&q{f zh8+5dms|G4 zqNSKQmSr&rg*J`2$CJbrKEhW?R<=^-BOOZ(K*32V&=cI1fPoyMZGqE6cMA79#CrG^ zWCA9pbQZkCOnJ}A*;PB$w3^f&G2tjjk<0c zvyBV*Cl?G*M(168F163~W9T^i4{Pf_-hgLh}w-^p?YiXa9OXWaVvlgHh>GTgFS z6_ujJbqEx+MG=Z*+5jCUWp@zN^+$=6&_hW`ZeBV?5#H_La!I6oWHzvEv-8a z`JLmW4aY(DKw*RXrsI4xafAF#&2d=lIgX%Qoi3?;v!z*9(PdhHtg0S2fMFds0tKqv zmf)i$`pA46K9E+Bx6;bJXeydCxwu_aOKBZd8*D45X$6I@xP;dk9Z{I1<|D+YAPP~o z6@>XIL=-kEgORsWW=jafhHf^^=7xE_x?vdll^U)UTpPI7R#sJ+?qS)PA2~Dqk~c6E z9SZd)=tNA8ZjIMC`jZ#>XWBq#CR=#kM8B~3nPzHs17@xY>T%pZ!hRW_Wo=YZ{;To> zdFgA~fDdDFkbsm9I5Co<43Rfug_MDa!;?A|Wi7E5s&Fc=Rk{GTJ=}W_IV}$(bR0@h z-gTe>_{9X}8rT)pnCb*r9Nm=J#}JYwBJ2;jdE-K5J5`KGMV<@wmAoxP>F8X=AG!zJ zDKze7MU=!G>KV|hO71AZ5cjli&Y3%N+YvfHGQwE|6>=}_MU+;A#Qa_)6ZL30 z5;G)2;^Z`Cd4W&qtVDsRl3F`rjvTy~>054ak8)6fNLE_M2R?Taf5v-Rg)m!`{Hg4W zWEhBLIPjS?LRACt5e3(ro`pzmzoK&ZALjQgTcq_?-ncw|cW2vqvSV+bXx}59a@gOMlP|Ey}mM97&{`n2AgbIF?3G1d|g8mdQwJxPqq*XYY zpkm$LECDY2)t{XWx1g?4C1~UBnnl#RwQgHbJFF# zU%kKW+<&-z|J|ML1A9GF1RXOth)Sg-H6*v!%8m1uT6Nv?$Ud##&63bh$w8H4){Ul) OzkICfb-h_xJNzFx{%?!` literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/flask/app.py b/venv/lib/python3.9/site-packages/flask/app.py new file mode 100644 index 0000000..3abce3c --- /dev/null +++ b/venv/lib/python3.9/site-packages/flask/app.py @@ -0,0 +1,2088 @@ +import functools +import inspect +import logging +import os +import sys +import typing as t +import weakref +from datetime import timedelta +from itertools import chain +from threading import Lock +from types import TracebackType + +from werkzeug.datastructures import Headers +from werkzeug.datastructures import ImmutableDict +from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import BadRequestKeyError +from werkzeug.exceptions import HTTPException +from werkzeug.exceptions import InternalServerError +from werkzeug.local import ContextVar +from werkzeug.routing import BuildError +from werkzeug.routing import Map +from werkzeug.routing import MapAdapter +from werkzeug.routing import RequestRedirect +from werkzeug.routing import RoutingException +from werkzeug.routing import Rule +from werkzeug.wrappers import Response as BaseResponse + +from . import cli +from . import json +from .config import Config +from .config import ConfigAttribute +from .ctx import _AppCtxGlobals +from .ctx import AppContext +from .ctx import RequestContext +from .globals import _request_ctx_stack +from .globals import g +from .globals import request +from .globals import session +from .helpers import _split_blueprint_path +from .helpers import get_debug_flag +from .helpers import get_env +from .helpers import get_flashed_messages +from .helpers import get_load_dotenv +from .helpers import locked_cached_property +from .helpers import url_for +from .json import jsonify +from .logging import create_logger +from .scaffold import _endpoint_from_view_func +from .scaffold import _sentinel +from .scaffold import find_package +from .scaffold import Scaffold +from .scaffold import setupmethod +from .sessions import SecureCookieSessionInterface +from .signals import appcontext_tearing_down +from .signals import got_request_exception +from .signals import request_finished +from .signals import request_started +from .signals import request_tearing_down +from .templating import DispatchingJinjaLoader +from .templating import Environment +from .typing import AfterRequestCallable +from .typing import BeforeRequestCallable +from .typing import ErrorHandlerCallable +from .typing import ResponseReturnValue +from .typing import TeardownCallable +from .typing import TemplateContextProcessorCallable +from .typing import TemplateFilterCallable +from .typing import TemplateGlobalCallable +from .typing import TemplateTestCallable +from .typing import URLDefaultCallable +from .typing import URLValuePreprocessorCallable +from .wrappers import Request +from .wrappers import Response + +if t.TYPE_CHECKING: + import typing_extensions as te + from .blueprints import Blueprint + from .testing import FlaskClient + from .testing import FlaskCliRunner + +if sys.version_info >= (3, 8): + iscoroutinefunction = inspect.iscoroutinefunction +else: + + def iscoroutinefunction(func: t.Any) -> bool: + while inspect.ismethod(func): + func = func.__func__ + + while isinstance(func, functools.partial): + func = func.func + + return inspect.iscoroutinefunction(func) + + +def _make_timedelta(value: t.Optional[timedelta]) -> t.Optional[timedelta]: + if value is None or isinstance(value, timedelta): + return value + + return timedelta(seconds=value) + + +class Flask(Scaffold): + """The flask object implements a WSGI application and acts as the central + object. It is passed the name of the module or package of the + application. Once it is created it will act as a central registry for + the view functions, the URL rules, template configuration and much more. + + The name of the package is used to resolve resources from inside the + package or the folder the module is contained in depending on if the + package parameter resolves to an actual python package (a folder with + an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). + + For more information about resource loading, see :func:`open_resource`. + + Usually you create a :class:`Flask` instance in your main module or + in the :file:`__init__.py` file of your package like this:: + + from flask import Flask + app = Flask(__name__) + + .. admonition:: About the First Parameter + + The idea of the first parameter is to give Flask an idea of what + belongs to your application. This name is used to find resources + on the filesystem, can be used by extensions to improve debugging + information and a lot more. + + So it's important what you provide there. If you are using a single + module, `__name__` is always the correct value. If you however are + using a package, it's usually recommended to hardcode the name of + your package there. + + For example if your application is defined in :file:`yourapplication/app.py` + you should create it with one of the two versions below:: + + app = Flask('yourapplication') + app = Flask(__name__.split('.')[0]) + + Why is that? The application will work even with `__name__`, thanks + to how resources are looked up. However it will make debugging more + painful. Certain extensions can make assumptions based on the + import name of your application. For example the Flask-SQLAlchemy + extension will look for the code in your application that triggered + an SQL query in debug mode. If the import name is not properly set + up, that debugging information is lost. (For example it would only + pick up SQL queries in `yourapplication.app` and not + `yourapplication.views.frontend`) + + .. versionadded:: 0.7 + The `static_url_path`, `static_folder`, and `template_folder` + parameters were added. + + .. versionadded:: 0.8 + The `instance_path` and `instance_relative_config` parameters were + added. + + .. versionadded:: 0.11 + The `root_path` parameter was added. + + .. versionadded:: 1.0 + The ``host_matching`` and ``static_host`` parameters were added. + + .. versionadded:: 1.0 + The ``subdomain_matching`` parameter was added. Subdomain + matching needs to be enabled manually now. Setting + :data:`SERVER_NAME` does not implicitly enable it. + + :param import_name: the name of the application package + :param static_url_path: can be used to specify a different path for the + static files on the web. Defaults to the name + of the `static_folder` folder. + :param static_folder: The folder with static files that is served at + ``static_url_path``. Relative to the application ``root_path`` + or an absolute path. Defaults to ``'static'``. + :param static_host: the host to use when adding the static route. + Defaults to None. Required when using ``host_matching=True`` + with a ``static_folder`` configured. + :param host_matching: set ``url_map.host_matching`` attribute. + Defaults to False. + :param subdomain_matching: consider the subdomain relative to + :data:`SERVER_NAME` when matching routes. Defaults to False. + :param template_folder: the folder that contains the templates that should + be used by the application. Defaults to + ``'templates'`` folder in the root path of the + application. + :param instance_path: An alternative instance path for the application. + By default the folder ``'instance'`` next to the + package or module is assumed to be the instance + path. + :param instance_relative_config: if set to ``True`` relative filenames + for loading the config are assumed to + be relative to the instance path instead + of the application root. + :param root_path: The path to the root of the application files. + This should only be set manually when it can't be detected + automatically, such as for namespace packages. + """ + + #: The class that is used for request objects. See :class:`~flask.Request` + #: for more information. + request_class = Request + + #: The class that is used for response objects. See + #: :class:`~flask.Response` for more information. + response_class = Response + + #: The class 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") + + #: The secure cookie uses this for the name of the session cookie. + #: + #: This attribute can also be configured from the config with the + #: ``SESSION_COOKIE_NAME`` configuration key. Defaults to ``'session'`` + session_cookie_name = ConfigAttribute("SESSION_COOKIE_NAME") + + #: 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 + ) + + #: A :class:`~datetime.timedelta` or number of seconds which is used + #: as the default ``max_age`` for :func:`send_file`. The default is + #: ``None``, which tells the browser to use conditional requests + #: instead of a timed cache. + #: + #: Configured with the :data:`SEND_FILE_MAX_AGE_DEFAULT` + #: configuration key. + #: + #: .. versionchanged:: 2.0 + #: Defaults to ``None`` instead of 12 hours. + send_file_max_age_default = ConfigAttribute( + "SEND_FILE_MAX_AGE_DEFAULT", get_converter=_make_timedelta + ) + + #: Enable this if you want to use the X-Sendfile feature. Keep in + #: mind that the server has to support this. This only affects files + #: sent with the :func:`send_file` method. + #: + #: .. versionadded:: 0.2 + #: + #: This attribute can also be configured from the config with the + #: ``USE_X_SENDFILE`` configuration key. Defaults to ``False``. + use_x_sendfile = ConfigAttribute("USE_X_SENDFILE") + + #: The JSON encoder class to use. Defaults to :class:`~flask.json.JSONEncoder`. + #: + #: .. versionadded:: 0.10 + json_encoder = json.JSONEncoder + + #: The JSON decoder class to use. Defaults to :class:`~flask.json.JSONDecoder`. + #: + #: .. versionadded:: 0.10 + json_decoder = json.JSONDecoder + + #: Options that are passed to the Jinja environment in + #: :meth:`create_jinja_environment`. Changing these options after + #: the environment is created (accessing :attr:`jinja_env`) will + #: have no effect. + #: + #: .. versionchanged:: 1.1.0 + #: This is a ``dict`` instead of an ``ImmutableDict`` to allow + #: easier configuration. + #: + jinja_options: dict = {} + + #: Default configuration parameters. + default_config = ImmutableDict( + { + "ENV": None, + "DEBUG": None, + "TESTING": False, + "PROPAGATE_EXCEPTIONS": None, + "PRESERVE_CONTEXT_ON_EXCEPTION": None, + "SECRET_KEY": None, + "PERMANENT_SESSION_LIFETIME": timedelta(days=31), + "USE_X_SENDFILE": False, + "SERVER_NAME": None, + "APPLICATION_ROOT": "/", + "SESSION_COOKIE_NAME": "session", + "SESSION_COOKIE_DOMAIN": None, + "SESSION_COOKIE_PATH": None, + "SESSION_COOKIE_HTTPONLY": True, + "SESSION_COOKIE_SECURE": False, + "SESSION_COOKIE_SAMESITE": None, + "SESSION_REFRESH_EACH_REQUEST": True, + "MAX_CONTENT_LENGTH": None, + "SEND_FILE_MAX_AGE_DEFAULT": None, + "TRAP_BAD_REQUEST_ERRORS": None, + "TRAP_HTTP_EXCEPTIONS": False, + "EXPLAIN_TEMPLATE_LOADING": False, + "PREFERRED_URL_SCHEME": "http", + "JSON_AS_ASCII": True, + "JSON_SORT_KEYS": True, + "JSONIFY_PRETTYPRINT_REGULAR": False, + "JSONIFY_MIMETYPE": "application/json", + "TEMPLATES_AUTO_RELOAD": None, + "MAX_COOKIE_SIZE": 4093, + } + ) + + #: The rule object to use for URL rules created. This is used by + #: :meth:`add_url_rule`. Defaults to :class:`werkzeug.routing.Rule`. + #: + #: .. versionadded:: 0.7 + url_rule_class = Rule + + #: The map object to use for storing the URL rules and routing + #: configuration parameters. Defaults to :class:`werkzeug.routing.Map`. + #: + #: .. versionadded:: 1.1.0 + url_map_class = Map + + #: the test client that is used with when `test_client` is used. + #: + #: .. versionadded:: 0.7 + test_client_class: t.Optional[t.Type["FlaskClient"]] = None + + #: The :class:`~click.testing.CliRunner` subclass, by default + #: :class:`~flask.testing.FlaskCliRunner` that is used by + #: :meth:`test_cli_runner`. Its ``__init__`` method should take a + #: Flask app object as the first argument. + #: + #: .. versionadded:: 1.0 + test_cli_runner_class: t.Optional[t.Type["FlaskCliRunner"]] = None + + #: the session interface to use. By default an instance of + #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here. + #: + #: .. versionadded:: 0.8 + session_interface = SecureCookieSessionInterface() + + def __init__( + self, + import_name: str, + static_url_path: t.Optional[str] = None, + static_folder: t.Optional[str] = "static", + static_host: t.Optional[str] = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: t.Optional[str] = "templates", + instance_path: t.Optional[str] = None, + instance_relative_config: bool = False, + root_path: t.Optional[str] = None, + ): + super().__init__( + import_name=import_name, + static_folder=static_folder, + static_url_path=static_url_path, + template_folder=template_folder, + root_path=root_path, + ) + + if instance_path is None: + instance_path = self.auto_find_instance_path() + elif not os.path.isabs(instance_path): + raise ValueError( + "If an instance path is provided it must be absolute." + " A relative path was given instead." + ) + + #: Holds the path to the instance folder. + #: + #: .. versionadded:: 0.8 + self.instance_path = instance_path + + #: The configuration dictionary as :class:`Config`. This behaves + #: exactly like a regular dictionary but supports additional methods + #: to load a config from files. + self.config = self.make_config(instance_relative_config) + + #: A list of functions that are called when :meth:`url_for` raises a + #: :exc:`~werkzeug.routing.BuildError`. Each function registered here + #: is called with `error`, `endpoint` and `values`. If a function + #: returns ``None`` or raises a :exc:`BuildError` the next function is + #: tried. + #: + #: .. versionadded:: 0.9 + self.url_build_error_handlers: t.List[ + t.Callable[[Exception, str, dict], str] + ] = [] + + #: A list of functions that will be called at the beginning of the + #: first request to this instance. To register a function, use the + #: :meth:`before_first_request` decorator. + #: + #: .. versionadded:: 0.8 + self.before_first_request_funcs: t.List[BeforeRequestCallable] = [] + + #: A list of functions that are called when the application context + #: is destroyed. Since the application context is also torn down + #: if the request ends this is the place to store code that disconnects + #: from databases. + #: + #: .. versionadded:: 0.9 + self.teardown_appcontext_funcs: t.List[TeardownCallable] = [] + + #: A list of shell context processor functions that should be run + #: when a shell context is created. + #: + #: .. versionadded:: 0.11 + self.shell_context_processors: t.List[t.Callable[[], t.Dict[str, t.Any]]] = [] + + #: Maps registered blueprint names to blueprint objects. The + #: dict retains the order the blueprints were registered in. + #: Blueprints can be registered multiple times, this dict does + #: not track how often they were attached. + #: + #: .. versionadded:: 0.7 + self.blueprints: t.Dict[str, "Blueprint"] = {} + + #: a place where extensions can store application specific state. For + #: example this is where an extension could store database engines and + #: similar things. + #: + #: The key must match the name of the extension module. For example in + #: case of a "Flask-Foo" extension in `flask_foo`, the key would be + #: ``'foo'``. + #: + #: .. versionadded:: 0.7 + self.extensions: dict = {} + + #: The :class:`~werkzeug.routing.Map` for this instance. You can use + #: this to change the routing converters after the class was created + #: but before any routes are connected. Example:: + #: + #: from werkzeug.routing import BaseConverter + #: + #: class ListConverter(BaseConverter): + #: def to_python(self, value): + #: return value.split(',') + #: def to_url(self, values): + #: return ','.join(super(ListConverter, self).to_url(value) + #: for value in values) + #: + #: app = Flask(__name__) + #: app.url_map.converters['list'] = ListConverter + self.url_map = self.url_map_class() + + self.url_map.host_matching = host_matching + self.subdomain_matching = subdomain_matching + + # tracks internally if the application already handled at least one + # request. + self._got_first_request = False + self._before_request_lock = Lock() + + # Add a static route using the provided static_url_path, static_host, + # and static_folder if there is a configured static_folder. + # Note we do this without checking if static_folder exists. + # For one, it might be created while the server is running (e.g. during + # development). Also, Google App Engine stores static files somewhere + if self.has_static_folder: + assert ( + bool(static_host) == host_matching + ), "Invalid static_host/host_matching combination" + # Use a weakref to avoid creating a reference cycle between the app + # and the view function (see #3761). + self_ref = weakref.ref(self) + self.add_url_rule( + f"{self.static_url_path}/", + endpoint="static", + host=static_host, + view_func=lambda **kw: self_ref().send_static_file(**kw), # type: ignore # noqa: B950 + ) + + # Set the name of the Click group in case someone wants to add + # the app's commands to another CLI tool. + self.cli.name = self.name + + def _is_setup_finished(self) -> bool: + return self.debug and self._got_first_request + + @locked_cached_property + def name(self) -> str: # type: ignore + """The name of the application. This is usually the import name + with the difference that it's guessed from the run file if the + import name is main. This name is used as a display name when + Flask needs the name of the application. It can be set and overridden + to change the value. + + .. versionadded:: 0.8 + """ + if self.import_name == "__main__": + fn = getattr(sys.modules["__main__"], "__file__", None) + if fn is None: + return "__main__" + return os.path.splitext(os.path.basename(fn))[0] + return self.import_name + + @property + def propagate_exceptions(self) -> bool: + """Returns the value of the ``PROPAGATE_EXCEPTIONS`` configuration + value in case it's set, otherwise a sensible default is returned. + + .. versionadded:: 0.7 + """ + rv = self.config["PROPAGATE_EXCEPTIONS"] + if rv is not None: + return rv + return self.testing or self.debug + + @property + def preserve_context_on_exception(self) -> bool: + """Returns the value of the ``PRESERVE_CONTEXT_ON_EXCEPTION`` + configuration value in case it's set, otherwise a sensible default + is returned. + + .. versionadded:: 0.7 + """ + rv = self.config["PRESERVE_CONTEXT_ON_EXCEPTION"] + if rv is not None: + return rv + return self.debug + + @locked_cached_property + def logger(self) -> logging.Logger: + """A standard Python :class:`~logging.Logger` for the app, with + the same name as :attr:`name`. + + In debug mode, the logger's :attr:`~logging.Logger.level` will + be set to :data:`~logging.DEBUG`. + + If there are no handlers configured, a default handler will be + added. See :doc:`/logging` for more information. + + .. versionchanged:: 1.1.0 + The logger takes the same name as :attr:`name` rather than + hard-coding ``"flask.app"``. + + .. versionchanged:: 1.0.0 + Behavior was simplified. The logger is always named + ``"flask.app"``. The level is only set during configuration, + it doesn't check ``app.debug`` each time. Only one format is + used, not different ones depending on ``app.debug``. No + handlers are removed, and a handler is only added if no + handlers are already configured. + + .. versionadded:: 0.3 + """ + return create_logger(self) + + @locked_cached_property + def jinja_env(self) -> Environment: + """The Jinja environment used to load templates. + + The environment is created the first time this property is + accessed. Changing :attr:`jinja_options` after that will have no + effect. + """ + return self.create_jinja_environment() + + @property + def got_first_request(self) -> bool: + """This attribute is set to ``True`` if the application started + handling the first request. + + .. versionadded:: 0.8 + """ + return self._got_first_request + + def make_config(self, instance_relative: bool = False) -> Config: + """Used to create the config attribute by the Flask constructor. + The `instance_relative` parameter is passed in from the constructor + of Flask (there named `instance_relative_config`) and indicates if + the config should be relative to the instance path or the root path + of the application. + + .. versionadded:: 0.8 + """ + root_path = self.root_path + if instance_relative: + root_path = self.instance_path + defaults = dict(self.default_config) + defaults["ENV"] = get_env() + defaults["DEBUG"] = get_debug_flag() + return self.config_class(root_path, defaults) + + def auto_find_instance_path(self) -> str: + """Tries to locate the instance path if it was not provided to the + constructor of the application class. It will basically calculate + the path to a folder named ``instance`` next to your main file or + the package. + + .. versionadded:: 0.8 + """ + prefix, package_path = find_package(self.import_name) + if prefix is None: + return os.path.join(package_path, "instance") + return os.path.join(prefix, "var", f"{self.name}-instance") + + def open_instance_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]: + """Opens a resource from the application's instance folder + (:attr:`instance_path`). Otherwise works like + :meth:`open_resource`. Instance resources can also be opened for + writing. + + :param resource: the name of the resource. To access resources within + subfolders use forward slashes as separator. + :param mode: resource file opening mode, default is 'rb'. + """ + return open(os.path.join(self.instance_path, resource), mode) + + @property + def templates_auto_reload(self) -> bool: + """Reload templates when they are changed. Used by + :meth:`create_jinja_environment`. + + This attribute can be configured with :data:`TEMPLATES_AUTO_RELOAD`. If + not set, it will be enabled in debug mode. + + .. versionadded:: 1.0 + This property was added but the underlying config and behavior + already existed. + """ + rv = self.config["TEMPLATES_AUTO_RELOAD"] + return rv if rv is not None else self.debug + + @templates_auto_reload.setter + def templates_auto_reload(self, value: bool) -> None: + self.config["TEMPLATES_AUTO_RELOAD"] = value + + def create_jinja_environment(self) -> Environment: + """Create the Jinja environment based on :attr:`jinja_options` + and the various Jinja-related methods of the app. Changing + :attr:`jinja_options` after this will have no effect. Also adds + Flask-related globals and filters to the environment. + + .. versionchanged:: 0.11 + ``Environment.auto_reload`` set in accordance with + ``TEMPLATES_AUTO_RELOAD`` configuration option. + + .. versionadded:: 0.5 + """ + options = dict(self.jinja_options) + + if "autoescape" not in options: + options["autoescape"] = self.select_jinja_autoescape + + if "auto_reload" not in options: + options["auto_reload"] = self.templates_auto_reload + + rv = self.jinja_environment(self, **options) + rv.globals.update( + url_for=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"] = json.dumps + return rv + + def create_global_jinja_loader(self) -> DispatchingJinjaLoader: + """Creates the loader for the Jinja2 environment. Can be used to + override just the loader and keeping the rest unchanged. It's + discouraged to override this function. Instead one should override + the :meth:`jinja_loader` function instead. + + The global loader dispatches between the loaders of the application + and the individual blueprints. + + .. versionadded:: 0.7 + """ + return DispatchingJinjaLoader(self) + + def select_jinja_autoescape(self, filename: str) -> bool: + """Returns ``True`` if autoescaping should be active for the given + template name. If no template name is given, returns `True`. + + .. versionadded:: 0.5 + """ + if filename is None: + return True + return filename.endswith((".html", ".htm", ".xml", ".xhtml")) + + def update_template_context(self, context: dict) -> None: + """Update the template context with some commonly used variables. + This injects request, session, config and g into the template + context as well as everything template context processors want + to inject. Note that the as of Flask 0.6, the original values + in the context will not be overridden if a context processor + decides to return a value with the same key. + + :param context: the context as a dictionary that is updated in place + to add extra variables. + """ + funcs: t.Iterable[ + TemplateContextProcessorCallable + ] = self.template_context_processors[None] + reqctx = _request_ctx_stack.top + if reqctx is not None: + for bp in request.blueprints: + if bp in self.template_context_processors: + funcs = chain(funcs, self.template_context_processors[bp]) + orig_ctx = context.copy() + for func in funcs: + context.update(func()) + # make sure the original values win. This makes it possible to + # easier add new variables in context processors without breaking + # existing views. + 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 + + #: What environment the app is running in. Flask and extensions may + #: enable behaviors based on the environment, such as enabling debug + #: mode. This maps to the :data:`ENV` config key. This is set by the + #: :envvar:`FLASK_ENV` environment variable and may not behave as + #: expected if set in code. + #: + #: **Do not enable development when deploying in production.** + #: + #: Default: ``'production'`` + env = ConfigAttribute("ENV") + + @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. This is + enabled when :attr:`env` is ``'development'`` and is overridden + by the ``FLASK_DEBUG`` environment variable. It may not behave as + expected if set in code. + + **Do not enable debug mode when deploying in production.** + + Default: ``True`` if :attr:`env` is ``'development'``, or + ``False`` otherwise. + """ + return self.config["DEBUG"] + + @debug.setter + def debug(self, value: bool) -> None: + self.config["DEBUG"] = value + self.jinja_env.auto_reload = self.templates_auto_reload + + def run( + self, + host: t.Optional[str] = None, + port: t.Optional[int] = None, + debug: t.Optional[bool] = None, + load_dotenv: bool = True, + **options: t.Any, + ) -> None: + """Runs the application on a local development server. + + Do not use ``run()`` in a production setting. It is not intended to + meet security and performance requirements for a production server. + Instead, see :doc:`/deploying/index` for WSGI server recommendations. + + If the :attr:`debug` flag is set the server will automatically reload + for code changes and show a debugger in case an exception happened. + + If you want to run the application in debug mode, but disable the + code execution on the interactive debugger, you can pass + ``use_evalex=False`` as parameter. This will keep the debugger's + traceback screen active, but disable code execution. + + It is not recommended to use this function for development with + automatic reloading as this is badly supported. Instead you should + be using the :command:`flask` command line script's ``run`` support. + + .. admonition:: Keep in Mind + + Flask will suppress any server error with a generic error page + unless it is in debug mode. As such to enable just the + interactive debugger without the code reloading, you have to + invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``. + Setting ``use_debugger`` to ``True`` without being in debug mode + won't catch any exceptions because there won't be any to + catch. + + :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to + have the server available externally as well. Defaults to + ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable + if present. + :param port: the port of the webserver. Defaults to ``5000`` or the + port defined in the ``SERVER_NAME`` config variable if present. + :param debug: if given, enable or disable debug mode. See + :attr:`debug`. + :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` + files to set environment variables. Will also change the working + directory to the directory containing the first file found. + :param options: the options to be forwarded to the underlying Werkzeug + server. See :func:`werkzeug.serving.run_simple` for more + information. + + .. versionchanged:: 1.0 + If installed, python-dotenv will be used to load environment + variables from :file:`.env` and :file:`.flaskenv` files. + + If set, the :envvar:`FLASK_ENV` and :envvar:`FLASK_DEBUG` + environment variables will override :attr:`env` and + :attr:`debug`. + + Threaded mode is enabled by default. + + .. versionchanged:: 0.10 + The default port is now picked from the ``SERVER_NAME`` + variable. + """ + # Change this into a no-op if the server is invoked from the + # command line. Have a look at cli.py for more information. + if os.environ.get("FLASK_RUN_FROM_CLI") == "true": + from .debughelpers import explain_ignored_app_run + + explain_ignored_app_run() + return + + if get_load_dotenv(load_dotenv): + cli.load_dotenv() + + # if set, let env vars override previous values + if "FLASK_ENV" in os.environ: + self.env = get_env() + self.debug = get_debug_flag() + elif "FLASK_DEBUG" in os.environ: + self.debug = get_debug_flag() + + # debug passed to method overrides all other sources + if debug is not None: + self.debug = bool(debug) + + server_name = self.config.get("SERVER_NAME") + sn_host = sn_port = None + + if server_name: + sn_host, _, sn_port = server_name.partition(":") + + if not host: + if sn_host: + host = sn_host + else: + host = "127.0.0.1" + + if port or port == 0: + port = int(port) + elif sn_port: + port = int(sn_port) + else: + port = 5000 + + options.setdefault("use_reloader", self.debug) + options.setdefault("use_debugger", self.debug) + options.setdefault("threaded", True) + + cli.show_server_banner(self.env, self.debug, self.name, False) + + from werkzeug.serving import run_simple + + try: + run_simple(t.cast(str, host), port, self, **options) + finally: + # reset the first request information if the development server + # reset normally. This makes it possible to restart the server + # without reloader and that stuff from an interactive shell. + self._got_first_request = False + + def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> "FlaskClient": + """Creates a test client for this application. For information + about unit testing head over to :doc:`/testing`. + + Note that if you are testing for assertions or exceptions in your + application code, you must set ``app.testing = True`` in order for the + exceptions to propagate to the test client. Otherwise, the exception + will be handled by the application (not visible to the test client) and + the only indication of an AssertionError or other exception will be a + 500 status code response to the test client. See the :attr:`testing` + attribute. For example:: + + app.testing = True + client = app.test_client() + + The test client can be used in a ``with`` block to defer the closing down + of the context until the end of the ``with`` block. This is useful if + you want to access the context locals for testing:: + + with app.test_client() as c: + rv = c.get('/?vodka=42') + assert request.args['vodka'] == '42' + + Additionally, you may pass optional keyword arguments that will then + be passed to the application's :attr:`test_client_class` constructor. + For example:: + + from flask.testing import FlaskClient + + class CustomClient(FlaskClient): + def __init__(self, *args, **kwargs): + self._authentication = kwargs.pop("authentication") + super(CustomClient,self).__init__( *args, **kwargs) + + app.test_client_class = CustomClient + client = app.test_client(authentication='Basic ....') + + See :class:`~flask.testing.FlaskClient` for more information. + + .. versionchanged:: 0.4 + added support for ``with`` block usage for the client. + + .. versionadded:: 0.7 + The `use_cookies` parameter was added as well as the ability + to override the client to be used by setting the + :attr:`test_client_class` attribute. + + .. versionchanged:: 0.11 + Added `**kwargs` to support passing additional keyword arguments to + the constructor of :attr:`test_client_class`. + """ + cls = self.test_client_class + if cls is None: + from .testing import FlaskClient as cls # type: ignore + return cls( # type: ignore + self, self.response_class, use_cookies=use_cookies, **kwargs + ) + + def test_cli_runner(self, **kwargs: t.Any) -> "FlaskCliRunner": + """Create a CLI runner for testing CLI commands. + See :ref:`testing-cli`. + + Returns an instance of :attr:`test_cli_runner_class`, by default + :class:`~flask.testing.FlaskCliRunner`. The Flask app object is + passed as the first argument. + + .. versionadded:: 1.0 + """ + cls = self.test_cli_runner_class + + if cls is None: + from .testing import FlaskCliRunner as cls # type: ignore + + return cls(self, **kwargs) # type: ignore + + @setupmethod + def register_blueprint(self, blueprint: "Blueprint", **options: t.Any) -> None: + """Register a :class:`~flask.Blueprint` on the application. Keyword + arguments passed to this method will override the defaults set on the + blueprint. + + Calls the blueprint's :meth:`~flask.Blueprint.register` method after + recording the blueprint in the application's :attr:`blueprints`. + + :param blueprint: The blueprint to register. + :param url_prefix: Blueprint routes will be prefixed with this. + :param subdomain: Blueprint routes will match on this subdomain. + :param url_defaults: Blueprint routes will use these default values for + view arguments. + :param options: Additional keyword arguments are passed to + :class:`~flask.blueprints.BlueprintSetupState`. They can be + accessed in :meth:`~flask.Blueprint.record` callbacks. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + + .. versionadded:: 0.7 + """ + blueprint.register(self, options) + + def iter_blueprints(self) -> t.ValuesView["Blueprint"]: + """Iterates over all blueprints by the order they were registered. + + .. versionadded:: 0.11 + """ + return self.blueprints.values() + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: t.Optional[str] = None, + view_func: t.Optional[t.Callable] = None, + provide_automatic_options: t.Optional[bool] = None, + **options: t.Any, + ) -> None: + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) # type: ignore + options["endpoint"] = endpoint + methods = options.pop("methods", None) + + # if the methods are not given and the view_func object knows its + # methods we can use that instead. If neither exists, we go with + # a tuple of only ``GET`` as default. + if methods is None: + methods = getattr(view_func, "methods", None) or ("GET",) + if isinstance(methods, str): + raise TypeError( + "Allowed methods must be a list of strings, for" + ' example: @app.route(..., methods=["POST"])' + ) + methods = {item.upper() for item in methods} + + # Methods that should always be added + required_methods = set(getattr(view_func, "required_methods", ())) + + # starting with Flask 0.8 the view_func object can disable and + # force-enable the automatic options handling. + if provide_automatic_options is None: + provide_automatic_options = getattr( + view_func, "provide_automatic_options", None + ) + + if provide_automatic_options is None: + if "OPTIONS" not in methods: + provide_automatic_options = True + required_methods.add("OPTIONS") + else: + provide_automatic_options = False + + # Add the required methods now. + methods |= required_methods + + rule = self.url_rule_class(rule, methods=methods, **options) + rule.provide_automatic_options = provide_automatic_options # type: ignore + + self.url_map.add(rule) + if view_func is not None: + old_func = self.view_functions.get(endpoint) + if old_func is not None and old_func != view_func: + raise AssertionError( + "View function mapping is overwriting an existing" + f" endpoint function: {endpoint}" + ) + self.view_functions[endpoint] = view_func + + @setupmethod + def template_filter( + self, name: t.Optional[str] = None + ) -> t.Callable[[TemplateFilterCallable], TemplateFilterCallable]: + """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: TemplateFilterCallable) -> TemplateFilterCallable: + self.add_template_filter(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_filter( + self, f: TemplateFilterCallable, name: t.Optional[str] = None + ) -> None: + """Register a custom template filter. Works exactly like the + :meth:`template_filter` decorator. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + self.jinja_env.filters[name or f.__name__] = f + + @setupmethod + def template_test( + self, name: t.Optional[str] = None + ) -> t.Callable[[TemplateTestCallable], TemplateTestCallable]: + """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: TemplateTestCallable) -> TemplateTestCallable: + self.add_template_test(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_test( + self, f: TemplateTestCallable, name: t.Optional[str] = None + ) -> None: + """Register a custom template test. Works exactly like the + :meth:`template_test` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + self.jinja_env.tests[name or f.__name__] = f + + @setupmethod + def template_global( + self, name: t.Optional[str] = None + ) -> t.Callable[[TemplateGlobalCallable], TemplateGlobalCallable]: + """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: TemplateGlobalCallable) -> TemplateGlobalCallable: + self.add_template_global(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_global( + self, f: TemplateGlobalCallable, name: t.Optional[str] = None + ) -> None: + """Register a custom template global function. Works exactly like the + :meth:`template_global` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + self.jinja_env.globals[name or f.__name__] = f + + @setupmethod + def before_first_request(self, f: BeforeRequestCallable) -> BeforeRequestCallable: + """Registers a function to be run before the first request to this + instance of the application. + + The function will be called without any arguments and its return + value is ignored. + + .. versionadded:: 0.8 + """ + self.before_first_request_funcs.append(f) + return f + + @setupmethod + def teardown_appcontext(self, f: TeardownCallable) -> TeardownCallable: + """Registers a function to be called when the application context + ends. These functions are typically also called when the request + context is popped. + + Example:: + + ctx = app.app_context() + ctx.push() + ... + ctx.pop() + + When ``ctx.pop()`` is executed in the above example, the teardown + functions are called just before the app context moves from the + stack of active contexts. This becomes relevant if you are using + such constructs in tests. + + 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. + + 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.Callable) -> t.Callable: + """Registers a shell context processor function. + + .. versionadded:: 0.11 + """ + self.shell_context_processors.append(f) + return f + + def _find_error_handler(self, e: Exception) -> t.Optional[ErrorHandlerCallable]: + """Return a registered error handler for an exception in this order: + blueprint handler for a specific code, app handler for a specific code, + blueprint handler for an exception class, app handler for an exception + class, or ``None`` if a suitable handler is not found. + """ + exc_class, code = self._get_exc_class_and_code(type(e)) + + for c in [code, None]: + for name in chain(request.blueprints, [None]): + handler_map = self.error_handler_spec[name][c] + + if not handler_map: + continue + + for cls in exc_class.__mro__: + handler = handler_map.get(cls) + + if handler is not None: + return handler + return None + + def handle_http_exception( + self, e: HTTPException + ) -> t.Union[HTTPException, 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 + ``HTTPExcpetion`` subclasses can be handled with a catch-all + handler for the base ``HTTPException``. + + .. versionadded:: 0.3 + """ + # Proxy exceptions don't have error codes. We want to always return + # those unchanged as errors + if e.code is None: + return e + + # RoutingExceptions are used internally to trigger routing + # actions, such as slash redirects raising RequestRedirect. They + # are not raised or handled in user code. + if isinstance(e, RoutingException): + return e + + handler = self._find_error_handler(e) + if handler is None: + return e + return self.ensure_sync(handler)(e) + + def trap_http_exception(self, e: Exception) -> bool: + """Checks if an HTTP exception should be trapped or not. By default + this will return ``False`` for all exceptions except for a bad request + key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``. It + also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``. + + This is called for all HTTP exceptions raised by a view function. + If it returns ``True`` for any exception the error handler for this + exception is not called and it shows up as regular exception in the + traceback. This is helpful for debugging implicitly raised HTTP + exceptions. + + .. versionchanged:: 1.0 + Bad request errors are not trapped by default in debug mode. + + .. versionadded:: 0.8 + """ + if self.config["TRAP_HTTP_EXCEPTIONS"]: + return True + + trap_bad_request = self.config["TRAP_BAD_REQUEST_ERRORS"] + + # if unset, trap key errors in debug mode + if ( + trap_bad_request is None + and self.debug + and isinstance(e, BadRequestKeyError) + ): + return True + + if trap_bad_request: + return isinstance(e, BadRequest) + + return False + + def handle_user_exception( + self, e: Exception + ) -> t.Union[HTTPException, ResponseReturnValue]: + """This method is called whenever an exception occurs that + should be handled. A special case is :class:`~werkzeug + .exceptions.HTTPException` which is forwarded to the + :meth:`handle_http_exception` method. This function will either + return a response value or reraise the exception with the same + traceback. + + .. versionchanged:: 1.0 + Key errors raised from request data like ``form`` show the + bad key in debug mode rather than a generic bad request + message. + + .. versionadded:: 0.7 + """ + if isinstance(e, BadRequestKeyError) and ( + self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"] + ): + e.show_exception = True + + if isinstance(e, HTTPException) and not self.trap_http_exception(e): + return self.handle_http_exception(e) + + handler = self._find_error_handler(e) + + if handler is None: + raise + + return self.ensure_sync(handler)(e) + + def handle_exception(self, e: Exception) -> Response: + """Handle an exception that did not have an error handler + associated with it, or that was raised from an error handler. + This always causes a 500 ``InternalServerError``. + + Always sends the :data:`got_request_exception` signal. + + If :attr:`propagate_exceptions` is ``True``, such as in debug + mode, the error will be re-raised so that the debugger can + display it. Otherwise, the original exception is logged, and + an :exc:`~werkzeug.exceptions.InternalServerError` is returned. + + If an error handler is registered for ``InternalServerError`` or + ``500``, it will be used. For consistency, the handler will + always receive the ``InternalServerError``. The original + unhandled exception is available as ``e.original_exception``. + + .. versionchanged:: 1.1.0 + Always passes the ``InternalServerError`` instance to the + handler, setting ``original_exception`` to the unhandled + error. + + .. versionchanged:: 1.1.0 + ``after_request`` functions and other finalization is done + even for the default 500 response when there is no handler. + + .. versionadded:: 0.3 + """ + exc_info = sys.exc_info() + got_request_exception.send(self, exception=e) + + if self.propagate_exceptions: + # Re-raise if called with an active exception, otherwise + # raise the passed in exception. + if exc_info[1] is e: + raise + + raise e + + self.log_exception(exc_info) + server_error: t.Union[InternalServerError, ResponseReturnValue] + server_error = InternalServerError(original_exception=e) + handler = self._find_error_handler(server_error) + + if handler is not None: + server_error = self.ensure_sync(handler)(server_error) + + return self.finalize_request(server_error, from_error_handler=True) + + def log_exception( + self, + exc_info: t.Union[ + t.Tuple[type, BaseException, TracebackType], t.Tuple[None, None, None] + ], + ) -> None: + """Logs an exception. This is called by :meth:`handle_exception` + if debugging is disabled and right before the handler is called. + The default implementation logs the exception as error on the + :attr:`logger`. + + .. versionadded:: 0.8 + """ + self.logger.error( + f"Exception on {request.path} [{request.method}]", exc_info=exc_info + ) + + def raise_routing_exception(self, request: Request) -> "te.NoReturn": + """Exceptions that are recording during routing are reraised with + this method. During debug we are not reraising redirect requests + for non ``GET``, ``HEAD``, or ``OPTIONS`` requests and we're raising + a different error instead to help debug situations. + + :internal: + """ + if ( + not self.debug + or not isinstance(request.routing_exception, RequestRedirect) + or request.method in ("GET", "HEAD", "OPTIONS") + ): + raise request.routing_exception # type: ignore + + from .debughelpers import FormDataRoutingRedirect + + raise FormDataRoutingRedirect(request) + + def dispatch_request(self) -> 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_stack.top.request + if req.routing_exception is not None: + self.raise_routing_exception(req) + rule = req.url_rule + # 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 + return self.ensure_sync(self.view_functions[rule.endpoint])(**req.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.try_trigger_before_first_request_functions() + try: + request_started.send(self) + rv = self.preprocess_request() + if rv is None: + rv = self.dispatch_request() + except Exception as e: + rv = self.handle_user_exception(e) + return self.finalize_request(rv) + + def finalize_request( + self, + rv: t.Union[ResponseReturnValue, HTTPException], + from_error_handler: bool = False, + ) -> Response: + """Given the return value from a view function this finalizes + the request by converting it into a response and invoking the + postprocessing functions. This is invoked for both normal + request dispatching as well as error handlers. + + Because this means that it might be called as a result of a + failure a special safe mode is available which can be enabled + with the `from_error_handler` flag. If enabled, failures in + response processing will be logged and otherwise ignored. + + :internal: + """ + response = self.make_response(rv) + try: + response = self.process_response(response) + request_finished.send(self, response=response) + except Exception: + if not from_error_handler: + raise + self.logger.exception( + "Request finalizing failed with an error while handling an error" + ) + return response + + def try_trigger_before_first_request_functions(self) -> None: + """Called before each request and will ensure that it triggers + the :attr:`before_first_request_funcs` and only exactly once per + application instance (which means process usually). + + :internal: + """ + if self._got_first_request: + return + with self._before_request_lock: + if self._got_first_request: + return + for func in self.before_first_request_funcs: + self.ensure_sync(func)() + self._got_first_request = True + + 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_stack.top.url_adapter + methods = adapter.allowed_methods() + rv = self.response_class() + rv.allow.update(methods) + return rv + + def should_ignore_error(self, error: t.Optional[BaseException]) -> bool: + """This is called to figure out if an error should be ignored + or not as far as the teardown system is concerned. If this + function returns ``True`` then the teardown handlers will not be + passed the error. + + .. versionadded:: 0.10 + """ + return False + + def ensure_sync(self, func: t.Callable) -> t.Callable: + """Ensure that the function is synchronous for WSGI workers. + Plain ``def`` functions are returned as-is. ``async def`` + functions are wrapped to run and wait for the response. + + Override this method to change how the app runs async views. + + .. versionadded:: 2.0 + """ + if iscoroutinefunction(func): + return self.async_to_sync(func) + + return func + + def async_to_sync( + self, func: t.Callable[..., t.Coroutine] + ) -> t.Callable[..., t.Any]: + """Return a sync function that will run the coroutine function. + + .. code-block:: python + + result = app.async_to_sync(func)(*args, **kwargs) + + Override this method to change how the app converts async code + to be synchronously callable. + + .. versionadded:: 2.0 + """ + try: + from asgiref.sync import async_to_sync as asgiref_async_to_sync + except ImportError: + raise RuntimeError( + "Install Flask with the 'async' extra in order to use async views." + ) + + # Check that Werkzeug isn't using its fallback ContextVar class. + if ContextVar.__module__ == "werkzeug.local": + raise RuntimeError( + "Async cannot be used with this combination of Python " + "and Greenlet versions." + ) + + return asgiref_async_to_sync(func) + + def make_response(self, rv: 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. + + ``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:: 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 + # 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 + # 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)): + # 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) + status = headers = None + elif isinstance(rv, dict): + rv = jsonify(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 # noqa: B950 + 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, tuple, Response instance, or WSGI" + f" callable, but it was a {type(rv).__name__}." + ).with_traceback(sys.exc_info()[2]) + else: + raise TypeError( + "The view function did not return a valid" + " response. The return type must be a string," + " dict, tuple, Response instance, or WSGI" + f" callable, but it was a {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 # type: ignore + else: + rv.status_code = status + + # extend existing headers with provided headers + if headers: + rv.headers.update(headers) + + return rv + + def create_url_adapter( + self, request: t.Optional[Request] + ) -> t.Optional[MapAdapter]: + """Creates a URL adapter for the given request. The URL adapter + is created at a point where the request context is not yet set + up so the request is passed explicitly. + + .. versionadded:: 0.6 + + .. versionchanged:: 0.9 + This can now also be called without a request object when the + URL adapter is created for the application context. + + .. versionchanged:: 1.0 + :data:`SERVER_NAME` no longer implicitly enables subdomain + matching. Use :attr:`subdomain_matching` instead. + """ + if request is not None: + # If subdomain matching is disabled (the default), use the + # default subdomain in all cases. This should be the default + # in Werkzeug but it currently does not have that feature. + if not self.subdomain_matching: + subdomain = self.url_map.default_subdomain or None + else: + subdomain = None + + return self.url_map.bind_to_environ( + request.environ, + server_name=self.config["SERVER_NAME"], + subdomain=subdomain, + ) + # We need at the very least the server name to be set for this + # to work. + if self.config["SERVER_NAME"] is not None: + return self.url_map.bind( + self.config["SERVER_NAME"], + script_name=self.config["APPLICATION_ROOT"], + url_scheme=self.config["PREFERRED_URL_SCHEME"], + ) + + return None + + def inject_url_defaults(self, endpoint: str, values: dict) -> None: + """Injects the URL defaults for the given endpoint directly into + the values dictionary passed. This is used internally and + automatically called on URL building. + + .. versionadded:: 0.7 + """ + funcs: t.Iterable[URLDefaultCallable] = self.url_default_functions[None] + + if "." in endpoint: + # This is called by url_for, which can be called outside a + # request, can't use request.blueprints. + bps = _split_blueprint_path(endpoint.rpartition(".")[0]) + bp_funcs = chain.from_iterable(self.url_default_functions[bp] for bp in bps) + funcs = chain(funcs, bp_funcs) + + for func in funcs: + func(endpoint, values) + + def handle_url_build_error( + self, error: Exception, endpoint: str, values: dict + ) -> str: + """Handle :class:`~werkzeug.routing.BuildError` on + :meth:`url_for`. + """ + for handler in self.url_build_error_handlers: + try: + rv = handler(error, endpoint, values) + except BuildError as e: + # make error available outside except block + error = e + else: + if rv is not None: + return rv + + # Re-raise if called with an active exception, otherwise raise + # the passed in exception. + if error is sys.exc_info()[1]: + raise + + raise error + + def preprocess_request(self) -> t.Optional[ResponseReturnValue]: + """Called before the request is dispatched. Calls + :attr:`url_value_preprocessors` registered with the app and the + current blueprint (if any). Then calls :attr:`before_request_funcs` + registered with the app and the blueprint. + + If any :meth:`before_request` handler returns a non-None value, the + value is handled as if it was the return value from the view, and + further request handling is stopped. + """ + + funcs: t.Iterable[URLValuePreprocessorCallable] = self.url_value_preprocessors[ + None + ] + for bp in request.blueprints: + if bp in self.url_value_preprocessors: + funcs = chain(funcs, self.url_value_preprocessors[bp]) + for func in funcs: + func(request.endpoint, request.view_args) + + funcs: t.Iterable[BeforeRequestCallable] = self.before_request_funcs[None] + for bp in request.blueprints: + if bp in self.before_request_funcs: + funcs = chain(funcs, self.before_request_funcs[bp]) + for func in funcs: + rv = self.ensure_sync(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_stack.top + funcs: t.Iterable[AfterRequestCallable] = ctx._after_request_functions + for bp in request.blueprints: + if bp in self.after_request_funcs: + funcs = chain(funcs, reversed(self.after_request_funcs[bp])) + if None in self.after_request_funcs: + funcs = chain(funcs, reversed(self.after_request_funcs[None])) + for handler in funcs: + response = self.ensure_sync(handler)(response) + if not self.session_interface.is_null_session(ctx.session): + self.session_interface.save_session(self, ctx.session, response) + return response + + def do_teardown_request( + self, exc: t.Optional[BaseException] = _sentinel # type: ignore + ) -> None: + """Called after the request is dispatched and the response is + returned, right before the request context is popped. + + This calls all functions decorated with + :meth:`teardown_request`, and :meth:`Blueprint.teardown_request` + if a blueprint handled the request. Finally, the + :data:`request_tearing_down` signal is sent. + + This is called by + :meth:`RequestContext.pop() `, + which may be delayed during testing to maintain access to + resources. + + :param exc: An unhandled exception raised while dispatching the + request. Detected from the current exception information if + not passed. Passed to each teardown function. + + .. versionchanged:: 0.9 + Added the ``exc`` argument. + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + funcs: t.Iterable[TeardownCallable] = reversed( + self.teardown_request_funcs[None] + ) + for bp in request.blueprints: + if bp in self.teardown_request_funcs: + funcs = chain(funcs, reversed(self.teardown_request_funcs[bp])) + for func in funcs: + self.ensure_sync(func)(exc) + request_tearing_down.send(self, exc=exc) + + def do_teardown_appcontext( + self, exc: t.Optional[BaseException] = _sentinel # type: ignore + ) -> None: + """Called right before the application context is popped. + + When handling a request, the application context is popped + after the request context. See :meth:`do_teardown_request`. + + This calls all functions decorated with + :meth:`teardown_appcontext`. Then the + :data:`appcontext_tearing_down` signal is sent. + + This is called by + :meth:`AppContext.pop() `. + + .. versionadded:: 0.9 + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + for func in reversed(self.teardown_appcontext_funcs): + self.ensure_sync(func)(exc) + appcontext_tearing_down.send(self, exc=exc) + + def app_context(self) -> AppContext: + """Create an :class:`~flask.ctx.AppContext`. Use as a ``with`` + block to push the context, which will make :data:`current_app` + point at this application. + + An application context is automatically pushed by + :meth:`RequestContext.push() ` + when handling a request, and when running a CLI command. Use + this to manually create a context outside of these situations. + + :: + + with app.app_context(): + init_db() + + See :doc:`/appcontext`. + + .. versionadded:: 0.9 + """ + return AppContext(self) + + def request_context(self, environ: dict) -> RequestContext: + """Create a :class:`~flask.ctx.RequestContext` representing a + WSGI environment. Use a ``with`` block to push the context, + which will make :data:`request` point at this request. + + See :doc:`/reqcontext`. + + Typically you should not call this from your own code. A request + context is automatically pushed by the :meth:`wsgi_app` when + handling a request. Use :meth:`test_request_context` to create + an environment and context instead of this method. + + :param environ: a WSGI environment + """ + return RequestContext(self, environ) + + def test_request_context(self, *args: t.Any, **kwargs: t.Any) -> RequestContext: + """Create a :class:`~flask.ctx.RequestContext` for a WSGI + environment created from the given values. This is mostly useful + during testing, where you may want to run a function that uses + request data without dispatching a full request. + + See :doc:`/reqcontext`. + + Use a ``with`` block to push the context, which will make + :data:`request` point at the request for the created + environment. :: + + with test_request_context(...): + generate_report() + + When using the shell, it may be easier to push and pop the + context manually to avoid indentation. :: + + ctx = app.test_request_context(...) + ctx.push() + ... + ctx.pop() + + Takes the same arguments as Werkzeug's + :class:`~werkzeug.test.EnvironBuilder`, with some defaults from + the application. See the linked Werkzeug docs for most of the + available arguments. Flask-specific behavior is listed here. + + :param path: URL path being requested. + :param base_url: Base URL where the app is being served, which + ``path`` is relative to. If not given, built from + :data:`PREFERRED_URL_SCHEME`, ``subdomain``, + :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. + :param subdomain: Subdomain name to append to + :data:`SERVER_NAME`. + :param url_scheme: Scheme to use instead of + :data:`PREFERRED_URL_SCHEME`. + :param data: The request body, either as a string or a dict of + form keys and values. + :param json: If given, this is serialized as JSON and passed as + ``data``. Also defaults ``content_type`` to + ``application/json``. + :param args: other positional arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + :param kwargs: other keyword arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + """ + from .testing import EnvironBuilder + + builder = EnvironBuilder(self, *args, **kwargs) + + try: + return self.request_context(builder.get_environ()) + finally: + builder.close() + + def wsgi_app(self, environ: dict, start_response: t.Callable) -> t.Any: + """The actual WSGI application. This is not implemented in + :meth:`__call__` so that middlewares can be applied without + losing a reference to the app object. Instead of doing this:: + + app = MyMiddleware(app) + + It's a better idea to do this instead:: + + app.wsgi_app = MyMiddleware(app.wsgi_app) + + Then you still have the original application object around and + can continue to call methods on it. + + .. versionchanged:: 0.7 + Teardown events for the request and app contexts are called + even if an unhandled error occurs. Other events may not be + called depending on when an error occurs during dispatch. + See :ref:`callbacks-and-errors`. + + :param environ: A WSGI environment. + :param start_response: A callable accepting a status code, + a list of headers, and an optional exception context to + start the response. + """ + ctx = self.request_context(environ) + error: t.Optional[BaseException] = None + try: + try: + ctx.push() + response = self.full_dispatch_request() + except Exception as e: + error = e + response = self.handle_exception(e) + except: # noqa: B001 + error = sys.exc_info()[1] + raise + return response(environ, start_response) + finally: + if self.should_ignore_error(error): + error = None + ctx.auto_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/venv/lib/python3.9/site-packages/flask/blueprints.py b/venv/lib/python3.9/site-packages/flask/blueprints.py new file mode 100644 index 0000000..f3913b3 --- /dev/null +++ b/venv/lib/python3.9/site-packages/flask/blueprints.py @@ -0,0 +1,603 @@ +import typing as t +from collections import defaultdict +from functools import update_wrapper + +from .scaffold import _endpoint_from_view_func +from .scaffold import _sentinel +from .scaffold import Scaffold +from .typing import AfterRequestCallable +from .typing import BeforeRequestCallable +from .typing import ErrorHandlerCallable +from .typing import TeardownCallable +from .typing import TemplateContextProcessorCallable +from .typing import TemplateFilterCallable +from .typing import TemplateGlobalCallable +from .typing import TemplateTestCallable +from .typing import URLDefaultCallable +from .typing import URLValuePreprocessorCallable + +if t.TYPE_CHECKING: + from .app import Flask + +DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable] + + +class BlueprintSetupState: + """Temporary holder object for registering a blueprint with the + application. An instance of this class is created by the + :meth:`~flask.Blueprint.make_setup_state` method and later passed + to all register callback functions. + """ + + def __init__( + self, + blueprint: "Blueprint", + app: "Flask", + options: t.Any, + first_registration: bool, + ) -> None: + #: a reference to the current application + self.app = app + + #: a reference to the blueprint that created this setup state. + self.blueprint = blueprint + + #: a dictionary with all options that were passed to the + #: :meth:`~flask.Flask.register_blueprint` method. + self.options = options + + #: as blueprints can be registered multiple times with the + #: application and not everything wants to be registered + #: multiple times on it, this attribute can be used to figure + #: out if the blueprint was registered in the past already. + self.first_registration = first_registration + + subdomain = self.options.get("subdomain") + if subdomain is None: + subdomain = self.blueprint.subdomain + + #: The subdomain that the blueprint should be active for, ``None`` + #: otherwise. + self.subdomain = subdomain + + url_prefix = self.options.get("url_prefix") + if url_prefix is None: + url_prefix = self.blueprint.url_prefix + #: The prefix that should be used for all URLs defined on the + #: blueprint. + self.url_prefix = url_prefix + + self.name = self.options.get("name", blueprint.name) + self.name_prefix = self.options.get("name_prefix", "") + + #: A dictionary with URL defaults that is added to each and every + #: URL that was defined with the blueprint. + self.url_defaults = dict(self.blueprint.url_values_defaults) + self.url_defaults.update(self.options.get("url_defaults", ())) + + def add_url_rule( + self, + rule: str, + endpoint: t.Optional[str] = None, + view_func: t.Optional[t.Callable] = None, + **options: t.Any, + ) -> None: + """A helper method to register a rule (and optionally a view function) + to the application. The endpoint is automatically prefixed with the + blueprint's name. + """ + if self.url_prefix is not None: + if rule: + rule = "/".join((self.url_prefix.rstrip("/"), rule.lstrip("/"))) + else: + rule = self.url_prefix + options.setdefault("subdomain", self.subdomain) + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) # type: ignore + defaults = self.url_defaults + if "defaults" in options: + defaults = dict(defaults, **options.pop("defaults")) + + self.app.add_url_rule( + rule, + f"{self.name_prefix}.{self.name}.{endpoint}".lstrip("."), + view_func, + defaults=defaults, + **options, + ) + + +class Blueprint(Scaffold): + """Represents a blueprint, a collection of routes and other + app-related functions that can be registered on a real application + later. + + A blueprint is an object that allows defining application functions + without requiring an application object ahead of time. It uses the + same decorators as :class:`~flask.Flask`, but defers the need for an + application by recording them for later registration. + + Decorating a function with a blueprint creates a deferred function + that is called with :class:`~flask.blueprints.BlueprintSetupState` + when the blueprint is registered on an application. + + See :doc:`/blueprints` for more information. + + :param name: The name of the blueprint. Will be prepended to each + endpoint name. + :param import_name: The name of the blueprint package, usually + ``__name__``. This helps locate the ``root_path`` for the + blueprint. + :param static_folder: A folder with static files that should be + served by the blueprint's static route. The path is relative to + the blueprint's root path. Blueprint static files are disabled + by default. + :param static_url_path: The url to serve static files from. + Defaults to ``static_folder``. If the blueprint does not have + a ``url_prefix``, the app's static route will take precedence, + and the blueprint's static files won't be accessible. + :param template_folder: A folder with templates that should be added + to the app's template search path. The path is relative to the + blueprint's root path. Blueprint templates are disabled by + default. Blueprint templates have a lower precedence than those + in the app's templates folder. + :param url_prefix: A path to prepend to all of the blueprint's URLs, + to make them distinct from the rest of the app's routes. + :param subdomain: A subdomain that blueprint routes will match on by + default. + :param url_defaults: A dict of default values that blueprint routes + will receive by default. + :param root_path: By default, the blueprint will automatically set + this based on ``import_name``. In certain situations this + automatic detection can fail, so the path can be specified + manually instead. + + .. versionchanged:: 1.1.0 + Blueprints have a ``cli`` group to register nested CLI commands. + The ``cli_group`` parameter controls the name of the group under + the ``flask`` command. + + .. versionadded:: 0.7 + """ + + warn_on_modifications = False + _got_registered_once = False + + #: Blueprint local JSON encoder class to use. Set to ``None`` to use + #: the app's :class:`~flask.Flask.json_encoder`. + json_encoder = None + #: Blueprint local JSON decoder class to use. Set to ``None`` to use + #: the app's :class:`~flask.Flask.json_decoder`. + json_decoder = None + + def __init__( + self, + name: str, + import_name: str, + static_folder: t.Optional[str] = None, + static_url_path: t.Optional[str] = None, + template_folder: t.Optional[str] = None, + url_prefix: t.Optional[str] = None, + subdomain: t.Optional[str] = None, + url_defaults: t.Optional[dict] = None, + root_path: t.Optional[str] = None, + cli_group: t.Optional[str] = _sentinel, # type: ignore + ): + super().__init__( + import_name=import_name, + static_folder=static_folder, + static_url_path=static_url_path, + template_folder=template_folder, + root_path=root_path, + ) + + if "." in name: + raise ValueError("'name' may not contain a dot '.' character.") + + self.name = name + self.url_prefix = url_prefix + self.subdomain = subdomain + self.deferred_functions: t.List[DeferredSetupFunction] = [] + + if url_defaults is None: + url_defaults = {} + + self.url_values_defaults = url_defaults + self.cli_group = cli_group + self._blueprints: t.List[t.Tuple["Blueprint", dict]] = [] + + def _is_setup_finished(self) -> bool: + return self.warn_on_modifications and self._got_registered_once + + 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. + """ + if self._got_registered_once and self.warn_on_modifications: + from warnings import warn + + warn( + Warning( + "The blueprint was already registered once but is" + " getting modified now. These changes will not show" + " up." + ) + ) + self.deferred_functions.append(func) + + 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) + + return self.record(update_wrapper(wrapper, func)) + + def make_setup_state( + self, app: "Flask", options: dict, first_registration: bool = False + ) -> BlueprintSetupState: + """Creates an instance of :meth:`~flask.blueprints.BlueprintSetupState` + object that is later passed to the register callback functions. + Subclasses can override this to return a subclass of the setup state. + """ + return BlueprintSetupState(self, app, options, first_registration) + + def register_blueprint(self, blueprint: "Blueprint", **options: t.Any) -> None: + """Register a :class:`~flask.Blueprint` on this blueprint. Keyword + arguments passed to this method will override the defaults set + on the blueprint. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + + .. versionadded:: 2.0 + """ + if blueprint is self: + raise ValueError("Cannot register a blueprint on itself") + self._blueprints.append((blueprint, options)) + + def register(self, app: "Flask", options: dict) -> None: + """Called by :meth:`Flask.register_blueprint` to register all + views and callbacks registered on the blueprint with the + application. Creates a :class:`.BlueprintSetupState` and calls + each :meth:`record` callback with it. + + :param app: The application this blueprint is being registered + with. + :param options: Keyword arguments forwarded from + :meth:`~Flask.register_blueprint`. + + .. versionchanged:: 2.0.1 + Nested blueprints are registered with their dotted name. + This allows different blueprints with the same name to be + nested at different locations. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + + .. versionchanged:: 2.0.1 + Registering the same blueprint with the same name multiple + times is deprecated and will become an error in Flask 2.1. + """ + first_registration = not any(bp is self for bp in app.blueprints.values()) + 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: + existing_at = f" '{name}'" if self_name != name else "" + + if app.blueprints[name] is not self: + raise ValueError( + f"The name '{self_name}' is already registered for" + f" a different blueprint{existing_at}. Use 'name='" + " to provide a unique name." + ) + else: + import warnings + + warnings.warn( + f"The name '{self_name}' is already registered for" + f" this blueprint{existing_at}. Use 'name=' to" + " provide a unique name. This will become an error" + " in Flask 2.1.", + stacklevel=4, + ) + + app.blueprints[name] = self + self._got_registered_once = True + state = self.make_setup_state(app, options, first_registration) + + if self.has_static_folder: + state.add_url_rule( + f"{self.static_url_path}/", + view_func=self.send_static_file, + endpoint="static", + ) + + # Merge blueprint data into parent. + if first_registration: + + def extend(bp_dict, parent_dict): + for key, values in bp_dict.items(): + key = name if key is None else f"{name}.{key}" + parent_dict[key].extend(values) + + for key, value in self.error_handler_spec.items(): + key = name if key is None else f"{name}.{key}" + value = defaultdict( + dict, + { + code: { + exc_class: func for exc_class, func in code_values.items() + } + for code, code_values in value.items() + }, + ) + app.error_handler_spec[key] = value + + for endpoint, func in self.view_functions.items(): + app.view_functions[endpoint] = func + + extend(self.before_request_funcs, app.before_request_funcs) + extend(self.after_request_funcs, app.after_request_funcs) + extend( + self.teardown_request_funcs, + app.teardown_request_funcs, + ) + extend(self.url_default_functions, app.url_default_functions) + extend(self.url_value_preprocessors, app.url_value_preprocessors) + extend(self.template_context_processors, app.template_context_processors) + + for deferred in self.deferred_functions: + deferred(state) + + cli_resolved_group = options.get("cli_group", self.cli_group) + + if self.cli.commands: + if cli_resolved_group is None: + app.cli.commands.update(self.cli.commands) + elif cli_resolved_group is _sentinel: + self.cli.name = name + app.cli.add_command(self.cli) + else: + self.cli.name = cli_resolved_group + app.cli.add_command(self.cli) + + for blueprint, bp_options in self._blueprints: + bp_options = bp_options.copy() + bp_url_prefix = bp_options.get("url_prefix") + + if bp_url_prefix is None: + bp_url_prefix = blueprint.url_prefix + + if state.url_prefix is not None and bp_url_prefix is not None: + bp_options["url_prefix"] = ( + state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/") + ) + elif bp_url_prefix is not None: + bp_options["url_prefix"] = bp_url_prefix + elif state.url_prefix is not None: + bp_options["url_prefix"] = state.url_prefix + + bp_options["name_prefix"] = name + blueprint.register(app, bp_options) + + def add_url_rule( + self, + rule: str, + endpoint: t.Optional[str] = None, + view_func: t.Optional[t.Callable] = None, + provide_automatic_options: t.Optional[bool] = None, + **options: t.Any, + ) -> None: + """Like :meth:`Flask.add_url_rule` but for a blueprint. The endpoint for + the :func:`url_for` function is prefixed with the name of the blueprint. + """ + if endpoint and "." in endpoint: + raise ValueError("'endpoint' may not contain a dot '.' character.") + + if view_func and hasattr(view_func, "__name__") and "." in view_func.__name__: + raise ValueError("'view_func' name may not contain a dot '.' character.") + + self.record( + lambda s: s.add_url_rule( + rule, + endpoint, + view_func, + provide_automatic_options=provide_automatic_options, + **options, + ) + ) + + def app_template_filter( + self, name: t.Optional[str] = None + ) -> t.Callable[[TemplateFilterCallable], TemplateFilterCallable]: + """Register a custom template filter, available application wide. Like + :meth:`Flask.template_filter` but for a blueprint. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def decorator(f: TemplateFilterCallable) -> TemplateFilterCallable: + self.add_app_template_filter(f, name=name) + return f + + return decorator + + def add_app_template_filter( + self, f: TemplateFilterCallable, name: t.Optional[str] = None + ) -> None: + """Register a custom template filter, available application wide. Like + :meth:`Flask.add_template_filter` but for a blueprint. Works exactly + like the :meth:`app_template_filter` decorator. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.filters[name or f.__name__] = f + + self.record_once(register_template) + + def app_template_test( + self, name: t.Optional[str] = None + ) -> t.Callable[[TemplateTestCallable], TemplateTestCallable]: + """Register a custom template test, available application wide. Like + :meth:`Flask.template_test` but for a blueprint. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def decorator(f: TemplateTestCallable) -> TemplateTestCallable: + self.add_app_template_test(f, name=name) + return f + + return decorator + + def add_app_template_test( + self, f: TemplateTestCallable, name: t.Optional[str] = None + ) -> None: + """Register a custom template test, available application wide. Like + :meth:`Flask.add_template_test` but for a blueprint. Works exactly + like the :meth:`app_template_test` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.tests[name or f.__name__] = f + + self.record_once(register_template) + + def app_template_global( + self, name: t.Optional[str] = None + ) -> t.Callable[[TemplateGlobalCallable], TemplateGlobalCallable]: + """Register a custom template global, available application wide. Like + :meth:`Flask.template_global` but for a blueprint. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + + def decorator(f: TemplateGlobalCallable) -> TemplateGlobalCallable: + self.add_app_template_global(f, name=name) + return f + + return decorator + + def add_app_template_global( + self, f: TemplateGlobalCallable, name: t.Optional[str] = None + ) -> None: + """Register a custom template global, available application wide. Like + :meth:`Flask.add_template_global` but for a blueprint. Works exactly + like the :meth:`app_template_global` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.globals[name or f.__name__] = f + + self.record_once(register_template) + + def before_app_request(self, f: BeforeRequestCallable) -> BeforeRequestCallable: + """Like :meth:`Flask.before_request`. Such a function is executed + before each request, even if outside of a blueprint. + """ + self.record_once( + lambda s: s.app.before_request_funcs.setdefault(None, []).append(f) + ) + return f + + def before_app_first_request( + self, f: BeforeRequestCallable + ) -> BeforeRequestCallable: + """Like :meth:`Flask.before_first_request`. Such a function is + executed before the first request to the application. + """ + self.record_once(lambda s: s.app.before_first_request_funcs.append(f)) + return f + + def after_app_request(self, f: AfterRequestCallable) -> AfterRequestCallable: + """Like :meth:`Flask.after_request` but for a blueprint. Such a function + is executed after each request, even if outside of the blueprint. + """ + self.record_once( + lambda s: s.app.after_request_funcs.setdefault(None, []).append(f) + ) + return f + + def teardown_app_request(self, f: TeardownCallable) -> TeardownCallable: + """Like :meth:`Flask.teardown_request` but for a blueprint. Such a + function is executed when tearing down each request, even if outside of + the blueprint. + """ + self.record_once( + lambda s: s.app.teardown_request_funcs.setdefault(None, []).append(f) + ) + return f + + def app_context_processor( + self, f: TemplateContextProcessorCallable + ) -> TemplateContextProcessorCallable: + """Like :meth:`Flask.context_processor` but for a blueprint. Such a + function is executed each request, even if outside of the blueprint. + """ + self.record_once( + lambda s: s.app.template_context_processors.setdefault(None, []).append(f) + ) + return f + + def app_errorhandler(self, code: t.Union[t.Type[Exception], int]) -> t.Callable: + """Like :meth:`Flask.errorhandler` but for a blueprint. This + handler is used for all requests, even if outside of the blueprint. + """ + + def decorator(f: ErrorHandlerCallable) -> ErrorHandlerCallable: + self.record_once(lambda s: s.app.errorhandler(code)(f)) + return f + + return decorator + + def app_url_value_preprocessor( + self, f: URLValuePreprocessorCallable + ) -> URLValuePreprocessorCallable: + """Same as :meth:`url_value_preprocessor` but application wide.""" + self.record_once( + lambda s: s.app.url_value_preprocessors.setdefault(None, []).append(f) + ) + return f + + def app_url_defaults(self, f: URLDefaultCallable) -> URLDefaultCallable: + """Same as :meth:`url_defaults` but application wide.""" + self.record_once( + lambda s: s.app.url_default_functions.setdefault(None, []).append(f) + ) + return f diff --git a/venv/lib/python3.9/site-packages/flask/cli.py b/venv/lib/python3.9/site-packages/flask/cli.py new file mode 100644 index 0000000..d9e810d --- /dev/null +++ b/venv/lib/python3.9/site-packages/flask/cli.py @@ -0,0 +1,994 @@ +import ast +import inspect +import os +import platform +import re +import sys +import traceback +import warnings +from functools import update_wrapper +from operator import attrgetter +from threading import Lock +from threading import Thread + +import click +from werkzeug.utils import import_string + +from .globals import current_app +from .helpers import get_debug_flag +from .helpers import get_env +from .helpers import get_load_dotenv + +try: + import dotenv +except ImportError: + dotenv = None + +try: + import ssl +except ImportError: + ssl = None # type: ignore + + +class NoAppException(click.UsageError): + """Raised if an application cannot be found or loaded.""" + + +def find_best_app(script_info, 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__!r}. Use 'FLASK_APP={module.__name__}:name'" + f" 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 = call_factory(script_info, app_factory) + + if isinstance(app, Flask): + return app + except TypeError: + if not _called_with_wrong_args(app_factory): + raise + raise NoAppException( + f"Detected factory {attr_name!r} in module {module.__name__!r}," + " but could not call it without arguments. Use" + f" \"FLASK_APP='{module.__name__}:{attr_name}(args)'\"" + " to specify arguments." + ) + + raise NoAppException( + "Failed to find Flask application or factory in module" + f" {module.__name__!r}. Use 'FLASK_APP={module.__name__}:name'" + " to specify one." + ) + + +def call_factory(script_info, app_factory, args=None, kwargs=None): + """Takes an app factory, a ``script_info` object and optionally a tuple + of arguments. Checks for the existence of a script_info argument and calls + the app_factory depending on that and the arguments provided. + """ + sig = inspect.signature(app_factory) + args = [] if args is None else args + kwargs = {} if kwargs is None else kwargs + + if "script_info" in sig.parameters: + warnings.warn( + "The 'script_info' argument is deprecated and will not be" + " passed to the app factory function in Flask 2.1.", + DeprecationWarning, + ) + kwargs["script_info"] = script_info + + if ( + not args + and len(sig.parameters) == 1 + and next(iter(sig.parameters.values())).default is inspect.Parameter.empty + ): + warnings.warn( + "Script info is deprecated and will not be passed as the" + " single argument to the app factory function in Flask" + " 2.1.", + DeprecationWarning, + ) + args.append(script_info) + + return app_factory(*args, **kwargs) + + +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(script_info, 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." + ) + + if isinstance(expr, ast.Name): + name = expr.id + args = kwargs = None + 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}." + ) + else: + raise NoAppException( + f"Failed to parse {app_name!r} as an attribute name or function call." + ) + + try: + attr = getattr(module, name) + except AttributeError: + raise NoAppException( + f"Failed to find attribute {name!r} in {module.__name__!r}." + ) + + # If the attribute is a function, call it with any args and kwargs + # to get the real application. + if inspect.isfunction(attr): + try: + app = call_factory(script_info, attr, args, kwargs) + except TypeError: + 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." + ) + 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(script_info, module_name, app_name, raise_if_not_found=True): + __traceback_hide__ = True # noqa: F841 + + 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()}" + ) + elif raise_if_not_found: + raise NoAppException(f"Could not import {module_name!r}.") + else: + return + + module = sys.modules[module_name] + + if app_name is None: + return find_best_app(script_info, module) + else: + return find_app_by_string(script_info, module, app_name) + + +def get_version(ctx, param, value): + if not value or ctx.resilient_parsing: + return + + import werkzeug + from . import __version__ + + click.echo( + f"Python {platform.python_version()}\n" + f"Flask {__version__}\n" + f"Werkzeug {werkzeug.__version__}", + color=ctx.color, + ) + ctx.exit() + + +version_option = click.Option( + ["--version"], + help="Show the flask version", + expose_value=False, + callback=get_version, + is_flag=True, + is_eager=True, +) + + +class DispatchingApp: + """Special application that dispatches to a Flask application which + is imported by name in a background thread. If an error happens + it is recorded and shown as part of the WSGI handling which in case + of the Werkzeug debugger means that it shows up in the browser. + """ + + def __init__(self, loader, use_eager_loading=None): + self.loader = loader + self._app = None + self._lock = Lock() + self._bg_loading_exc_info = None + + if use_eager_loading is None: + use_eager_loading = os.environ.get("WERKZEUG_RUN_MAIN") != "true" + + if use_eager_loading: + self._load_unlocked() + else: + self._load_in_background() + + def _load_in_background(self): + def _load_app(): + __traceback_hide__ = True # noqa: F841 + with self._lock: + try: + self._load_unlocked() + except Exception: + self._bg_loading_exc_info = sys.exc_info() + + t = Thread(target=_load_app, args=()) + t.start() + + def _flush_bg_loading_exception(self): + __traceback_hide__ = True # noqa: F841 + exc_info = self._bg_loading_exc_info + if exc_info is not None: + self._bg_loading_exc_info = None + raise exc_info + + def _load_unlocked(self): + __traceback_hide__ = True # noqa: F841 + self._app = rv = self.loader() + self._bg_loading_exc_info = None + return rv + + def __call__(self, environ, start_response): + __traceback_hide__ = True # noqa: F841 + if self._app is not None: + return self._app(environ, start_response) + self._flush_bg_loading_exception() + with self._lock: + if self._app is not None: + rv = self._app + else: + rv = self._load_unlocked() + return rv(environ, start_response) + + +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=None, create_app=None, set_debug_flag=True): + #: Optionally the import path for the Flask application. + self.app_import_path = app_import_path or os.environ.get("FLASK_APP") + #: 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 = {} + self.set_debug_flag = set_debug_flag + self._loaded_app = None + + def load_app(self): + """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. + """ + __traceback_hide__ = True # noqa: F841 + + if self._loaded_app is not None: + return self._loaded_app + + if self.create_app is not None: + app = call_factory(self, self.create_app) + else: + if self.app_import_path: + path, name = ( + re.split(r":(?![\\/])", self.app_import_path, 1) + [None] + )[:2] + import_name = prepare_import(path) + app = locate_app(self, import_name, name) + else: + for path in ("wsgi.py", "app.py"): + import_name = prepare_import(path) + app = locate_app(self, import_name, None, raise_if_not_found=False) + + if app: + break + + if not app: + raise NoAppException( + "Could not locate a Flask application. You did not provide " + 'the "FLASK_APP" environment variable, and a "wsgi.py" or ' + '"app.py" module was not found 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. If callbacks are registered directly + to the ``app.cli`` object then they are wrapped with this function + by default unless it's disabled. + """ + + @click.pass_context + def decorator(__ctx, *args, **kwargs): + with __ctx.ensure_object(ScriptInfo).load_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) + + +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 based on the active + environment + + .. 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=True, + create_app=None, + add_version_option=True, + load_dotenv=True, + set_debug_flag=True, + **extra, + ): + params = list(extra.pop("params", None) or ()) + + if add_version_option: + params.append(version_option) + + AppGroup.__init__(self, 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 + try: + import pkg_resources + except ImportError: + self._loaded_plugin_commands = True + return + + for ep in pkg_resources.iter_entry_points("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: + return info.load_app().cli.get_command(ctx, name) + except NoAppException as e: + click.secho(f"Error: {e.format_message()}\n", err=True, fg="red") + + 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 main(self, *args, **kwargs): + # Set a global flag that indicates that we were invoked from the + # command line interface. This is detected by Flask.run to make the + # call into a no-op. This is necessary to avoid ugly errors when the + # script that is loaded here also attempts to start a server. + os.environ["FLASK_RUN_FROM_CLI"] = "true" + + if get_load_dotenv(self.load_dotenv): + load_dotenv() + + obj = kwargs.get("obj") + + if obj is None: + obj = ScriptInfo( + create_app=self.create_app, set_debug_flag=self.set_debug_flag + ) + + kwargs["obj"] = obj + kwargs.setdefault("auto_envvar_prefix", "FLASK") + return super().main(*args, **kwargs) + + +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=None): + """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:: 1.1.0 + Returns ``False`` when python-dotenv is not installed, or when + the given path isn't a file. + + .. versionchanged:: 2.0 + When loading the env files, set the default encoding to UTF-8. + + .. versionadded:: 1.0 + """ + if dotenv is None: + 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 + + # if the given path specifies the actual file then return True, + # else False + if path is not None: + if os.path.isfile(path): + return dotenv.load_dotenv(path, encoding="utf-8") + + return False + + new_dir = None + + for name in (".env", ".flaskenv"): + path = dotenv.find_dotenv(name, usecwd=True) + + if not path: + continue + + if new_dir is None: + new_dir = os.path.dirname(path) + + dotenv.load_dotenv(path, encoding="utf-8") + + return new_dir is not None # at least one file was located and loaded + + +def show_server_banner(env, debug, app_import_path, eager_loading): + """Show extra startup messages the first time the server is run, + ignoring the reloader. + """ + if os.environ.get("WERKZEUG_RUN_MAIN") == "true": + return + + if app_import_path is not None: + message = f" * Serving Flask app {app_import_path!r}" + + if not eager_loading: + message += " (lazy loading)" + + click.echo(message) + + click.echo(f" * Environment: {env}") + + if env == "production": + click.secho( + " WARNING: This is a development server. Do not use it in" + " a production deployment.", + fg="red", + ) + click.secho(" Use a production WSGI server instead.", dim=True) + + 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): + if ssl is None: + raise click.BadParameter( + 'Using "--cert" requires Python to be compiled with SSL support.', + ctx, + param, + ) + + 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, + ) + + 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" + is_context = ssl and 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." +) +@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( + "--eager-loading/--lazy-loading", + default=None, + help="Enable or disable eager loading. By default eager " + "loading is enabled if the reloader is disabled.", +) +@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}." + ), +) +@pass_script_info +def run_command( + info, host, port, reload, debugger, eager_loading, with_threads, cert, extra_files +): + """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 if + FLASK_ENV=development or FLASK_DEBUG=1. + """ + debug = get_debug_flag() + + if reload is None: + reload = debug + + if debugger is None: + debugger = debug + + show_server_banner(get_env(), debug, info.app_import_path, eager_loading) + app = DispatchingApp(info.load_app, use_eager_loading=eager_loading) + + from werkzeug.serving import run_simple + + run_simple( + host, + port, + app, + use_reloader=reload, + use_debugger=debugger, + threaded=with_threads, + ssl_context=cert, + extra_files=extra_files, + ) + + +@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 + from .globals import _app_ctx_stack + + app = _app_ctx_stack.top.app + banner = ( + f"Python {sys.version} on {sys.platform}\n" + f"App: {app.import_name} [{app.env}]\n" + f"Instance: {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(app.make_shell_context()) + + # Site, customize, or startup script can set a hook to call when + # entering interactive mode. The default one sets up readline with + # tab and history completion. + interactive_hook = getattr(sys, "__interactivehook__", None) + + if interactive_hook is not None: + try: + import readline + from rlcompleter import Completer + except ImportError: + pass + else: + # rlcompleter uses __main__.__dict__ by default, which is + # flask.__main__. Use the shell context instead. + readline.set_completer(Completer(ctx).complete) + + interactive_hook() + + code.interact(banner=banner, local=ctx) + + +@click.command("routes", short_help="Show the routes for the app.") +@click.option( + "--sort", + "-s", + type=click.Choice(("endpoint", "methods", "rule", "match")), + default="endpoint", + help=( + 'Method to sort routes by. "match" is the order that Flask will match ' + "routes when dispatching a request." + ), +) +@click.option("--all-methods", is_flag=True, help="Show HEAD and OPTIONS methods.") +@with_appcontext +def routes_command(sort: str, all_methods: bool) -> None: + """Show all registered routes with endpoints and methods.""" + + rules = list(current_app.url_map.iter_rules()) + if not rules: + click.echo("No routes were registered.") + return + + ignored_methods = set(() if all_methods else ("HEAD", "OPTIONS")) + + if sort in ("endpoint", "rule"): + rules = sorted(rules, key=attrgetter(sort)) + elif sort == "methods": + rules = sorted(rules, key=lambda rule: sorted(rule.methods)) # type: ignore + + rule_methods = [ + ", ".join(sorted(rule.methods - ignored_methods)) # type: ignore + for rule in rules + ] + + headers = ("Endpoint", "Methods", "Rule") + widths = ( + max(len(rule.endpoint) for rule in rules), + max(len(methods) for methods in rule_methods), + max(len(rule.rule) for rule in rules), + ) + widths = [max(len(h), w) for h, w in zip(headers, widths)] + row = "{{0:<{0}}} {{1:<{1}}} {{2:<{2}}}".format(*widths) + + click.echo(row.format(*headers).strip()) + click.echo(row.format(*("-" * width for width in widths))) + + for rule, methods in zip(rules, rule_methods): + click.echo(row.format(rule.endpoint, methods, rule.rule).rstrip()) + + +cli = FlaskGroup( + help="""\ +A general utility script for Flask applications. + +Provides commands from Flask, extensions, and the application. Loads the +application defined in the FLASK_APP environment variable, or from a wsgi.py +file. Setting the FLASK_ENV environment variable to 'development' will enable +debug mode. + +\b + {prefix}{cmd} FLASK_APP=hello.py + {prefix}{cmd} FLASK_ENV=development + {prefix}flask run +""".format( + cmd="export" if os.name == "posix" else "set", + prefix="$ " if os.name == "posix" else "> ", + ) +) + + +def main() -> None: + if int(click.__version__[0]) < 8: + warnings.warn( + "Using the `flask` cli with Click 7 is deprecated and" + " will not be supported starting with Flask 2.1." + " Please upgrade to Click 8 as soon as possible.", + DeprecationWarning, + ) + # TODO omit sys.argv once https://github.com/pallets/click/issues/536 is fixed + cli.main(args=sys.argv[1:]) + + +if __name__ == "__main__": + main() diff --git a/venv/lib/python3.9/site-packages/flask/config.py b/venv/lib/python3.9/site-packages/flask/config.py new file mode 100644 index 0000000..c79a558 --- /dev/null +++ b/venv/lib/python3.9/site-packages/flask/config.py @@ -0,0 +1,291 @@ +import errno +import os +import types +import typing as t + +from werkzeug.utils import import_string + + +class ConfigAttribute: + """Makes an attribute forward to the config""" + + def __init__(self, name: str, get_converter: t.Optional[t.Callable] = None) -> None: + self.__name__ = name + self.get_converter = get_converter + + def __get__(self, obj: t.Any, owner: t.Any = None) -> t.Any: + if obj is None: + return self + rv = obj.config[self.__name__] + if self.get_converter is not None: + rv = self.get_converter(rv) + return rv + + def __set__(self, obj: t.Any, value: t.Any) -> None: + obj.config[self.__name__] = value + + +class Config(dict): + """Works exactly like a dict but provides ways to fill it from files + or special dictionaries. There are two common patterns to populate the + config. + + Either you can fill the config from a config file:: + + app.config.from_pyfile('yourconfig.cfg') + + Or alternatively you can define the configuration options in the + module that calls :meth:`from_object` or provide an import path to + a module that should be loaded. It is also possible to tell it to + use the same module and with that provide the configuration values + just before the call:: + + DEBUG = True + SECRET_KEY = 'development key' + app.config.from_object(__name__) + + In both cases (loading from any Python file or loading from modules), + only uppercase keys are added to the config. This makes it possible to use + lowercase values in the config file for temporary values that are not added + to the config or to define the config keys in the same file that implements + the application. + + Probably the most interesting way to load configurations is from an + environment variable pointing to a file:: + + app.config.from_envvar('YOURAPPLICATION_SETTINGS') + + In this case before launching the application you have to set this + environment variable to the file you want to use. On Linux and OS X + use the export statement:: + + export YOURAPPLICATION_SETTINGS='/path/to/config/file' + + On windows use `set` instead. + + :param root_path: path to which files are read relative from. When the + config object is created by the application, this is + the application's :attr:`~flask.Flask.root_path`. + :param defaults: an optional dictionary of default values + """ + + def __init__(self, root_path: str, defaults: t.Optional[dict] = None) -> None: + dict.__init__(self, 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: bool. ``True`` if able to load config, ``False`` otherwise. + """ + 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_pyfile(self, filename: str, silent: bool = False) -> bool: + """Updates the values in the config from a Python file. This function + behaves as if the file was imported as module with the + :meth:`from_object` function. + + :param filename: the filename of the config. This can either be an + absolute filename or a filename relative to the + root path. + :param silent: set to ``True`` if you want silent failure for missing + files. + + .. versionadded:: 0.7 + `silent` parameter. + """ + filename = os.path.join(self.root_path, filename) + d = types.ModuleType("config") + d.__file__ = filename + try: + with open(filename, mode="rb") as config_file: + exec(compile(config_file.read(), filename, "exec"), d.__dict__) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR, errno.ENOTDIR): + return False + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + self.from_object(d) + return True + + def from_object(self, obj: t.Union[object, str]) -> None: + """Updates the values from the given object. An object can be of one + of the following two types: + + - a string: in this case the object with that name will be imported + - an actual object reference: that object is used directly + + Objects are usually either modules or classes. :meth:`from_object` + loads only the uppercase attributes of the module/class. A ``dict`` + object will not work with :meth:`from_object` because the keys of a + ``dict`` are not attributes of the ``dict`` class. + + Example of module-based configuration:: + + app.config.from_object('yourapplication.default_config') + from yourapplication import default_config + app.config.from_object(default_config) + + Nothing is done to the object before loading. If the object is a + class and has ``@property`` attributes, it needs to be + instantiated before being passed to this method. + + You should not use this function to load the actual configuration but + rather configuration defaults. The actual config should be loaded + with :meth:`from_pyfile` and ideally from a location not within the + package because the package might be installed system wide. + + See :ref:`config-dev-prod` for an example of class-based configuration + using :meth:`from_object`. + + :param obj: an import name or object + """ + if isinstance(obj, str): + obj = import_string(obj) + for key in dir(obj): + if key.isupper(): + self[key] = getattr(obj, key) + + def from_file( + self, + filename: str, + load: t.Callable[[t.IO[t.Any]], t.Mapping], + silent: bool = False, + ) -> bool: + """Update the values in the config from a file that is loaded + using the ``load`` parameter. The loaded data is passed to the + :meth:`from_mapping` method. + + .. code-block:: python + + import toml + app.config.from_file("config.toml", load=toml.load) + + :param filename: The path to the data file. This can be an + absolute path or relative to the config root path. + :param load: A callable that takes a file handle and returns a + mapping of loaded data from the file. + :type load: ``Callable[[Reader], Mapping]`` where ``Reader`` + implements a ``read`` method. + :param silent: Ignore the file if it doesn't exist. + + .. versionadded:: 2.0 + """ + filename = os.path.join(self.root_path, filename) + + try: + with open(filename) as f: + obj = load(f) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR): + return False + + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + + return self.from_mapping(obj) + + def from_json(self, filename: str, silent: bool = False) -> bool: + """Update the values in the config from a JSON file. The loaded + data is passed to the :meth:`from_mapping` method. + + :param filename: The path to the JSON file. This can be an + absolute path or relative to the config root path. + :param silent: Ignore the file if it doesn't exist. + + .. deprecated:: 2.0.0 + Will be removed in Flask 2.1. Use :meth:`from_file` instead. + This was removed early in 2.0.0, was added back in 2.0.1. + + .. versionadded:: 0.11 + """ + import warnings + from . import json + + warnings.warn( + "'from_json' is deprecated and will be removed in Flask" + " 2.1. Use 'from_file(path, json.load)' instead.", + DeprecationWarning, + stacklevel=2, + ) + return self.from_file(filename, json.load, silent=silent) + + def from_mapping( + self, mapping: t.Optional[t.Mapping[str, t.Any]] = None, **kwargs: t.Any + ) -> bool: + """Updates the config like :meth:`update` ignoring items with non-upper + keys. + + .. versionadded:: 0.11 + """ + mappings: t.Dict[str, t.Any] = {} + if mapping is not None: + mappings.update(mapping) + mappings.update(kwargs) + for key, value in mappings.items(): + if key.isupper(): + self[key] = value + return True + + def get_namespace( + self, namespace: str, lowercase: bool = True, trim_namespace: bool = True + ) -> t.Dict[str, t.Any]: + """Returns a dictionary containing a subset of configuration options + that match the specified namespace/prefix. Example usage:: + + app.config['IMAGE_STORE_TYPE'] = 'fs' + app.config['IMAGE_STORE_PATH'] = '/var/app/images' + app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com' + image_store_config = app.config.get_namespace('IMAGE_STORE_') + + The resulting dictionary `image_store_config` would look like:: + + { + 'type': 'fs', + 'path': '/var/app/images', + 'base_url': 'http://img.website.com' + } + + This is often useful when configuration options map directly to + keyword arguments in functions or class constructors. + + :param namespace: a configuration namespace + :param lowercase: a flag indicating if the keys of the resulting + dictionary should be lowercase + :param trim_namespace: a flag indicating if the keys of the resulting + dictionary should not include the namespace + + .. versionadded:: 0.11 + """ + rv = {} + for k, v in self.items(): + if not k.startswith(namespace): + continue + if trim_namespace: + key = k[len(namespace) :] + else: + key = k + if lowercase: + key = key.lower() + rv[key] = v + return rv + + def __repr__(self) -> str: + return f"<{type(self).__name__} {dict.__repr__(self)}>" diff --git a/venv/lib/python3.9/site-packages/flask/ctx.py b/venv/lib/python3.9/site-packages/flask/ctx.py new file mode 100644 index 0000000..5c06463 --- /dev/null +++ b/venv/lib/python3.9/site-packages/flask/ctx.py @@ -0,0 +1,480 @@ +import sys +import typing as t +from functools import update_wrapper +from types import TracebackType + +from werkzeug.exceptions import HTTPException + +from .globals import _app_ctx_stack +from .globals import _request_ctx_stack +from .signals import appcontext_popped +from .signals import appcontext_pushed +from .typing import AfterRequestCallable + +if t.TYPE_CHECKING: + from .app import Flask + from .sessions import SessionMixin + from .wrappers import Request + + +# a singleton sentinel value for parameter defaults +_sentinel = object() + + +class _AppCtxGlobals: + """A plain object. Used as a namespace for storing data during an + application context. + + Creating an app context automatically creates this object, which is + made available as the :data:`g` proxy. + + .. describe:: 'key' in g + + Check whether an attribute is present. + + .. versionadded:: 0.10 + + .. describe:: iter(g) + + Return an iterator over the attribute names. + + .. versionadded:: 0.10 + """ + + # Define attr methods to let mypy know this is a namespace object + # that has arbitrary attributes. + + def __getattr__(self, name: str) -> t.Any: + try: + return self.__dict__[name] + except KeyError: + raise AttributeError(name) from None + + def __setattr__(self, name: str, value: t.Any) -> None: + self.__dict__[name] = value + + def __delattr__(self, name: str) -> None: + try: + del self.__dict__[name] + except KeyError: + raise AttributeError(name) from None + + def get(self, name: str, default: t.Optional[t.Any] = None) -> t.Any: + """Get an attribute by name, or a default value. Like + :meth:`dict.get`. + + :param name: Name of attribute to get. + :param default: Value to return if the attribute is not present. + + .. versionadded:: 0.10 + """ + return self.__dict__.get(name, default) + + def pop(self, name: str, default: t.Any = _sentinel) -> t.Any: + """Get and remove an attribute by name. Like :meth:`dict.pop`. + + :param name: Name of attribute to pop. + :param default: Value to return if the attribute is not present, + instead of raising a ``KeyError``. + + .. versionadded:: 0.11 + """ + if default is _sentinel: + return self.__dict__.pop(name) + else: + return self.__dict__.pop(name, default) + + def setdefault(self, name: str, default: t.Any = None) -> t.Any: + """Get the value of an attribute if it is present, otherwise + set and return a default value. Like :meth:`dict.setdefault`. + + :param name: Name of attribute to get. + :param default: Value to set and return if the attribute is not + present. + + .. versionadded:: 0.11 + """ + return self.__dict__.setdefault(name, default) + + def __contains__(self, item: str) -> bool: + return item in self.__dict__ + + def __iter__(self) -> t.Iterator[str]: + return iter(self.__dict__) + + def __repr__(self) -> str: + top = _app_ctx_stack.top + if top is not None: + return f"" + return object.__repr__(self) + + +def after_this_request(f: AfterRequestCallable) -> 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 + """ + _request_ctx_stack.top._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 + """ + top = _request_ctx_stack.top + if top is None: + raise RuntimeError( + "This decorator can only be used at local scopes " + "when a request context is on the stack. For instance within " + "view functions." + ) + reqctx = top.copy() + + def wrapper(*args, **kwargs): + with reqctx: + return 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 _request_ctx_stack.top 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 _app_ctx_stack.top is not None + + +class AppContext: + """The application context binds an application object implicitly + to the current thread or greenlet, similar to how the + :class:`RequestContext` binds request information. The application + context is also implicitly created if a request context is created + but the application is not on top of the individual application + context. + """ + + def __init__(self, app: "Flask") -> None: + self.app = app + self.url_adapter = app.create_url_adapter(None) + self.g = app.app_ctx_globals_class() + + # Like request context, app contexts can be pushed multiple times + # but there a basic "refcount" is enough to track them. + self._refcnt = 0 + + def push(self) -> None: + """Binds the app context to the current context.""" + self._refcnt += 1 + _app_ctx_stack.push(self) + appcontext_pushed.send(self.app) + + def pop(self, exc: t.Optional[BaseException] = _sentinel) -> None: # type: ignore + """Pops the app context.""" + try: + self._refcnt -= 1 + if self._refcnt <= 0: + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_appcontext(exc) + finally: + rv = _app_ctx_stack.pop() + assert rv is self, f"Popped wrong app context. ({rv!r} instead of {self!r})" + appcontext_popped.send(self.app) + + def __enter__(self) -> "AppContext": + self.push() + return self + + def __exit__( + self, exc_type: type, exc_value: BaseException, tb: TracebackType + ) -> None: + self.pop(exc_value) + + +class RequestContext: + """The request context contains all request relevant information. It is + created at the beginning of the request and pushed to the + `_request_ctx_stack` and removed at the end of it. 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 + for you. In debug mode the request context is kept around if + exceptions happen so that interactive debuggers have a chance to + introspect the data. With 0.4 this can also be forced for requests + that did not fail and outside of ``DEBUG`` mode. By setting + ``'flask._preserve_context'`` to ``True`` on the WSGI environment the + context will not pop itself at the end of the request. This is used by + the :meth:`~flask.Flask.test_client` for example to implement the + deferred cleanup functionality. + + You might find this helpful for unittests where you need the + information from the context local around for a little longer. Make + sure to properly :meth:`~werkzeug.LocalStack.pop` the stack yourself in + that situation, otherwise your unittests will leak memory. + """ + + def __init__( + self, + app: "Flask", + environ: dict, + request: t.Optional["Request"] = None, + session: t.Optional["SessionMixin"] = None, + ) -> None: + self.app = app + if request is None: + request = app.request_class(environ) + self.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 = None + self.session = session + + # Request contexts can be pushed multiple times and interleaved with + # other request contexts. Now only if the last level is popped we + # get rid of them. Additionally if an application context is missing + # one is created implicitly so for each level we add this information + self._implicit_app_ctx_stack: t.List[t.Optional["AppContext"]] = [] + + # indicator if the context was preserved. Next time another context + # is pushed the preserved context is popped. + self.preserved = False + + # remembers the exception for pop if there is one in case the context + # preservation kicks in. + self._preserved_exc = None + + # Functions that should be executed after the request on the response + # object. These will be called before the regular "after_request" + # functions. + self._after_request_functions: t.List[AfterRequestCallable] = [] + + @property + def g(self) -> AppContext: + return _app_ctx_stack.top.g + + @g.setter + def g(self, value: AppContext) -> None: + _app_ctx_stack.top.g = value + + 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: + """Binds the request context to the current context.""" + # If an exception occurs in debug mode or if context preservation is + # activated under exception situations exactly one context stays + # on the stack. The rationale is that you want to access that + # information under debug situations. However if someone forgets to + # pop that context again we want to make sure that on the next push + # it's invalidated, otherwise we run at risk that something leaks + # memory. This is usually only a problem in test suite since this + # functionality is not active in production environments. + top = _request_ctx_stack.top + if top is not None and top.preserved: + top.pop(top._preserved_exc) + + # Before we push the request context we have to ensure that there + # is an application context. + app_ctx = _app_ctx_stack.top + if app_ctx is None or app_ctx.app != self.app: + app_ctx = self.app.app_context() + app_ctx.push() + self._implicit_app_ctx_stack.append(app_ctx) + else: + self._implicit_app_ctx_stack.append(None) + + _request_ctx_stack.push(self) + + # Open the session at the moment that the request context is available. + # This allows a custom open_session method to use the request context. + # Only open a new session if this is the first time the request was + # pushed, otherwise stream_with_context loses the session. + if self.session is None: + session_interface = self.app.session_interface + self.session = session_interface.open_session(self.app, self.request) + + if self.session is None: + self.session = session_interface.make_null_session(self.app) + + # Match the request URL after loading the session, so that the + # session is available in custom URL converters. + if self.url_adapter is not None: + self.match_request() + + def pop(self, exc: t.Optional[BaseException] = _sentinel) -> None: # type: ignore + """Pops the request context and unbinds it by doing that. This will + also trigger the execution of functions registered by the + :meth:`~flask.Flask.teardown_request` decorator. + + .. versionchanged:: 0.9 + Added the `exc` argument. + """ + app_ctx = self._implicit_app_ctx_stack.pop() + clear_request = False + + try: + if not self._implicit_app_ctx_stack: + self.preserved = False + self._preserved_exc = None + 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() + clear_request = True + finally: + rv = _request_ctx_stack.pop() + + # 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: + rv.request.environ["werkzeug.request"] = None + + # Get rid of the app as well if necessary. + if app_ctx is not None: + app_ctx.pop(exc) + + assert ( + rv is self + ), f"Popped wrong request context. ({rv!r} instead of {self!r})" + + def auto_pop(self, exc: t.Optional[BaseException]) -> None: + if self.request.environ.get("flask._preserve_context") or ( + exc is not None and self.app.preserve_context_on_exception + ): + self.preserved = True + self._preserved_exc = exc # type: ignore + else: + self.pop(exc) + + def __enter__(self) -> "RequestContext": + self.push() + return self + + def __exit__( + self, exc_type: type, exc_value: BaseException, tb: TracebackType + ) -> None: + # do not pop the request stack if we are in debug mode and an + # exception happened. This will allow the debugger to still + # access the request object in the interactive shell. Furthermore + # the context can be force kept alive for the test client. + # See flask.testing for how this works. + self.auto_pop(exc_value) + + def __repr__(self) -> str: + return ( + f"<{type(self).__name__} {self.request.url!r}" + f" [{self.request.method}] of {self.app.name}>" + ) diff --git a/venv/lib/python3.9/site-packages/flask/debughelpers.py b/venv/lib/python3.9/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..ce65c48 --- /dev/null +++ b/venv/lib/python3.9/site-packages/flask/debughelpers.py @@ -0,0 +1,171 @@ +import os +import typing as t +from warnings import warn + +from .app import Flask +from .blueprints import Blueprint +from .globals import _request_ctx_stack + + +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 by Flask in debug mode if it detects a + redirect caused by the routing system when the request method is not + GET, HEAD or OPTIONS. Reasoning: form data will be dropped. + """ + + def __init__(self, request): + exc = request.routing_exception + buf = [ + f"A request was sent to this URL ({request.url}) but a" + " redirect was issued automatically by the routing system" + f" to {exc.new_url!r}." + ] + + # In case just a slash was appended we can be extra helpful + if f"{request.base_url}/" == exc.new_url.split("?")[0]: + buf.append( + " The URL was defined with a trailing slash so Flask" + " will automatically redirect to the URL with the" + " trailing slash if it was accessed without one." + ) + + buf.append( + " Make sure to directly send your" + f" {request.method}-request to this URL since we can't make" + " browsers or HTTP clients redirect with form data reliably" + " or without user interaction." + ) + buf.append("\n\nNote: this exception is only raised in debug mode") + AssertionError.__init__(self, "".join(buf).encode("utf-8")) + + +def attach_enctype_error_multidict(request): + """Since Flask 0.8 we're monkeypatching the files object in case a + request is detected that does not use multipart form data but the files + object is accessed. + """ + oldcls = request.files.__class__ + + class newcls(oldcls): + def __getitem__(self, key): + try: + return oldcls.__getitem__(self, key) + except KeyError: + if key not in request.form: + raise + raise DebugFilesKeyError(request, key) + + newcls.__name__ = oldcls.__name__ + newcls.__module__ = oldcls.__module__ + request.files.__class__ = newcls + + +def _dump_loader_info(loader) -> t.Generator: + yield f"class: {type(loader).__module__}.{type(loader).__name__}" + for key, value in sorted(loader.__dict__.items()): + if key.startswith("_"): + continue + if isinstance(value, (tuple, list)): + if not all(isinstance(x, str) for x in value): + continue + yield f"{key}:" + for item in value: + yield f" - {item}" + continue + elif not isinstance(value, (str, int, float, bool)): + continue + yield f"{key}: {value!r}" + + +def explain_template_loading_attempts(app: Flask, template, attempts) -> None: + """This should help developers understand what failed""" + info = [f"Locating template {template!r}:"] + total_found = 0 + blueprint = None + reqctx = _request_ctx_stack.top + if reqctx is not None and reqctx.request.blueprint is not None: + blueprint = reqctx.request.blueprint + + for idx, (loader, srcobj, triple) in enumerate(attempts): + if isinstance(srcobj, Flask): + src_info = f"application {srcobj.import_name!r}" + elif isinstance(srcobj, Blueprint): + src_info = f"blueprint {srcobj.name!r} ({srcobj.import_name})" + else: + src_info = repr(srcobj) + + info.append(f"{idx + 1:5}: trying loader of {src_info}") + + for line in _dump_loader_info(loader): + info.append(f" {line}") + + if triple is None: + detail = "no match" + else: + detail = f"found ({triple[1] or ''!r})" + total_found += 1 + info.append(f" -> {detail}") + + seems_fishy = False + if total_found == 0: + info.append("Error: the template could not be found.") + seems_fishy = True + elif total_found > 1: + info.append("Warning: multiple loaders returned a match for the template.") + seems_fishy = True + + if blueprint is not None and seems_fishy: + info.append( + " The template was looked up from an endpoint that belongs" + f" to the blueprint {blueprint!r}." + ) + info.append(" Maybe you did not place a template in the right folder?") + info.append(" See https://flask.palletsprojects.com/blueprints/#templates") + + app.logger.info("\n".join(info)) + + +def explain_ignored_app_run() -> None: + if os.environ.get("WERKZEUG_RUN_MAIN") != "true": + warn( + Warning( + "Silently ignoring app.run() because the application is" + " run from the flask command line executable. Consider" + ' putting app.run() behind an if __name__ == "__main__"' + " guard to silence this warning." + ), + stacklevel=3, + ) diff --git a/venv/lib/python3.9/site-packages/flask/globals.py b/venv/lib/python3.9/site-packages/flask/globals.py new file mode 100644 index 0000000..6d91c75 --- /dev/null +++ b/venv/lib/python3.9/site-packages/flask/globals.py @@ -0,0 +1,59 @@ +import typing as t +from functools import partial + +from werkzeug.local import LocalProxy +from werkzeug.local import LocalStack + +if t.TYPE_CHECKING: + from .app import Flask + from .ctx import _AppCtxGlobals + from .sessions import SessionMixin + from .wrappers import Request + +_request_ctx_err_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.\ +""" +_app_ctx_err_msg = """\ +Working outside of application context. + +This typically means that you attempted to use functionality that needed +to interface with the current application object in some way. To solve +this, set up an application context with app.app_context(). See the +documentation for more information.\ +""" + + +def _lookup_req_object(name): + top = _request_ctx_stack.top + if top is None: + raise RuntimeError(_request_ctx_err_msg) + return getattr(top, name) + + +def _lookup_app_object(name): + top = _app_ctx_stack.top + if top is None: + raise RuntimeError(_app_ctx_err_msg) + return getattr(top, name) + + +def _find_app(): + top = _app_ctx_stack.top + if top is None: + raise RuntimeError(_app_ctx_err_msg) + return top.app + + +# context locals +_request_ctx_stack = LocalStack() +_app_ctx_stack = LocalStack() +current_app: "Flask" = LocalProxy(_find_app) # type: ignore +request: "Request" = LocalProxy(partial(_lookup_req_object, "request")) # type: ignore +session: "SessionMixin" = LocalProxy( # type: ignore + partial(_lookup_req_object, "session") +) +g: "_AppCtxGlobals" = LocalProxy(partial(_lookup_app_object, "g")) # type: ignore diff --git a/venv/lib/python3.9/site-packages/flask/helpers.py b/venv/lib/python3.9/site-packages/flask/helpers.py new file mode 100644 index 0000000..7b8b087 --- /dev/null +++ b/venv/lib/python3.9/site-packages/flask/helpers.py @@ -0,0 +1,836 @@ +import os +import pkgutil +import socket +import sys +import typing as t +import warnings +from datetime import datetime +from datetime import timedelta +from functools import lru_cache +from functools import update_wrapper +from threading import RLock + +import werkzeug.utils +from werkzeug.exceptions import NotFound +from werkzeug.routing import BuildError +from werkzeug.urls import url_quote + +from .globals import _app_ctx_stack +from .globals import _request_ctx_stack +from .globals import current_app +from .globals import request +from .globals import session +from .signals import message_flashed + +if t.TYPE_CHECKING: + from .wrappers import Response + + +def get_env() -> str: + """Get the environment the app is running in, indicated by the + :envvar:`FLASK_ENV` environment variable. The default is + ``'production'``. + """ + return os.environ.get("FLASK_ENV") or "production" + + +def get_debug_flag() -> bool: + """Get whether debug mode should be enabled for the app, indicated + by the :envvar:`FLASK_DEBUG` environment variable. The default is + ``True`` if :func:`.get_env` returns ``'development'``, or ``False`` + otherwise. + """ + val = os.environ.get("FLASK_DEBUG") + + if not val: + return get_env() == "development" + + return val.lower() not in ("0", "false", "no") + + +def get_load_dotenv(default: bool = True) -> bool: + """Get whether the user has disabled loading dotenv files by setting + :envvar:`FLASK_SKIP_DOTENV`. The default is ``True``, load the + files. + + :param default: What to return if the env var isn't set. + """ + val = os.environ.get("FLASK_SKIP_DOTENV") + + if not val: + return default + + return val.lower() in ("0", "false", "no") + + +def stream_with_context( + generator_or_function: t.Union[ + t.Iterator[t.AnyStr], t.Callable[..., t.Iterator[t.AnyStr]] + ] +) -> t.Iterator[t.AnyStr]: + """Request contexts disappear when the response is started on the server. + This is done for efficiency reasons and to make it less likely to encounter + memory leaks with badly written WSGI middlewares. The downside is that if + you are using streamed responses, the generator cannot access request bound + information any more. + + This function however can help you keep the context around for longer:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + @stream_with_context + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(generate()) + + Alternatively it can also be used around a specific generator:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(stream_with_context(generate())) + + .. versionadded:: 0.9 + """ + try: + gen = iter(generator_or_function) # type: ignore + except TypeError: + + def decorator(*args: t.Any, **kwargs: t.Any) -> t.Any: + gen = generator_or_function(*args, **kwargs) # type: ignore + return stream_with_context(gen) + + return update_wrapper(decorator, generator_or_function) # type: ignore + + def generator() -> t.Generator: + ctx = _request_ctx_stack.top + if ctx is None: + raise RuntimeError( + "Attempted to stream with context but " + "there was no context in the first place to keep around." + ) + with ctx: + # Dummy sentinel. Has to be inside the context block or we're + # not actually keeping the context around. + yield None + + # The try/finally is here so that if someone passes a WSGI level + # iterator in we're still running the cleanup logic. Generators + # don't need that because they are closed on their destruction + # automatically. + try: + yield from gen + finally: + if hasattr(gen, "close"): + gen.close() # type: ignore + + # The trick is to start the generator. Then the code execution runs until + # the first dummy None is yielded at which point the context was already + # pushed. This item is discarded. Then when the iteration continues the + # real generator is executed. + wrapped_g = generator() + next(wrapped_g) + return wrapped_g + + +def make_response(*args: t.Any) -> "Response": + """Sometimes it is necessary to set additional headers in a view. Because + views do not have to return response objects but can return a value that + is converted into a response object by Flask itself, it becomes tricky to + add headers to it. This function can be called instead of using a return + and you will get a response object which you can use to attach headers. + + If view looked like this and you want to add a new header:: + + def index(): + return render_template('index.html', foo=42) + + You can now do something like this:: + + def index(): + response = make_response(render_template('index.html', foo=42)) + response.headers['X-Parachutes'] = 'parachutes are cool' + return response + + This function accepts the very same arguments you can return from a + view function. This for example creates a response with a 404 error + code:: + + response = make_response(render_template('not_found.html'), 404) + + The other use case of this function is to force the return value of a + view function into a response which is helpful with view + decorators:: + + response = make_response(view_function()) + response.headers['X-Parachutes'] = 'parachutes are cool' + + Internally this function does the following things: + + - if no arguments are passed, it creates a new response argument + - if one argument is passed, :meth:`flask.Flask.make_response` + is invoked with it. + - if more than one argument is passed, the arguments are passed + to the :meth:`flask.Flask.make_response` function as tuple. + + .. versionadded:: 0.6 + """ + if not args: + return current_app.response_class() + if len(args) == 1: + args = args[0] + return current_app.make_response(args) + + +def url_for(endpoint: str, **values: t.Any) -> str: + """Generates a URL to the given endpoint with the method provided. + + Variable arguments that are unknown to the target endpoint are appended + to the generated URL as query arguments. If the value of a query argument + is ``None``, the whole pair is skipped. In case blueprints are active + you can shortcut references to the same blueprint by prefixing the + local endpoint with a dot (``.``). + + This will reference the index function local to the current blueprint:: + + url_for('.index') + + See :ref:`url-building`. + + Configuration values ``APPLICATION_ROOT`` and ``SERVER_NAME`` are only used when + generating URLs outside of a request context. + + To integrate applications, :class:`Flask` has a hook to intercept URL build + errors through :attr:`Flask.url_build_error_handlers`. The `url_for` + function results in a :exc:`~werkzeug.routing.BuildError` when the current + app does not have a URL for the given endpoint and values. When it does, the + :data:`~flask.current_app` calls its :attr:`~Flask.url_build_error_handlers` if + it is not ``None``, which can return a string to use as the result of + `url_for` (instead of `url_for`'s default to raise the + :exc:`~werkzeug.routing.BuildError` exception) or re-raise the exception. + An example:: + + def external_url_handler(error, endpoint, values): + "Looks up an external URL when `url_for` cannot build a URL." + # This is an example of hooking the build_error_handler. + # Here, lookup_url is some utility function you've built + # which looks up the endpoint in some external URL registry. + url = lookup_url(endpoint, **values) + if url is None: + # External lookup did not have a URL. + # Re-raise the BuildError, in context of original traceback. + exc_type, exc_value, tb = sys.exc_info() + if exc_value is error: + raise exc_type(exc_value).with_traceback(tb) + else: + raise error + # url_for will use this result, instead of raising BuildError. + return url + + app.url_build_error_handlers.append(external_url_handler) + + Here, `error` is the instance of :exc:`~werkzeug.routing.BuildError`, and + `endpoint` and `values` are the arguments passed into `url_for`. Note + that this is for building URLs outside the current application, and not for + handling 404 NotFound errors. + + .. versionadded:: 0.10 + The `_scheme` parameter was added. + + .. versionadded:: 0.9 + The `_anchor` and `_method` parameters were added. + + .. versionadded:: 0.9 + Calls :meth:`Flask.handle_build_error` on + :exc:`~werkzeug.routing.BuildError`. + + :param endpoint: the endpoint of the URL (name of the function) + :param values: the variable arguments of the URL rule + :param _external: if set to ``True``, an absolute URL is generated. Server + address can be changed via ``SERVER_NAME`` configuration variable which + falls back to the `Host` header, then to the IP and port of the request. + :param _scheme: a string specifying the desired URL scheme. The `_external` + parameter must be set to ``True`` or a :exc:`ValueError` is raised. The default + behavior uses the same scheme as the current request, or + :data:`PREFERRED_URL_SCHEME` if no request context is available. + This also can be set to an empty string to build protocol-relative + URLs. + :param _anchor: if provided this is added as anchor to the URL. + :param _method: if provided this explicitly specifies an HTTP method. + """ + appctx = _app_ctx_stack.top + reqctx = _request_ctx_stack.top + + if appctx is None: + raise RuntimeError( + "Attempted to generate a URL without the application context being" + " pushed. This has to be executed when application context is" + " available." + ) + + # If request specific information is available we have some extra + # features that support "relative" URLs. + if reqctx is not None: + url_adapter = reqctx.url_adapter + blueprint_name = request.blueprint + + if endpoint[:1] == ".": + if blueprint_name is not None: + endpoint = f"{blueprint_name}{endpoint}" + else: + endpoint = endpoint[1:] + + external = values.pop("_external", False) + + # Otherwise go with the url adapter from the appctx and make + # the URLs external by default. + else: + url_adapter = appctx.url_adapter + + if url_adapter is None: + raise RuntimeError( + "Application was not able to create a URL adapter for request" + " independent URL generation. You might be able to fix this by" + " setting the SERVER_NAME config variable." + ) + + external = values.pop("_external", True) + + anchor = values.pop("_anchor", None) + method = values.pop("_method", None) + scheme = values.pop("_scheme", None) + appctx.app.inject_url_defaults(endpoint, values) + + # This is not the best way to deal with this but currently the + # underlying Werkzeug router does not support overriding the scheme on + # a per build call basis. + old_scheme = None + if scheme is not None: + if not external: + raise ValueError("When specifying _scheme, _external must be True") + old_scheme = url_adapter.url_scheme + url_adapter.url_scheme = scheme + + try: + try: + rv = url_adapter.build( + endpoint, values, method=method, force_external=external + ) + finally: + if old_scheme is not None: + url_adapter.url_scheme = old_scheme + except BuildError as error: + # We need to inject the values again so that the app callback can + # deal with that sort of stuff. + values["_external"] = external + values["_anchor"] = anchor + values["_method"] = method + values["_scheme"] = scheme + return appctx.app.handle_url_build_error(error, endpoint, values) + + if anchor is not None: + rv += f"#{url_quote(anchor)}" + return rv + + +def get_template_attribute(template_name: str, attribute: str) -> t.Any: + """Loads a macro (or variable) a template exports. This can be used to + invoke a macro from within Python code. If you for example have a + template named :file:`_cider.html` with the following contents: + + .. sourcecode:: html+jinja + + {% macro hello(name) %}Hello {{ name }}!{% endmacro %} + + You can access this from Python code like this:: + + hello = get_template_attribute('_cider.html', 'hello') + return hello('World') + + .. versionadded:: 0.2 + + :param template_name: the name of the template + :param attribute: the name of the variable of macro to access + """ + return getattr(current_app.jinja_env.get_template(template_name).module, attribute) + + +def flash(message: str, category: str = "message") -> None: + """Flashes a message to the next request. In order to remove the + flashed message from the session and to display it to the user, + the template has to call :func:`get_flashed_messages`. + + .. versionchanged:: 0.3 + `category` parameter added. + + :param message: the message to be flashed. + :param category: the category for the message. The following values + are recommended: ``'message'`` for any kind of message, + ``'error'`` for errors, ``'info'`` for information + messages and ``'warning'`` for warnings. However any + kind of string can be used as category. + """ + # Original implementation: + # + # session.setdefault('_flashes', []).append((category, message)) + # + # This assumed that changes made to mutable structures in the session are + # always in sync with the session object, which is not true for session + # implementations that use external storage for keeping their keys/values. + flashes = session.get("_flashes", []) + flashes.append((category, message)) + session["_flashes"] = flashes + message_flashed.send( + current_app._get_current_object(), # type: ignore + message=message, + category=category, + ) + + +def get_flashed_messages( + with_categories: bool = False, category_filter: t.Iterable[str] = () +) -> t.Union[t.List[str], t.List[t.Tuple[str, str]]]: + """Pulls all flashed messages from the session and returns them. + Further calls in the same request to the function will return + the same messages. By default just the messages are returned, + but when `with_categories` is set to ``True``, the return value will + be a list of tuples in the form ``(category, message)`` instead. + + Filter the flashed messages to one or more categories by providing those + categories in `category_filter`. This allows rendering categories in + separate html blocks. The `with_categories` and `category_filter` + arguments are distinct: + + * `with_categories` controls whether categories are returned with message + text (``True`` gives a tuple, where ``False`` gives just the message text). + * `category_filter` filters the messages down to only those matching the + provided categories. + + See :doc:`/patterns/flashing` for examples. + + .. versionchanged:: 0.3 + `with_categories` parameter added. + + .. versionchanged:: 0.9 + `category_filter` parameter added. + + :param with_categories: set to ``True`` to also receive categories. + :param category_filter: filter of categories to limit return values. Only + categories in the list will be returned. + """ + flashes = _request_ctx_stack.top.flashes + if flashes is None: + _request_ctx_stack.top.flashes = flashes = ( + session.pop("_flashes") if "_flashes" in session else [] + ) + 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( + download_name: t.Optional[str] = None, + attachment_filename: t.Optional[str] = None, + etag: t.Optional[t.Union[bool, str]] = None, + add_etags: t.Optional[t.Union[bool]] = None, + max_age: t.Optional[ + t.Union[int, t.Callable[[t.Optional[str]], t.Optional[int]]] + ] = None, + cache_timeout: t.Optional[int] = None, + **kwargs: t.Any, +) -> t.Dict[str, t.Any]: + if attachment_filename is not None: + warnings.warn( + "The 'attachment_filename' parameter has been renamed to" + " 'download_name'. The old name will be removed in Flask" + " 2.1.", + DeprecationWarning, + stacklevel=3, + ) + download_name = attachment_filename + + if cache_timeout is not None: + warnings.warn( + "The 'cache_timeout' parameter has been renamed to" + " 'max_age'. The old name will be removed in Flask 2.1.", + DeprecationWarning, + stacklevel=3, + ) + max_age = cache_timeout + + if add_etags is not None: + warnings.warn( + "The 'add_etags' parameter has been renamed to 'etag'. The" + " old name will be removed in Flask 2.1.", + DeprecationWarning, + stacklevel=3, + ) + etag = add_etags + + if max_age is None: + max_age = current_app.get_send_file_max_age + + kwargs.update( + environ=request.environ, + download_name=download_name, + etag=etag, + max_age=max_age, + use_x_sendfile=current_app.use_x_sendfile, + response_class=current_app.response_class, + _root_path=current_app.root_path, # type: ignore + ) + return kwargs + + +def send_file( + path_or_file: t.Union[os.PathLike, str, t.BinaryIO], + mimetype: t.Optional[str] = None, + as_attachment: bool = False, + download_name: t.Optional[str] = None, + attachment_filename: t.Optional[str] = None, + conditional: bool = True, + etag: t.Union[bool, str] = True, + add_etags: t.Optional[bool] = None, + last_modified: t.Optional[t.Union[datetime, int, float]] = None, + max_age: t.Optional[ + t.Union[int, t.Callable[[t.Optional[str]], t.Optional[int]]] + ] = None, + cache_timeout: t.Optional[int] = None, +): + """Send the contents of a file to the client. + + The first argument can be a file path or a file-like object. Paths + are preferred in most cases because Werkzeug can manage the file and + get extra information from the path. Passing a file-like object + requires that the file is opened in binary mode, and is mostly + useful when building a file in memory with :class:`io.BytesIO`. + + Never pass file paths provided by a user. The path is assumed to be + trusted, so a user could craft a path to access a file you didn't + intend. Use :func:`send_from_directory` to safely serve + user-requested paths from within a directory. + + If the WSGI server sets a ``file_wrapper`` in ``environ``, it is + used, otherwise Werkzeug's built-in wrapper is used. Alternatively, + if the HTTP server supports ``X-Sendfile``, configuring Flask with + ``USE_X_SENDFILE = True`` will tell the server to send the given + path, which is much more efficient than reading it in Python. + + :param path_or_file: The path to the file to send, relative to the + current working directory if a relative path is given. + Alternatively, a file-like object opened in binary mode. Make + sure the file pointer is seeked to the start of the data. + :param mimetype: The MIME type to send for the file. If not + provided, it will try to detect it from the file name. + :param as_attachment: Indicate to a browser that it should offer to + save the file instead of displaying it. + :param download_name: The default name browsers will use when saving + the file. Defaults to the passed file name. + :param conditional: Enable conditional and range responses based on + request headers. Requires passing a file path and ``environ``. + :param etag: Calculate an ETag for the file, which requires passing + a file path. Can also be a string to use instead. + :param last_modified: The last modified time to send for the file, + in seconds. If not provided, it will try to detect it from the + file path. + :param max_age: How long the client should cache the file, in + seconds. If set, ``Cache-Control`` will be ``public``, otherwise + it will be ``no-cache`` to prefer conditional caching. + + .. versionchanged:: 2.0 + ``download_name`` replaces the ``attachment_filename`` + parameter. If ``as_attachment=False``, it is passed with + ``Content-Disposition: inline`` instead. + + .. versionchanged:: 2.0 + ``max_age`` replaces the ``cache_timeout`` parameter. + ``conditional`` is enabled and ``max_age`` is not set by + default. + + .. versionchanged:: 2.0 + ``etag`` replaces the ``add_etags`` parameter. It can be a + string to use instead of generating one. + + .. versionchanged:: 2.0 + Passing a file-like object that inherits from + :class:`~io.TextIOBase` will raise a :exc:`ValueError` rather + than sending an empty file. + + .. versionadded:: 2.0 + Moved the implementation to Werkzeug. This is now a wrapper to + pass some Flask-specific arguments. + + .. versionchanged:: 1.1 + ``filename`` may be a :class:`~os.PathLike` object. + + .. versionchanged:: 1.1 + Passing a :class:`~io.BytesIO` object supports range requests. + + .. versionchanged:: 1.0.3 + Filenames are encoded with ASCII instead of Latin-1 for broader + compatibility with WSGI servers. + + .. versionchanged:: 1.0 + UTF-8 filenames as specified in :rfc:`2231` are supported. + + .. versionchanged:: 0.12 + The filename is no longer automatically inferred from file + objects. If you want to use automatic MIME and etag support, + pass a filename via ``filename_or_fp`` or + ``attachment_filename``. + + .. versionchanged:: 0.12 + ``attachment_filename`` is preferred over ``filename`` for MIME + detection. + + .. versionchanged:: 0.9 + ``cache_timeout`` defaults to + :meth:`Flask.get_send_file_max_age`. + + .. versionchanged:: 0.7 + MIME guessing and etag support for file-like objects was + deprecated because it was unreliable. Pass a filename if you are + able to, otherwise attach an etag yourself. + + .. versionchanged:: 0.5 + The ``add_etags``, ``cache_timeout`` and ``conditional`` + parameters were added. The default behavior is to add etags. + + .. versionadded:: 0.2 + """ + return werkzeug.utils.send_file( + **_prepare_send_file_kwargs( + path_or_file=path_or_file, + environ=request.environ, + mimetype=mimetype, + as_attachment=as_attachment, + download_name=download_name, + attachment_filename=attachment_filename, + conditional=conditional, + etag=etag, + add_etags=add_etags, + last_modified=last_modified, + max_age=max_age, + cache_timeout=cache_timeout, + ) + ) + + +def safe_join(directory: str, *pathnames: str) -> str: + """Safely join zero or more untrusted path components to a base + directory to avoid escaping the base directory. + + :param directory: The trusted base directory. + :param pathnames: The untrusted path components relative to the + base directory. + :return: A safe path, otherwise ``None``. + """ + warnings.warn( + "'flask.helpers.safe_join' is deprecated and will be removed in" + " Flask 2.1. Use 'werkzeug.utils.safe_join' instead.", + DeprecationWarning, + stacklevel=2, + ) + path = werkzeug.utils.safe_join(directory, *pathnames) + + if path is None: + raise NotFound() + + return path + + +def send_from_directory( + directory: t.Union[os.PathLike, str], + path: t.Union[os.PathLike, str], + filename: t.Optional[str] = None, + **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. + :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 + """ + if filename is not None: + warnings.warn( + "The 'filename' parameter has been renamed to 'path'. The" + " old name will be removed in Flask 2.1.", + DeprecationWarning, + stacklevel=2, + ) + path = filename + + return werkzeug.utils.send_from_directory( # type: ignore + 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__"): + return os.path.dirname(os.path.abspath(mod.__file__)) + + # Next attempt: check the loader. + loader = pkgutil.get_loader(import_name) + + # Loader does not exist or we're referring to an unloaded main + # module or a main module without path (interactive sessions), go + # with the current working directory. + if loader is None or import_name == "__main__": + return os.getcwd() + + if hasattr(loader, "get_filename"): + filepath = loader.get_filename(import_name) # type: ignore + else: + # Fall back to imports. + __import__(import_name) + mod = sys.modules[import_name] + filepath = getattr(mod, "__file__", None) + + # If we don't have a file path it might be because it is a + # namespace package. In this case pick the root path from the + # first module that is contained in the package. + if filepath is None: + raise RuntimeError( + "No root path can be found for the provided module" + f" {import_name!r}. This can happen because the module" + " came from an import hook that does not provide file" + " name information or because it's a namespace package." + " In this case the root path needs to be explicitly" + " provided." + ) + + # filepath is import_name.py for a module, or __init__.py for a package. + return os.path.dirname(os.path.abspath(filepath)) + + +class locked_cached_property(werkzeug.utils.cached_property): + """A :func:`property` that is only evaluated once. Like + :class:`werkzeug.utils.cached_property` except access uses a lock + for thread safety. + + .. versionchanged:: 2.0 + Inherits from Werkzeug's ``cached_property`` (and ``property``). + """ + + def __init__( + self, + fget: t.Callable[[t.Any], t.Any], + name: t.Optional[str] = None, + doc: t.Optional[str] = None, + ) -> None: + super().__init__(fget, name=name, doc=doc) + self.lock = RLock() + + def __get__(self, obj: object, type: type = None) -> t.Any: # type: ignore + if obj is None: + return self + + with self.lock: + return super().__get__(obj, type=type) + + def __set__(self, obj: object, value: t.Any) -> None: + with self.lock: + super().__set__(obj, value) + + def __delete__(self, obj: object) -> None: + with self.lock: + super().__delete__(obj) + + +def total_seconds(td: timedelta) -> int: + """Returns the total seconds from a timedelta object. + + :param timedelta td: the timedelta to be converted in seconds + + :returns: number of seconds + :rtype: int + + .. deprecated:: 2.0 + Will be removed in Flask 2.1. Use + :meth:`timedelta.total_seconds` instead. + """ + warnings.warn( + "'total_seconds' is deprecated and will be removed in Flask" + " 2.1. Use 'timedelta.total_seconds' instead.", + DeprecationWarning, + stacklevel=2, + ) + return td.days * 60 * 60 * 24 + td.seconds + + +def is_ip(value: str) -> bool: + """Determine if the given string is an IP address. + + :param value: value to check + :type value: str + + :return: True if string is an IP address + :rtype: bool + """ + for family in (socket.AF_INET, socket.AF_INET6): + try: + socket.inet_pton(family, value) + except OSError: + pass + else: + return True + + return False + + +@lru_cache(maxsize=None) +def _split_blueprint_path(name: str) -> t.List[str]: + out: t.List[str] = [name] + + if "." in name: + out.extend(_split_blueprint_path(name.rpartition(".")[0])) + + return out diff --git a/venv/lib/python3.9/site-packages/flask/json/__init__.py b/venv/lib/python3.9/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..5780e20 --- /dev/null +++ b/venv/lib/python3.9/site-packages/flask/json/__init__.py @@ -0,0 +1,350 @@ +import io +import json as _json +import typing as t +import uuid +import warnings +from datetime import date + +from jinja2.utils import htmlsafe_json_dumps as _jinja_htmlsafe_dumps +from werkzeug.http import http_date + +from ..globals import current_app +from ..globals import request + +if t.TYPE_CHECKING: + from ..app import Flask + from ..wrappers import Response + +try: + import dataclasses +except ImportError: + # Python < 3.7 + dataclasses = None # type: ignore + + +class JSONEncoder(_json.JSONEncoder): + """The default JSON encoder. Handles extra types compared to the + built-in :class:`json.JSONEncoder`. + + - :class:`datetime.datetime` and :class:`datetime.date` are + serialized to :rfc:`822` strings. This is the same as the HTTP + date format. + - :class:`uuid.UUID` is serialized to a string. + - :class:`dataclasses.dataclass` is passed to + :func:`dataclasses.asdict`. + - :class:`~markupsafe.Markup` (or any object with a ``__html__`` + method) will call the ``__html__`` method to get a string. + + Assign a subclass of this to :attr:`flask.Flask.json_encoder` or + :attr:`flask.Blueprint.json_encoder` to override the default. + """ + + def default(self, o: t.Any) -> t.Any: + """Convert ``o`` to a JSON serializable type. See + :meth:`json.JSONEncoder.default`. Python does not support + overriding how basic types like ``str`` or ``list`` are + serialized, they are handled before this method. + """ + if isinstance(o, date): + return http_date(o) + if isinstance(o, uuid.UUID): + return str(o) + if dataclasses and dataclasses.is_dataclass(o): + return dataclasses.asdict(o) + if hasattr(o, "__html__"): + return str(o.__html__()) + return super().default(o) + + +class JSONDecoder(_json.JSONDecoder): + """The default JSON decoder. + + This does not change any behavior from the built-in + :class:`json.JSONDecoder`. + + Assign a subclass of this to :attr:`flask.Flask.json_decoder` or + :attr:`flask.Blueprint.json_decoder` to override the default. + """ + + +def _dump_arg_defaults( + kwargs: t.Dict[str, t.Any], app: t.Optional["Flask"] = None +) -> None: + """Inject default arguments for dump functions.""" + if app is None: + app = current_app + + if app: + cls = app.json_encoder + bp = app.blueprints.get(request.blueprint) if request else None # type: ignore + if bp is not None and bp.json_encoder is not None: + cls = bp.json_encoder + + kwargs.setdefault("cls", cls) + kwargs.setdefault("ensure_ascii", app.config["JSON_AS_ASCII"]) + kwargs.setdefault("sort_keys", app.config["JSON_SORT_KEYS"]) + else: + kwargs.setdefault("sort_keys", True) + kwargs.setdefault("cls", JSONEncoder) + + +def _load_arg_defaults( + kwargs: t.Dict[str, t.Any], app: t.Optional["Flask"] = None +) -> None: + """Inject default arguments for load functions.""" + if app is None: + app = current_app + + if app: + cls = app.json_decoder + bp = app.blueprints.get(request.blueprint) if request else None # type: ignore + if bp is not None and bp.json_decoder is not None: + cls = bp.json_decoder + + kwargs.setdefault("cls", cls) + else: + kwargs.setdefault("cls", JSONDecoder) + + +def dumps(obj: t.Any, app: t.Optional["Flask"] = None, **kwargs: t.Any) -> str: + """Serialize an object to a string of JSON. + + Takes the same arguments as the built-in :func:`json.dumps`, with + some defaults from application configuration. + + :param obj: Object to serialize to JSON. + :param app: Use this app's config instead of the active app context + or defaults. + :param kwargs: Extra arguments passed to :func:`json.dumps`. + + .. versionchanged:: 2.0 + ``encoding`` is deprecated and will be removed in Flask 2.1. + + .. versionchanged:: 1.0.3 + ``app`` can be passed directly, rather than requiring an app + context for configuration. + """ + _dump_arg_defaults(kwargs, app=app) + encoding = kwargs.pop("encoding", None) + rv = _json.dumps(obj, **kwargs) + + if encoding is not None: + warnings.warn( + "'encoding' is deprecated and will be removed in Flask 2.1.", + DeprecationWarning, + stacklevel=2, + ) + + if isinstance(rv, str): + return rv.encode(encoding) # type: ignore + + return rv + + +def dump( + obj: t.Any, fp: t.IO[str], app: t.Optional["Flask"] = None, **kwargs: t.Any +) -> None: + """Serialize an object to JSON written to a file object. + + Takes the same arguments as the built-in :func:`json.dump`, with + some defaults from application configuration. + + :param obj: Object to serialize to JSON. + :param fp: File object to write JSON to. + :param app: Use this app's config instead of the active app context + or defaults. + :param kwargs: Extra arguments passed to :func:`json.dump`. + + .. versionchanged:: 2.0 + Writing to a binary file, and the ``encoding`` argument, is + deprecated and will be removed in Flask 2.1. + """ + _dump_arg_defaults(kwargs, app=app) + encoding = kwargs.pop("encoding", None) + show_warning = encoding is not None + + try: + fp.write("") + except TypeError: + show_warning = True + fp = io.TextIOWrapper(fp, encoding or "utf-8") # type: ignore + + if show_warning: + warnings.warn( + "Writing to a binary file, and the 'encoding' argument, is" + " deprecated and will be removed in Flask 2.1.", + DeprecationWarning, + stacklevel=2, + ) + + _json.dump(obj, fp, **kwargs) + + +def loads(s: str, app: t.Optional["Flask"] = None, **kwargs: t.Any) -> t.Any: + """Deserialize an object from a string of JSON. + + Takes the same arguments as the built-in :func:`json.loads`, with + some defaults from application configuration. + + :param s: JSON string to deserialize. + :param app: Use this app's config instead of the active app context + or defaults. + :param kwargs: Extra arguments passed to :func:`json.loads`. + + .. versionchanged:: 2.0 + ``encoding`` is deprecated and 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. + """ + _load_arg_defaults(kwargs, app=app) + encoding = kwargs.pop("encoding", None) + + if encoding is not None: + warnings.warn( + "'encoding' is deprecated and will be removed in Flask 2.1." + " The data must be a string or UTF-8 bytes.", + DeprecationWarning, + stacklevel=2, + ) + + if isinstance(s, bytes): + s = s.decode(encoding) + + return _json.loads(s, **kwargs) + + +def load(fp: t.IO[str], app: t.Optional["Flask"] = None, **kwargs: t.Any) -> t.Any: + """Deserialize an object from JSON read from a file object. + + Takes the same arguments as the built-in :func:`json.load`, with + some defaults from application configuration. + + :param fp: File object to read JSON from. + :param app: Use this app's config instead of the active app context + or defaults. + :param kwargs: Extra arguments passed to :func:`json.load`. + + .. versionchanged:: 2.0 + ``encoding`` is deprecated and will be removed in Flask 2.1. The + file must be text mode, or binary mode with UTF-8 bytes. + """ + _load_arg_defaults(kwargs, app=app) + encoding = kwargs.pop("encoding", None) + + if encoding is not None: + warnings.warn( + "'encoding' is deprecated and will be removed in Flask 2.1." + " The file must be text mode, or binary mode with UTF-8" + " bytes.", + DeprecationWarning, + stacklevel=2, + ) + + if isinstance(fp.read(0), bytes): + fp = io.TextIOWrapper(fp, encoding) # type: ignore + + return _json.load(fp, **kwargs) + + +def htmlsafe_dumps(obj: t.Any, **kwargs: t.Any) -> str: + """Serialize an object to a string of JSON with :func:`dumps`, then + replace HTML-unsafe characters with Unicode escapes and mark the + result safe with :class:`~markupsafe.Markup`. + + This is available in templates as the ``|tojson`` filter. + + The returned string is safe to render in HTML documents and + `` + + + +

+ +
+
+

Console Locked

+

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

+

PIN: + + +

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

%(exception_type)s

+
+

%(exception)s

+
+

Traceback (most recent call last)

+%(summary)s +
+

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

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

Interactive Console

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

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

+
%(lines)s
+
+""" + +SOURCE_LINE_HTML = """\ + + %(lineno)s + %(code)s + +""" + + +def render_console_html(secret: str, evalex_trusted: bool = True) -> str: + return CONSOLE_HTML % { + "evalex": "true", + "evalex_trusted": "true" if evalex_trusted else "false", + "console": "true", + "title": "Console", + "secret": secret, + "traceback_id": -1, + } + + +def get_current_traceback( + ignore_system_exceptions: bool = False, + show_hidden_frames: bool = False, + skip: int = 0, +) -> "Traceback": + """Get the current exception info as `Traceback` object. Per default + calling this method will reraise system exceptions such as generator exit, + system exit or others. This behavior can be disabled by passing `False` + to the function as first parameter. + """ + info = t.cast( + t.Tuple[t.Type[BaseException], BaseException, TracebackType], sys.exc_info() + ) + exc_type, exc_value, tb = info + + if ignore_system_exceptions and exc_type in { + SystemExit, + KeyboardInterrupt, + GeneratorExit, + }: + raise + for _ in range(skip): + if tb.tb_next is None: + break + tb = tb.tb_next + tb = Traceback(exc_type, exc_value, tb) + if not show_hidden_frames: + tb.filter_hidden_frames() + return tb + + +class Line: + """Helper for the source renderer.""" + + __slots__ = ("lineno", "code", "in_frame", "current") + + def __init__(self, lineno: int, code: str) -> None: + self.lineno = lineno + self.code = code + self.in_frame = False + self.current = False + + @property + def classes(self) -> t.List[str]: + rv = ["line"] + if self.in_frame: + rv.append("in-frame") + if self.current: + rv.append("current") + return rv + + def render(self) -> str: + return SOURCE_LINE_HTML % { + "classes": " ".join(self.classes), + "lineno": self.lineno, + "code": escape(self.code), + } + + +class Traceback: + """Wraps a traceback.""" + + def __init__( + self, + exc_type: t.Type[BaseException], + exc_value: BaseException, + tb: TracebackType, + ) -> None: + self.exc_type = exc_type + self.exc_value = exc_value + self.tb = tb + + exception_type = exc_type.__name__ + if exc_type.__module__ not in {"builtins", "__builtin__", "exceptions"}: + exception_type = f"{exc_type.__module__}.{exception_type}" + self.exception_type = exception_type + + self.groups = [] + memo = set() + while True: + self.groups.append(Group(exc_type, exc_value, tb)) + memo.add(id(exc_value)) + exc_value = exc_value.__cause__ or exc_value.__context__ # type: ignore + if exc_value is None or id(exc_value) in memo: + break + exc_type = type(exc_value) + tb = exc_value.__traceback__ # type: ignore + self.groups.reverse() + self.frames = [frame for group in self.groups for frame in group.frames] + + def filter_hidden_frames(self) -> None: + """Remove the frames according to the paste spec.""" + for group in self.groups: + group.filter_hidden_frames() + + self.frames[:] = [frame for group in self.groups for frame in group.frames] + + @property + def is_syntax_error(self) -> bool: + """Is it a syntax error?""" + return isinstance(self.exc_value, SyntaxError) + + @property + def exception(self) -> str: + """String representation of the final exception.""" + return self.groups[-1].exception + + def log(self, logfile: t.Optional[t.TextIO] = None) -> None: + """Log the ASCII traceback into a file object.""" + if logfile is None: + logfile = sys.stderr + tb = f"{self.plaintext.rstrip()}\n" + logfile.write(tb) + + def render_summary(self, include_title: bool = True) -> str: + """Render the traceback for the interactive console.""" + title = "" + classes = ["traceback"] + if not self.frames: + classes.append("noframe-traceback") + frames = [] + else: + library_frames = sum(frame.is_library for frame in self.frames) + mark_lib = 0 < library_frames < len(self.frames) + frames = [group.render(mark_lib=mark_lib) for group in self.groups] + + if include_title: + if self.is_syntax_error: + title = "Syntax Error" + else: + title = "Traceback (most recent call last):" + + if self.is_syntax_error: + description = f"
{escape(self.exception)}
" + else: + description = f"
{escape(self.exception)}
" + + return SUMMARY_HTML % { + "classes": " ".join(classes), + "title": f"

{title if title else ''}

", + "frames": "\n".join(frames), + "description": description, + } + + def render_full( + self, + evalex: bool = False, + secret: t.Optional[str] = None, + evalex_trusted: bool = True, + ) -> str: + """Render the Full HTML page with the traceback info.""" + exc = escape(self.exception) + return PAGE_HTML % { + "evalex": "true" if evalex else "false", + "evalex_trusted": "true" if evalex_trusted else "false", + "console": "false", + "title": exc, + "exception": exc, + "exception_type": escape(self.exception_type), + "summary": self.render_summary(include_title=False), + "plaintext": escape(self.plaintext), + "plaintext_cs": re.sub("-{2,}", "-", self.plaintext), + "traceback_id": self.id, + "secret": secret, + } + + @cached_property + def plaintext(self) -> str: + return "\n".join([group.render_text() for group in self.groups]) + + @property + def id(self) -> int: + return id(self) + + +class Group: + """A group of frames for an exception in a traceback. If the + exception has a ``__cause__`` or ``__context__``, there are multiple + exception groups. + """ + + def __init__( + self, + exc_type: t.Type[BaseException], + exc_value: BaseException, + tb: TracebackType, + ) -> None: + self.exc_type = exc_type + self.exc_value = exc_value + self.info = None + if exc_value.__cause__ is not None: + self.info = ( + "The above exception was the direct cause of the following exception" + ) + elif exc_value.__context__ is not None: + self.info = ( + "During handling of the above exception, another exception occurred" + ) + + self.frames = [] + while tb is not None: + self.frames.append(Frame(exc_type, exc_value, tb)) + tb = tb.tb_next # type: ignore + + def filter_hidden_frames(self) -> None: + new_frames: t.List[Frame] = [] + hidden = False + + for frame in self.frames: + hide = frame.hide + if hide in ("before", "before_and_this"): + new_frames = [] + hidden = False + if hide == "before_and_this": + continue + elif hide in ("reset", "reset_and_this"): + hidden = False + if hide == "reset_and_this": + continue + elif hide in ("after", "after_and_this"): + hidden = True + if hide == "after_and_this": + continue + elif hide or hidden: + continue + new_frames.append(frame) + + # if we only have one frame and that frame is from the codeop + # module, remove it. + if len(new_frames) == 1 and self.frames[0].module == "codeop": + del self.frames[:] + + # if the last frame is missing something went terrible wrong :( + elif self.frames[-1] in new_frames: + self.frames[:] = new_frames + + @property + def exception(self) -> str: + """String representation of the exception.""" + buf = traceback.format_exception_only(self.exc_type, self.exc_value) + rv = "".join(buf).strip() + return _to_str(rv, "utf-8", "replace") + + def render(self, mark_lib: bool = True) -> str: + out = [] + if self.info is not None: + out.append(f'
  • {self.info}:
    ') + for frame in self.frames: + title = f' title="{escape(frame.info)}"' if frame.info else "" + out.append(f"{frame.render(mark_lib=mark_lib)}") + return "\n".join(out) + + def render_text(self) -> str: + out = [] + if self.info is not None: + out.append(f"\n{self.info}:\n") + out.append("Traceback (most recent call last):") + for frame in self.frames: + out.append(frame.render_text()) + out.append(self.exception) + return "\n".join(out) + + +class Frame: + """A single frame in a traceback.""" + + def __init__( + self, + exc_type: t.Type[BaseException], + exc_value: BaseException, + tb: TracebackType, + ) -> None: + self.lineno = tb.tb_lineno + self.function_name = tb.tb_frame.f_code.co_name + self.locals = tb.tb_frame.f_locals + self.globals = tb.tb_frame.f_globals + + fn = inspect.getsourcefile(tb) or inspect.getfile(tb) + if fn[-4:] in (".pyo", ".pyc"): + fn = fn[:-1] + # if it's a file on the file system resolve the real filename. + if os.path.isfile(fn): + fn = os.path.realpath(fn) + self.filename = _to_str(fn, get_filesystem_encoding()) + self.module = self.globals.get("__name__", self.locals.get("__name__")) + self.loader = self.globals.get("__loader__", self.locals.get("__loader__")) + self.code = tb.tb_frame.f_code + + # support for paste's traceback extensions + self.hide = self.locals.get("__traceback_hide__", False) + info = self.locals.get("__traceback_info__") + if info is not None: + info = _to_str(info, "utf-8", "replace") + self.info = info + + def render(self, mark_lib: bool = True) -> str: + """Render a single frame in a traceback.""" + return FRAME_HTML % { + "id": self.id, + "filename": escape(self.filename), + "lineno": self.lineno, + "function_name": escape(self.function_name), + "lines": self.render_line_context(), + "library": "library" if mark_lib and self.is_library else "", + } + + @cached_property + def is_library(self) -> bool: + return any( + self.filename.startswith(os.path.realpath(path)) + for path in sysconfig.get_paths().values() + ) + + def render_text(self) -> str: + return ( + f' File "{self.filename}", line {self.lineno}, in {self.function_name}\n' + f" {self.current_line.strip()}" + ) + + def render_line_context(self) -> str: + before, current, after = self.get_context_lines() + rv = [] + + def render_line(line: str, cls: str) -> None: + line = line.expandtabs().rstrip() + stripped_line = line.strip() + prefix = len(line) - len(stripped_line) + rv.append( + f'
    {" " * prefix}'
    +                f"{escape(stripped_line) if stripped_line else ' '}
    " + ) + + for line in before: + render_line(line, "before") + render_line(current, "current") + for line in after: + render_line(line, "after") + + return "\n".join(rv) + + def get_annotated_lines(self) -> t.List[Line]: + """Helper function that returns lines with extra information.""" + lines = [Line(idx + 1, x) for idx, x in enumerate(self.sourcelines)] + + # find function definition and mark lines + if hasattr(self.code, "co_firstlineno"): + lineno = self.code.co_firstlineno - 1 + while lineno > 0: + if _funcdef_re.match(lines[lineno].code): + break + lineno -= 1 + try: + offset = len(inspect.getblock([f"{x.code}\n" for x in lines[lineno:]])) + except TokenError: + offset = 0 + for line in lines[lineno : lineno + offset]: + line.in_frame = True + + # mark current line + try: + lines[self.lineno - 1].current = True + except IndexError: + pass + + return lines + + def eval(self, code: t.Union[str, CodeType], mode: str = "single") -> t.Any: + """Evaluate code in the context of the frame.""" + if isinstance(code, str): + code = compile(code, "", mode) + return eval(code, self.globals, self.locals) + + @cached_property + def sourcelines(self) -> t.List[str]: + """The sourcecode of the file as list of strings.""" + # get sourcecode from loader or file + source = None + if self.loader is not None: + try: + if hasattr(self.loader, "get_source"): + source = self.loader.get_source(self.module) + elif hasattr(self.loader, "get_source_by_code"): + source = self.loader.get_source_by_code(self.code) + except Exception: + # we munch the exception so that we don't cause troubles + # if the loader is broken. + pass + + if source is None: + try: + with open(self.filename, mode="rb") as f: + source = f.read() + except OSError: + return [] + + # already str? return right away + if isinstance(source, str): + return source.splitlines() + + charset = "utf-8" + if source.startswith(codecs.BOM_UTF8): + source = source[3:] + else: + for idx, match in enumerate(_line_re.finditer(source)): + coding_match = _coding_re.search(match.group()) + if coding_match is not None: + charset = coding_match.group(1).decode("utf-8") + break + if idx > 1: + break + + # on broken cookies we fall back to utf-8 too + charset = _to_str(charset) + try: + codecs.lookup(charset) + except LookupError: + charset = "utf-8" + + return source.decode(charset, "replace").splitlines() + + def get_context_lines( + self, context: int = 5 + ) -> t.Tuple[t.List[str], str, t.List[str]]: + before = self.sourcelines[self.lineno - context - 1 : self.lineno - 1] + past = self.sourcelines[self.lineno : self.lineno + context] + return (before, self.current_line, past) + + @property + def current_line(self) -> str: + try: + return self.sourcelines[self.lineno - 1] + except IndexError: + return "" + + @cached_property + def console(self) -> Console: + return Console(self.globals, self.locals) + + @property + def id(self) -> int: + return id(self) diff --git a/venv/lib/python3.9/site-packages/werkzeug/exceptions.py b/venv/lib/python3.9/site-packages/werkzeug/exceptions.py new file mode 100644 index 0000000..16c3964 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/exceptions.py @@ -0,0 +1,943 @@ +"""Implements a number of Python exceptions which can be raised from within +a view to trigger a standard HTTP non-200 response. + +Usage Example +------------- + +.. code-block:: python + + from werkzeug.wrappers.request import Request + from werkzeug.exceptions import HTTPException, NotFound + + def view(request): + raise NotFound() + + @Request.application + def application(request): + try: + return view(request) + except HTTPException as e: + return e + +As you can see from this example those exceptions are callable WSGI +applications. However, they are not Werkzeug response objects. You +can get a response object by calling ``get_response()`` on a HTTP +exception. + +Keep in mind that you may have to pass an environ (WSGI) or scope +(ASGI) to ``get_response()`` because some errors fetch additional +information relating to the request. + +If you want to hook in a different exception page to say, a 404 status +code, you can add a second except for a specific subclass of an error: + +.. code-block:: python + + @Request.application + def application(request): + try: + return view(request) + except NotFound as e: + return not_found(request) + except HTTPException as e: + return e + +""" +import sys +import typing as t +import warnings +from datetime import datetime +from html import escape + +from ._internal import _get_environ + +if t.TYPE_CHECKING: + import typing_extensions as te + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIEnvironment + from .datastructures import WWWAuthenticate + from .sansio.response import Response + from .wrappers.response import Response as WSGIResponse # noqa: F401 + + +class HTTPException(Exception): + """The base class for all HTTP exceptions. This exception can be called as a WSGI + application to render a default error page or you can catch the subclasses + of it independently and render nicer error messages. + """ + + code: t.Optional[int] = None + description: t.Optional[str] = None + + def __init__( + self, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + ) -> None: + super().__init__() + if description is not None: + self.description = description + self.response = response + + @classmethod + def wrap( + cls, exception: t.Type[BaseException], name: t.Optional[str] = None + ) -> t.Type["HTTPException"]: + """Create an exception that is a subclass of the calling HTTP + exception and the ``exception`` argument. + + The first argument to the class will be passed to the + wrapped ``exception``, the rest to the HTTP exception. If + ``e.args`` is not empty and ``e.show_exception`` is ``True``, + the wrapped exception message is added to the HTTP error + description. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Create a subclass manually + instead. + + .. versionchanged:: 0.15.5 + The ``show_exception`` attribute controls whether the + description includes the wrapped exception message. + + .. versionchanged:: 0.15.0 + The description includes the wrapped exception message. + """ + warnings.warn( + "'HTTPException.wrap' is deprecated and will be removed in" + " Werkzeug 2.1. Create a subclass manually instead.", + DeprecationWarning, + stacklevel=2, + ) + + class newcls(cls, exception): # type: ignore + _description = cls.description + show_exception = False + + def __init__( + self, arg: t.Optional[t.Any] = None, *args: t.Any, **kwargs: t.Any + ) -> None: + super().__init__(*args, **kwargs) + + if arg is None: + exception.__init__(self) + else: + exception.__init__(self, arg) + + @property + def description(self) -> str: + if self.show_exception: + return ( + f"{self._description}\n" + f"{exception.__name__}: {exception.__str__(self)}" + ) + + return self._description # type: ignore + + @description.setter + def description(self, value: str) -> None: + self._description = value + + newcls.__module__ = sys._getframe(1).f_globals["__name__"] + name = name or cls.__name__ + exception.__name__ + newcls.__name__ = newcls.__qualname__ = name + return newcls + + @property + def name(self) -> str: + """The status name.""" + from .http import HTTP_STATUS_CODES + + return HTTP_STATUS_CODES.get(self.code, "Unknown Error") # type: ignore + + def get_description( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> str: + """Get the description.""" + if self.description is None: + description = "" + elif not isinstance(self.description, str): + description = str(self.description) + else: + description = self.description + + description = escape(description).replace("\n", "
    ") + return f"

    {description}

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

    {escape(self.name)}

    \n" + f"{self.get_description(environ)}\n" + ) + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + """Get a list of headers.""" + return [("Content-Type", "text/html; charset=utf-8")] + + def get_response( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> "Response": + """Get a response object. If one was passed to the exception + it's returned directly. + + :param environ: the optional environ for the request. This + can be used to modify the response depending + on how the request looked like. + :return: a :class:`Response` object or a subclass thereof. + """ + from .wrappers.response import Response as WSGIResponse # noqa: F811 + + if self.response is not None: + return self.response + if environ is not None: + environ = _get_environ(environ) + headers = self.get_headers(environ, scope) + return WSGIResponse(self.get_body(environ, scope), self.code, headers) + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + """Call the exception as WSGI application. + + :param environ: the WSGI environment. + :param start_response: the response callable provided by the WSGI + server. + """ + response = t.cast("WSGIResponse", self.get_response(environ)) + return response(environ, start_response) + + def __str__(self) -> str: + code = self.code if self.code is not None else "???" + return f"{code} {self.name}: {self.description}" + + def __repr__(self) -> str: + code = self.code if self.code is not None else "???" + return f"<{type(self).__name__} '{code}: {self.name}'>" + + +class BadRequest(HTTPException): + """*400* `Bad Request` + + Raise if the browser sends something to the application the application + or server cannot handle. + """ + + code = 400 + description = ( + "The browser (or proxy) sent a request that this server could " + "not understand." + ) + + +class BadRequestKeyError(BadRequest, KeyError): + """An exception that is used to signal both a :exc:`KeyError` and a + :exc:`BadRequest`. Used by many of the datastructures. + """ + + _description = BadRequest.description + #: Show the KeyError along with the HTTP error message in the + #: response. This should be disabled in production, but can be + #: useful in a debug mode. + show_exception = False + + def __init__(self, arg: t.Optional[str] = None, *args: t.Any, **kwargs: t.Any): + super().__init__(*args, **kwargs) + + if arg is None: + KeyError.__init__(self) + else: + KeyError.__init__(self, arg) + + @property # type: ignore + def description(self) -> str: # type: ignore + if self.show_exception: + return ( + f"{self._description}\n" + f"{KeyError.__name__}: {KeyError.__str__(self)}" + ) + + return self._description + + @description.setter + def description(self, value: str) -> None: + self._description = value + + +class ClientDisconnected(BadRequest): + """Internal exception that is raised if Werkzeug detects a disconnected + client. Since the client is already gone at that point attempting to + send the error message to the client might not work and might ultimately + result in another exception in the server. Mainly this is here so that + it is silenced by default as far as Werkzeug is concerned. + + Since disconnections cannot be reliably detected and are unspecified + by WSGI to a large extent this might or might not be raised if a client + is gone. + + .. versionadded:: 0.8 + """ + + +class SecurityError(BadRequest): + """Raised if something triggers a security error. This is otherwise + exactly like a bad request error. + + .. versionadded:: 0.9 + """ + + +class BadHost(BadRequest): + """Raised if the submitted host is badly formatted. + + .. versionadded:: 0.11.2 + """ + + +class Unauthorized(HTTPException): + """*401* ``Unauthorized`` + + Raise if the user is not authorized to access a resource. + + The ``www_authenticate`` argument should be used to set the + ``WWW-Authenticate`` header. This is used for HTTP basic auth and + other schemes. Use :class:`~werkzeug.datastructures.WWWAuthenticate` + to create correctly formatted values. Strictly speaking a 401 + response is invalid if it doesn't provide at least one value for + this header, although real clients typically don't care. + + :param description: Override the default message used for the body + of the response. + :param www-authenticate: A single value, or list of values, for the + WWW-Authenticate header(s). + + .. versionchanged:: 2.0 + Serialize multiple ``www_authenticate`` items into multiple + ``WWW-Authenticate`` headers, rather than joining them + into a single value, for better interoperability. + + .. versionchanged:: 0.15.3 + If the ``www_authenticate`` argument is not set, the + ``WWW-Authenticate`` header is not set. + + .. versionchanged:: 0.15.3 + The ``response`` argument was restored. + + .. versionchanged:: 0.15.1 + ``description`` was moved back as the first argument, restoring + its previous position. + + .. versionchanged:: 0.15.0 + ``www_authenticate`` was added as the first argument, ahead of + ``description``. + """ + + code = 401 + description = ( + "The server could not verify that you are authorized to access" + " the URL requested. You either supplied the wrong credentials" + " (e.g. a bad password), or your browser doesn't understand" + " how to supply the credentials required." + ) + + def __init__( + self, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + www_authenticate: t.Optional[ + t.Union["WWWAuthenticate", t.Iterable["WWWAuthenticate"]] + ] = None, + ) -> None: + super().__init__(description, response) + + from .datastructures import WWWAuthenticate + + if isinstance(www_authenticate, WWWAuthenticate): + www_authenticate = (www_authenticate,) + + self.www_authenticate = www_authenticate + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + headers = super().get_headers(environ, scope) + if self.www_authenticate: + headers.extend(("WWW-Authenticate", str(x)) for x in self.www_authenticate) + return headers + + +class Forbidden(HTTPException): + """*403* `Forbidden` + + Raise if the user doesn't have the permission for the requested resource + but was authenticated. + """ + + code = 403 + description = ( + "You don't have the permission to access the requested" + " resource. It is either read-protected or not readable by the" + " server." + ) + + +class NotFound(HTTPException): + """*404* `Not Found` + + Raise if a resource does not exist and never existed. + """ + + code = 404 + description = ( + "The requested URL was not found on the server. If you entered" + " the URL manually please check your spelling and try again." + ) + + +class MethodNotAllowed(HTTPException): + """*405* `Method Not Allowed` + + Raise if the server used a method the resource does not handle. For + example `POST` if the resource is view only. Especially useful for REST. + + The first argument for this exception should be a list of allowed methods. + Strictly speaking the response would be invalid if you don't provide valid + methods in the header which you can do with that list. + """ + + code = 405 + description = "The method is not allowed for the requested URL." + + def __init__( + self, + valid_methods: t.Optional[t.Iterable[str]] = None, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + ) -> None: + """Takes an optional list of valid http methods + starting with werkzeug 0.3 the list will be mandatory.""" + super().__init__(description=description, response=response) + self.valid_methods = valid_methods + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + headers = super().get_headers(environ, scope) + if self.valid_methods: + headers.append(("Allow", ", ".join(self.valid_methods))) + return headers + + +class NotAcceptable(HTTPException): + """*406* `Not Acceptable` + + Raise if the server can't return any content conforming to the + `Accept` headers of the client. + """ + + code = 406 + description = ( + "The resource identified by the request is only capable of" + " generating response entities which have content" + " characteristics not acceptable according to the accept" + " headers sent in the request." + ) + + +class RequestTimeout(HTTPException): + """*408* `Request Timeout` + + Raise to signalize a timeout. + """ + + code = 408 + description = ( + "The server closed the network connection because the browser" + " didn't finish the request within the specified time." + ) + + +class Conflict(HTTPException): + """*409* `Conflict` + + Raise to signal that a request cannot be completed because it conflicts + with the current state on the server. + + .. versionadded:: 0.7 + """ + + code = 409 + description = ( + "A conflict happened while processing the request. The" + " resource might have been modified while the request was being" + " processed." + ) + + +class Gone(HTTPException): + """*410* `Gone` + + Raise if a resource existed previously and went away without new location. + """ + + code = 410 + description = ( + "The requested URL is no longer available on this server and" + " there is no forwarding address. If you followed a link from a" + " foreign page, please contact the author of this page." + ) + + +class LengthRequired(HTTPException): + """*411* `Length Required` + + Raise if the browser submitted data but no ``Content-Length`` header which + is required for the kind of processing the server does. + """ + + code = 411 + description = ( + "A request with this method requires a valid Content-" + "Length header." + ) + + +class PreconditionFailed(HTTPException): + """*412* `Precondition Failed` + + Status code used in combination with ``If-Match``, ``If-None-Match``, or + ``If-Unmodified-Since``. + """ + + code = 412 + description = ( + "The precondition on the request for the URL failed positive evaluation." + ) + + +class RequestEntityTooLarge(HTTPException): + """*413* `Request Entity Too Large` + + The status code one should return if the data submitted exceeded a given + limit. + """ + + code = 413 + description = "The data value transmitted exceeds the capacity limit." + + +class RequestURITooLarge(HTTPException): + """*414* `Request URI Too Large` + + Like *413* but for too long URLs. + """ + + code = 414 + description = ( + "The length of the requested URL exceeds the capacity limit for" + " this server. The request cannot be processed." + ) + + +class UnsupportedMediaType(HTTPException): + """*415* `Unsupported Media Type` + + The status code returned if the server is unable to handle the media type + the client transmitted. + """ + + code = 415 + description = ( + "The server does not support the media type transmitted in the request." + ) + + +class RequestedRangeNotSatisfiable(HTTPException): + """*416* `Requested Range Not Satisfiable` + + The client asked for an invalid part of the file. + + .. versionadded:: 0.7 + """ + + code = 416 + description = "The server cannot provide the requested range." + + def __init__( + self, + length: t.Optional[int] = None, + units: str = "bytes", + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + ) -> None: + """Takes an optional `Content-Range` header value based on ``length`` + parameter. + """ + super().__init__(description=description, response=response) + self.length = length + self.units = units + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + headers = super().get_headers(environ, scope) + if self.length is not None: + headers.append(("Content-Range", f"{self.units} */{self.length}")) + return headers + + +class ExpectationFailed(HTTPException): + """*417* `Expectation Failed` + + The server cannot meet the requirements of the Expect request-header. + + .. versionadded:: 0.7 + """ + + code = 417 + description = "The server could not meet the requirements of the Expect header" + + +class ImATeapot(HTTPException): + """*418* `I'm a teapot` + + The server should return this if it is a teapot and someone attempted + to brew coffee with it. + + .. versionadded:: 0.7 + """ + + code = 418 + description = "This server is a teapot, not a coffee machine" + + +class UnprocessableEntity(HTTPException): + """*422* `Unprocessable Entity` + + Used if the request is well formed, but the instructions are otherwise + incorrect. + """ + + code = 422 + description = ( + "The request was well-formed but was unable to be followed due" + " to semantic errors." + ) + + +class Locked(HTTPException): + """*423* `Locked` + + Used if the resource that is being accessed is locked. + """ + + code = 423 + description = "The resource that is being accessed is locked." + + +class FailedDependency(HTTPException): + """*424* `Failed Dependency` + + Used if the method could not be performed on the resource + because the requested action depended on another action and that action failed. + """ + + code = 424 + description = ( + "The method could not be performed on the resource because the" + " requested action depended on another action and that action" + " failed." + ) + + +class PreconditionRequired(HTTPException): + """*428* `Precondition Required` + + The server requires this request to be conditional, typically to prevent + the lost update problem, which is a race condition between two or more + clients attempting to update a resource through PUT or DELETE. By requiring + each client to include a conditional header ("If-Match" or "If-Unmodified- + Since") with the proper value retained from a recent GET request, the + server ensures that each client has at least seen the previous revision of + the resource. + """ + + code = 428 + description = ( + "This request is required to be conditional; try using" + ' "If-Match" or "If-Unmodified-Since".' + ) + + +class _RetryAfter(HTTPException): + """Adds an optional ``retry_after`` parameter which will set the + ``Retry-After`` header. May be an :class:`int` number of seconds or + a :class:`~datetime.datetime`. + """ + + def __init__( + self, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + retry_after: t.Optional[t.Union[datetime, int]] = None, + ) -> None: + super().__init__(description, response) + self.retry_after = retry_after + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + headers = super().get_headers(environ, scope) + + if self.retry_after: + if isinstance(self.retry_after, datetime): + from .http import http_date + + value = http_date(self.retry_after) + else: + value = str(self.retry_after) + + headers.append(("Retry-After", value)) + + return headers + + +class TooManyRequests(_RetryAfter): + """*429* `Too Many Requests` + + The server is limiting the rate at which this user receives + responses, and this request exceeds that rate. (The server may use + any convenient method to identify users and their request rates). + The server may include a "Retry-After" header to indicate how long + the user should wait before retrying. + + :param retry_after: If given, set the ``Retry-After`` header to this + value. May be an :class:`int` number of seconds or a + :class:`~datetime.datetime`. + + .. versionchanged:: 1.0 + Added ``retry_after`` parameter. + """ + + code = 429 + description = "This user has exceeded an allotted request count. Try again later." + + +class RequestHeaderFieldsTooLarge(HTTPException): + """*431* `Request Header Fields Too Large` + + The server refuses to process the request because the header fields are too + large. One or more individual fields may be too large, or the set of all + headers is too large. + """ + + code = 431 + description = "One or more header fields exceeds the maximum size." + + +class UnavailableForLegalReasons(HTTPException): + """*451* `Unavailable For Legal Reasons` + + This status code indicates that the server is denying access to the + resource as a consequence of a legal demand. + """ + + code = 451 + description = "Unavailable for legal reasons." + + +class InternalServerError(HTTPException): + """*500* `Internal Server Error` + + Raise if an internal server error occurred. This is a good fallback if an + unknown error occurred in the dispatcher. + + .. versionchanged:: 1.0.0 + Added the :attr:`original_exception` attribute. + """ + + code = 500 + description = ( + "The server encountered an internal error and was unable to" + " complete your request. Either the server is overloaded or" + " there is an error in the application." + ) + + def __init__( + self, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + original_exception: t.Optional[BaseException] = None, + ) -> None: + #: The original exception that caused this 500 error. Can be + #: used by frameworks to provide context when handling + #: unexpected errors. + self.original_exception = original_exception + super().__init__(description=description, response=response) + + +class NotImplemented(HTTPException): + """*501* `Not Implemented` + + Raise if the application does not support the action requested by the + browser. + """ + + code = 501 + description = "The server does not support the action requested by the browser." + + +class BadGateway(HTTPException): + """*502* `Bad Gateway` + + If you do proxying in your application you should return this status code + if you received an invalid response from the upstream server it accessed + in attempting to fulfill the request. + """ + + code = 502 + description = ( + "The proxy server received an invalid response from an upstream server." + ) + + +class ServiceUnavailable(_RetryAfter): + """*503* `Service Unavailable` + + Status code you should return if a service is temporarily + unavailable. + + :param retry_after: If given, set the ``Retry-After`` header to this + value. May be an :class:`int` number of seconds or a + :class:`~datetime.datetime`. + + .. versionchanged:: 1.0 + Added ``retry_after`` parameter. + """ + + code = 503 + description = ( + "The server is temporarily unable to service your request due" + " to maintenance downtime or capacity problems. Please try" + " again later." + ) + + +class GatewayTimeout(HTTPException): + """*504* `Gateway Timeout` + + Status code you should return if a connection to an upstream server + times out. + """ + + code = 504 + description = "The connection to an upstream server timed out." + + +class HTTPVersionNotSupported(HTTPException): + """*505* `HTTP Version Not Supported` + + The server does not support the HTTP protocol version used in the request. + """ + + code = 505 + description = ( + "The server does not support the HTTP protocol version used in the request." + ) + + +default_exceptions: t.Dict[int, t.Type[HTTPException]] = {} + + +def _find_exceptions() -> None: + for obj in globals().values(): + try: + is_http_exception = issubclass(obj, HTTPException) + except TypeError: + is_http_exception = False + if not is_http_exception or obj.code is None: + continue + old_obj = default_exceptions.get(obj.code, None) + if old_obj is not None and issubclass(obj, old_obj): + continue + default_exceptions[obj.code] = obj + + +_find_exceptions() +del _find_exceptions + + +class Aborter: + """When passed a dict of code -> exception items it can be used as + callable that raises exceptions. If the first argument to the + callable is an integer it will be looked up in the mapping, if it's + a WSGI application it will be raised in a proxy exception. + + The rest of the arguments are forwarded to the exception constructor. + """ + + def __init__( + self, + mapping: t.Optional[t.Dict[int, t.Type[HTTPException]]] = None, + extra: t.Optional[t.Dict[int, t.Type[HTTPException]]] = None, + ) -> None: + if mapping is None: + mapping = default_exceptions + self.mapping = dict(mapping) + if extra is not None: + self.mapping.update(extra) + + def __call__( + self, code: t.Union[int, "Response"], *args: t.Any, **kwargs: t.Any + ) -> "te.NoReturn": + from .sansio.response import Response + + if isinstance(code, Response): + raise HTTPException(response=code) + + if code not in self.mapping: + raise LookupError(f"no exception for {code!r}") + + raise self.mapping[code](*args, **kwargs) + + +def abort( + status: t.Union[int, "Response"], *args: t.Any, **kwargs: t.Any +) -> "te.NoReturn": + """Raises an :py:exc:`HTTPException` for the given status code or WSGI + application. + + If a status code is given, it will be looked up in the list of + exceptions and will raise that exception. If passed a WSGI application, + it will wrap it in a proxy WSGI exception and raise that:: + + abort(404) # 404 Not Found + abort(Response('Hello World')) + + """ + _aborter(status, *args, **kwargs) + + +_aborter: Aborter = Aborter() diff --git a/venv/lib/python3.9/site-packages/werkzeug/filesystem.py b/venv/lib/python3.9/site-packages/werkzeug/filesystem.py new file mode 100644 index 0000000..36a3d12 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/filesystem.py @@ -0,0 +1,55 @@ +import codecs +import sys +import typing as t +import warnings + +# We do not trust traditional unixes. +has_likely_buggy_unicode_filesystem = ( + sys.platform.startswith("linux") or "bsd" in sys.platform +) + + +def _is_ascii_encoding(encoding: t.Optional[str]) -> bool: + """Given an encoding this figures out if the encoding is actually ASCII (which + is something we don't actually want in most cases). This is necessary + because ASCII comes under many names such as ANSI_X3.4-1968. + """ + if encoding is None: + return False + try: + return codecs.lookup(encoding).name == "ascii" + except LookupError: + return False + + +class BrokenFilesystemWarning(RuntimeWarning, UnicodeWarning): + """The warning used by Werkzeug to signal a broken filesystem. Will only be + used once per runtime.""" + + +_warned_about_filesystem_encoding = False + + +def get_filesystem_encoding() -> str: + """Returns the filesystem encoding that should be used. Note that this is + different from the Python understanding of the filesystem encoding which + might be deeply flawed. Do not use this value against Python's string APIs + because it might be different. See :ref:`filesystem-encoding` for the exact + behavior. + + The concept of a filesystem encoding in generally is not something you + should rely on. As such if you ever need to use this function except for + writing wrapper code reconsider. + """ + global _warned_about_filesystem_encoding + rv = sys.getfilesystemencoding() + if has_likely_buggy_unicode_filesystem and not rv or _is_ascii_encoding(rv): + if not _warned_about_filesystem_encoding: + warnings.warn( + "Detected a misconfigured UNIX filesystem: Will use" + f" UTF-8 as filesystem encoding instead of {rv!r}", + BrokenFilesystemWarning, + ) + _warned_about_filesystem_encoding = True + return "utf-8" + return rv diff --git a/venv/lib/python3.9/site-packages/werkzeug/formparser.py b/venv/lib/python3.9/site-packages/werkzeug/formparser.py new file mode 100644 index 0000000..2dcb709 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/formparser.py @@ -0,0 +1,495 @@ +import typing as t +import warnings +from functools import update_wrapper +from io import BytesIO +from itertools import chain +from typing import Union + +from . import exceptions +from ._internal import _to_str +from .datastructures import FileStorage +from .datastructures import Headers +from .datastructures import MultiDict +from .http import parse_options_header +from .sansio.multipart import Data +from .sansio.multipart import Epilogue +from .sansio.multipart import Field +from .sansio.multipart import File +from .sansio.multipart import MultipartDecoder +from .sansio.multipart import NeedData +from .urls import url_decode_stream +from .wsgi import _make_chunk_iter +from .wsgi import get_content_length +from .wsgi import get_input_stream + +# there are some platforms where SpooledTemporaryFile is not available. +# In that case we need to provide a fallback. +try: + from tempfile import SpooledTemporaryFile +except ImportError: + from tempfile import TemporaryFile + + SpooledTemporaryFile = None # type: ignore + +if t.TYPE_CHECKING: + import typing as te + from _typeshed.wsgi import WSGIEnvironment + + t_parse_result = t.Tuple[t.BinaryIO, MultiDict, MultiDict] + + class TStreamFactory(te.Protocol): + def __call__( + self, + total_content_length: t.Optional[int], + content_type: t.Optional[str], + filename: t.Optional[str], + content_length: t.Optional[int] = None, + ) -> t.BinaryIO: + ... + + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def _exhaust(stream: t.BinaryIO) -> None: + bts = stream.read(64 * 1024) + while bts: + bts = stream.read(64 * 1024) + + +def default_stream_factory( + total_content_length: t.Optional[int], + content_type: t.Optional[str], + filename: t.Optional[str], + content_length: t.Optional[int] = None, +) -> t.BinaryIO: + max_size = 1024 * 500 + + if SpooledTemporaryFile is not None: + return t.cast(t.BinaryIO, SpooledTemporaryFile(max_size=max_size, mode="rb+")) + elif total_content_length is None or total_content_length > max_size: + return t.cast(t.BinaryIO, TemporaryFile("rb+")) + + return BytesIO() + + +def parse_form_data( + environ: "WSGIEnvironment", + stream_factory: t.Optional["TStreamFactory"] = None, + charset: str = "utf-8", + errors: str = "replace", + max_form_memory_size: t.Optional[int] = None, + max_content_length: t.Optional[int] = None, + cls: t.Optional[t.Type[MultiDict]] = None, + silent: bool = True, +) -> "t_parse_result": + """Parse the form data in the environ and return it as tuple in the form + ``(stream, form, files)``. You should only call this method if the + transport method is `POST`, `PUT`, or `PATCH`. + + If the mimetype of the data transmitted is `multipart/form-data` the + files multidict will be filled with `FileStorage` objects. If the + mimetype is unknown the input stream is wrapped and returned as first + argument, else the stream is empty. + + This is a shortcut for the common usage of :class:`FormDataParser`. + + Have a look at :doc:`/request_data` for more details. + + .. versionadded:: 0.5 + The `max_form_memory_size`, `max_content_length` and + `cls` parameters were added. + + .. versionadded:: 0.5.1 + The optional `silent` flag was added. + + :param environ: the WSGI environment to be used for parsing. + :param stream_factory: An optional callable that returns a new read and + writeable file descriptor. This callable works + the same as :meth:`Response._get_file_stream`. + :param charset: The character set for URL and url encoded form data. + :param errors: The encoding error behavior. + :param max_form_memory_size: the maximum number of bytes to be accepted for + in-memory stored form data. If the data + exceeds the value specified an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param max_content_length: If this is provided and the transmitted data + is longer than this value an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param cls: an optional dict class to use. If this is not specified + or `None` the default :class:`MultiDict` is used. + :param silent: If set to False parsing errors will not be caught. + :return: A tuple in the form ``(stream, form, files)``. + """ + return FormDataParser( + stream_factory, + charset, + errors, + max_form_memory_size, + max_content_length, + cls, + silent, + ).parse_from_environ(environ) + + +def exhaust_stream(f: F) -> F: + """Helper decorator for methods that exhausts the stream on return.""" + + def wrapper(self, stream, *args, **kwargs): # type: ignore + try: + return f(self, stream, *args, **kwargs) + finally: + exhaust = getattr(stream, "exhaust", None) + + if exhaust is not None: + exhaust() + else: + while True: + chunk = stream.read(1024 * 64) + + if not chunk: + break + + return update_wrapper(t.cast(F, wrapper), f) + + +class FormDataParser: + """This class implements parsing of form data for Werkzeug. By itself + it can parse multipart and url encoded form data. It can be subclassed + and extended but for most mimetypes it is a better idea to use the + untouched stream and expose it as separate attributes on a request + object. + + .. versionadded:: 0.8 + + :param stream_factory: An optional callable that returns a new read and + writeable file descriptor. This callable works + the same as :meth:`Response._get_file_stream`. + :param charset: The character set for URL and url encoded form data. + :param errors: The encoding error behavior. + :param max_form_memory_size: the maximum number of bytes to be accepted for + in-memory stored form data. If the data + exceeds the value specified an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param max_content_length: If this is provided and the transmitted data + is longer than this value an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param cls: an optional dict class to use. If this is not specified + or `None` the default :class:`MultiDict` is used. + :param silent: If set to False parsing errors will not be caught. + """ + + def __init__( + self, + stream_factory: t.Optional["TStreamFactory"] = None, + charset: str = "utf-8", + errors: str = "replace", + max_form_memory_size: t.Optional[int] = None, + max_content_length: t.Optional[int] = None, + cls: t.Optional[t.Type[MultiDict]] = None, + silent: bool = True, + ) -> None: + if stream_factory is None: + stream_factory = default_stream_factory + + self.stream_factory = stream_factory + self.charset = charset + self.errors = errors + self.max_form_memory_size = max_form_memory_size + self.max_content_length = max_content_length + + if cls is None: + cls = MultiDict + + self.cls = cls + self.silent = silent + + def get_parse_func( + self, mimetype: str, options: t.Dict[str, str] + ) -> t.Optional[ + t.Callable[ + ["FormDataParser", t.BinaryIO, str, t.Optional[int], t.Dict[str, str]], + "t_parse_result", + ] + ]: + return self.parse_functions.get(mimetype) + + def parse_from_environ(self, environ: "WSGIEnvironment") -> "t_parse_result": + """Parses the information from the environment as form data. + + :param environ: the WSGI environment to be used for parsing. + :return: A tuple in the form ``(stream, form, files)``. + """ + content_type = environ.get("CONTENT_TYPE", "") + content_length = get_content_length(environ) + mimetype, options = parse_options_header(content_type) + return self.parse(get_input_stream(environ), mimetype, content_length, options) + + def parse( + self, + stream: t.BinaryIO, + mimetype: str, + content_length: t.Optional[int], + options: t.Optional[t.Dict[str, str]] = None, + ) -> "t_parse_result": + """Parses the information from the given stream, mimetype, + content length and mimetype parameters. + + :param stream: an input stream + :param mimetype: the mimetype of the data + :param content_length: the content length of the incoming data + :param options: optional mimetype parameters (used for + the multipart boundary for instance) + :return: A tuple in the form ``(stream, form, files)``. + """ + if ( + self.max_content_length is not None + and content_length is not None + and content_length > self.max_content_length + ): + # if the input stream is not exhausted, firefox reports Connection Reset + _exhaust(stream) + raise exceptions.RequestEntityTooLarge() + + if options is None: + options = {} + + parse_func = self.get_parse_func(mimetype, options) + + if parse_func is not None: + try: + return parse_func(self, stream, mimetype, content_length, options) + except ValueError: + if not self.silent: + raise + + return stream, self.cls(), self.cls() + + @exhaust_stream + def _parse_multipart( + self, + stream: t.BinaryIO, + mimetype: str, + content_length: t.Optional[int], + options: t.Dict[str, str], + ) -> "t_parse_result": + parser = MultiPartParser( + self.stream_factory, + self.charset, + self.errors, + max_form_memory_size=self.max_form_memory_size, + cls=self.cls, + ) + boundary = options.get("boundary", "").encode("ascii") + + if not boundary: + raise ValueError("Missing boundary") + + form, files = parser.parse(stream, boundary, content_length) + return stream, form, files + + @exhaust_stream + def _parse_urlencoded( + self, + stream: t.BinaryIO, + mimetype: str, + content_length: t.Optional[int], + options: t.Dict[str, str], + ) -> "t_parse_result": + if ( + self.max_form_memory_size is not None + and content_length is not None + and content_length > self.max_form_memory_size + ): + # if the input stream is not exhausted, firefox reports Connection Reset + _exhaust(stream) + raise exceptions.RequestEntityTooLarge() + + form = url_decode_stream(stream, self.charset, errors=self.errors, cls=self.cls) + return stream, form, self.cls() + + #: mapping of mimetypes to parsing functions + parse_functions: t.Dict[ + str, + t.Callable[ + ["FormDataParser", t.BinaryIO, str, t.Optional[int], t.Dict[str, str]], + "t_parse_result", + ], + ] = { + "multipart/form-data": _parse_multipart, + "application/x-www-form-urlencoded": _parse_urlencoded, + "application/x-url-encoded": _parse_urlencoded, + } + + +def _line_parse(line: str) -> t.Tuple[str, bool]: + """Removes line ending characters and returns a tuple (`stripped_line`, + `is_terminated`). + """ + if line[-2:] == "\r\n": + return line[:-2], True + + elif line[-1:] in {"\r", "\n"}: + return line[:-1], True + + return line, False + + +def parse_multipart_headers(iterable: t.Iterable[bytes]) -> Headers: + """Parses multipart headers from an iterable that yields lines (including + the trailing newline symbol). The iterable has to be newline terminated. + The iterable will stop at the line where the headers ended so it can be + further consumed. + :param iterable: iterable of strings that are newline terminated + """ + warnings.warn( + "'parse_multipart_headers' is deprecated and will be removed in" + " Werkzeug 2.1.", + DeprecationWarning, + stacklevel=2, + ) + result: t.List[t.Tuple[str, str]] = [] + + for b_line in iterable: + line = _to_str(b_line) + line, line_terminated = _line_parse(line) + + if not line_terminated: + raise ValueError("unexpected end of line in multipart header") + + if not line: + break + elif line[0] in " \t" and result: + key, value = result[-1] + result[-1] = (key, f"{value}\n {line[1:]}") + else: + parts = line.split(":", 1) + + if len(parts) == 2: + result.append((parts[0].strip(), parts[1].strip())) + + # we link the list to the headers, no need to create a copy, the + # list was not shared anyways. + return Headers(result) + + +class MultiPartParser: + def __init__( + self, + stream_factory: t.Optional["TStreamFactory"] = None, + charset: str = "utf-8", + errors: str = "replace", + max_form_memory_size: t.Optional[int] = None, + cls: t.Optional[t.Type[MultiDict]] = None, + buffer_size: int = 64 * 1024, + ) -> None: + self.charset = charset + self.errors = errors + self.max_form_memory_size = max_form_memory_size + + if stream_factory is None: + stream_factory = default_stream_factory + + self.stream_factory = stream_factory + + if cls is None: + cls = MultiDict + + self.cls = cls + + self.buffer_size = buffer_size + + def fail(self, message: str) -> "te.NoReturn": + raise ValueError(message) + + def get_part_charset(self, headers: Headers) -> str: + # Figure out input charset for current part + content_type = headers.get("content-type") + + if content_type: + mimetype, ct_params = parse_options_header(content_type) + return ct_params.get("charset", self.charset) + + return self.charset + + def start_file_streaming( + self, event: File, total_content_length: t.Optional[int] + ) -> t.BinaryIO: + content_type = event.headers.get("content-type") + + try: + content_length = int(event.headers["content-length"]) + except (KeyError, ValueError): + content_length = 0 + + container = self.stream_factory( + total_content_length=total_content_length, + filename=event.filename, + content_type=content_type, + content_length=content_length, + ) + return container + + def parse( + self, stream: t.BinaryIO, boundary: bytes, content_length: t.Optional[int] + ) -> t.Tuple[MultiDict, MultiDict]: + container: t.Union[t.BinaryIO, t.List[bytes]] + _write: t.Callable[[bytes], t.Any] + + iterator = chain( + _make_chunk_iter( + stream, + limit=content_length, + buffer_size=self.buffer_size, + ), + [None], + ) + + parser = MultipartDecoder(boundary, self.max_form_memory_size) + + fields = [] + files = [] + + current_part: Union[Field, File] + for data in iterator: + parser.receive_data(data) + event = parser.next_event() + while not isinstance(event, (Epilogue, NeedData)): + if isinstance(event, Field): + current_part = event + container = [] + _write = container.append + elif isinstance(event, File): + current_part = event + container = self.start_file_streaming(event, content_length) + _write = container.write + elif isinstance(event, Data): + _write(event.data) + if not event.more_data: + if isinstance(current_part, Field): + value = b"".join(container).decode( + self.get_part_charset(current_part.headers), self.errors + ) + fields.append((current_part.name, value)) + else: + container = t.cast(t.BinaryIO, container) + container.seek(0) + files.append( + ( + current_part.name, + FileStorage( + container, + current_part.filename, + current_part.name, + headers=current_part.headers, + ), + ) + ) + + event = parser.next_event() + + return self.cls(fields), self.cls(files) diff --git a/venv/lib/python3.9/site-packages/werkzeug/http.py b/venv/lib/python3.9/site-packages/werkzeug/http.py new file mode 100644 index 0000000..ca48fe2 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/http.py @@ -0,0 +1,1388 @@ +import base64 +import email.utils +import re +import typing +import typing as t +import warnings +from datetime import date +from datetime import datetime +from datetime import time +from datetime import timedelta +from datetime import timezone +from enum import Enum +from hashlib import sha1 +from time import mktime +from time import struct_time +from urllib.parse import unquote_to_bytes as _unquote +from urllib.request import parse_http_list as _parse_list_header + +from ._internal import _cookie_parse_impl +from ._internal import _cookie_quote +from ._internal import _make_cookie_domain +from ._internal import _to_bytes +from ._internal import _to_str +from ._internal import _wsgi_decoding_dance +from werkzeug._internal import _dt_as_utc + +if t.TYPE_CHECKING: + import typing_extensions as te + from _typeshed.wsgi import WSGIEnvironment + +# for explanation of "media-range", etc. see Sections 5.3.{1,2} of RFC 7231 +_accept_re = re.compile( + r""" + ( # media-range capturing-parenthesis + [^\s;,]+ # type/subtype + (?:[ \t]*;[ \t]* # ";" + (?: # parameter non-capturing-parenthesis + [^\s;,q][^\s;,]* # token that doesn't start with "q" + | # or + q[^\s;,=][^\s;,]* # token that is more than just "q" + ) + )* # zero or more parameters + ) # end of media-range + (?:[ \t]*;[ \t]*q= # weight is a "q" parameter + (\d*(?:\.\d+)?) # qvalue capturing-parentheses + [^,]* # "extension" accept params: who cares? + )? # accept params are optional + """, + re.VERBOSE, +) +_token_chars = frozenset( + "!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~" +) +_etag_re = re.compile(r'([Ww]/)?(?:"(.*?)"|(.*?))(?:\s*,\s*|$)') +_option_header_piece_re = re.compile( + r""" + ;\s*,?\s* # newlines were replaced with commas + (?P + "[^"\\]*(?:\\.[^"\\]*)*" # quoted string + | + [^\s;,=*]+ # token + ) + (?:\*(?P\d+))? # *1, optional continuation index + \s* + (?: # optionally followed by =value + (?: # equals sign, possibly with encoding + \*\s*=\s* # * indicates extended notation + (?: # optional encoding + (?P[^\s]+?) + '(?P[^\s]*?)' + )? + | + =\s* # basic notation + ) + (?P + "[^"\\]*(?:\\.[^"\\]*)*" # quoted string + | + [^;,]+ # token + )? + )? + \s* + """, + flags=re.VERBOSE, +) +_option_header_start_mime_type = re.compile(r",\s*([^;,\s]+)([;,]\s*.+)?") +_entity_headers = frozenset( + [ + "allow", + "content-encoding", + "content-language", + "content-length", + "content-location", + "content-md5", + "content-range", + "content-type", + "expires", + "last-modified", + ] +) +_hop_by_hop_headers = frozenset( + [ + "connection", + "keep-alive", + "proxy-authenticate", + "proxy-authorization", + "te", + "trailer", + "transfer-encoding", + "upgrade", + ] +) +HTTP_STATUS_CODES = { + 100: "Continue", + 101: "Switching Protocols", + 102: "Processing", + 103: "Early Hints", # see RFC 8297 + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi Status", + 208: "Already Reported", # see RFC 5842 + 226: "IM Used", # see RFC 3229 + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 306: "Switch Proxy", # unused + 307: "Temporary Redirect", + 308: "Permanent Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", # unused + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Request Entity Too Large", + 414: "Request URI Too Long", + 415: "Unsupported Media Type", + 416: "Requested Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a teapot", # see RFC 2324 + 421: "Misdirected Request", # see RFC 7540 + 422: "Unprocessable Entity", + 423: "Locked", + 424: "Failed Dependency", + 425: "Too Early", # see RFC 8470 + 426: "Upgrade Required", + 428: "Precondition Required", # see RFC 6585 + 429: "Too Many Requests", + 431: "Request Header Fields Too Large", + 449: "Retry With", # proprietary MS extension + 451: "Unavailable For Legal Reasons", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 506: "Variant Also Negotiates", # see RFC 2295 + 507: "Insufficient Storage", + 508: "Loop Detected", # see RFC 5842 + 510: "Not Extended", + 511: "Network Authentication Failed", +} + + +class COEP(Enum): + """Cross Origin Embedder Policies""" + + UNSAFE_NONE = "unsafe-none" + REQUIRE_CORP = "require-corp" + + +class COOP(Enum): + """Cross Origin Opener Policies""" + + UNSAFE_NONE = "unsafe-none" + SAME_ORIGIN_ALLOW_POPUPS = "same-origin-allow-popups" + SAME_ORIGIN = "same-origin" + + +def quote_header_value( + value: t.Union[str, int], extra_chars: str = "", allow_token: bool = True +) -> str: + """Quote a header value if necessary. + + .. versionadded:: 0.5 + + :param value: the value to quote. + :param extra_chars: a list of extra characters to skip quoting. + :param allow_token: if this is enabled token values are returned + unchanged. + """ + if isinstance(value, bytes): + value = value.decode("latin1") + value = str(value) + if allow_token: + token_chars = _token_chars | set(extra_chars) + if set(value).issubset(token_chars): + return value + value = value.replace("\\", "\\\\").replace('"', '\\"') + return f'"{value}"' + + +def unquote_header_value(value: str, is_filename: bool = False) -> str: + r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). + This does not use the real unquoting but what browsers are actually + using for quoting. + + .. versionadded:: 0.5 + + :param value: the header value to unquote. + :param is_filename: The value represents a filename or path. + """ + if value and value[0] == value[-1] == '"': + # this is not the real unquoting, but fixing this so that the + # RFC is met will result in bugs with internet explorer and + # probably some other browsers as well. IE for example is + # uploading files with "C:\foo\bar.txt" as filename + value = value[1:-1] + + # if this is a filename and the starting characters look like + # a UNC path, then just return the value without quotes. Using the + # replace sequence below on a UNC path has the effect of turning + # the leading double slash into a single slash and then + # _fix_ie_filename() doesn't work correctly. See #458. + if not is_filename or value[:2] != "\\\\": + return value.replace("\\\\", "\\").replace('\\"', '"') + return value + + +def dump_options_header( + header: t.Optional[str], options: t.Mapping[str, t.Optional[t.Union[str, int]]] +) -> str: + """The reverse function to :func:`parse_options_header`. + + :param header: the header to dump + :param options: a dict of options to append. + """ + segments = [] + if header is not None: + segments.append(header) + for key, value in options.items(): + if value is None: + segments.append(key) + else: + segments.append(f"{key}={quote_header_value(value)}") + return "; ".join(segments) + + +def dump_header( + iterable: t.Union[t.Dict[str, t.Union[str, int]], t.Iterable[str]], + allow_token: bool = True, +) -> str: + """Dump an HTTP header again. This is the reversal of + :func:`parse_list_header`, :func:`parse_set_header` and + :func:`parse_dict_header`. This also quotes strings that include an + equals sign unless you pass it as dict of key, value pairs. + + >>> dump_header({'foo': 'bar baz'}) + 'foo="bar baz"' + >>> dump_header(('foo', 'bar baz')) + 'foo, "bar baz"' + + :param iterable: the iterable or dict of values to quote. + :param allow_token: if set to `False` tokens as values are disallowed. + See :func:`quote_header_value` for more details. + """ + if isinstance(iterable, dict): + items = [] + for key, value in iterable.items(): + if value is None: + items.append(key) + else: + items.append( + f"{key}={quote_header_value(value, allow_token=allow_token)}" + ) + else: + items = [quote_header_value(x, allow_token=allow_token) for x in iterable] + return ", ".join(items) + + +def dump_csp_header(header: "ds.ContentSecurityPolicy") -> str: + """Dump a Content Security Policy header. + + These are structured into policies such as "default-src 'self'; + script-src 'self'". + + .. versionadded:: 1.0.0 + Support for Content Security Policy headers was added. + + """ + return "; ".join(f"{key} {value}" for key, value in header.items()) + + +def parse_list_header(value: str) -> t.List[str]: + """Parse lists as described by RFC 2068 Section 2. + + In particular, parse comma-separated lists where the elements of + the list may include quoted-strings. A quoted-string could + contain a comma. A non-quoted string could have quotes in the + middle. Quotes are removed automatically after parsing. + + It basically works like :func:`parse_set_header` just that items + may appear multiple times and case sensitivity is preserved. + + The return value is a standard :class:`list`: + + >>> parse_list_header('token, "quoted value"') + ['token', 'quoted value'] + + To create a header from the :class:`list` again, use the + :func:`dump_header` function. + + :param value: a string with a list header. + :return: :class:`list` + """ + result = [] + for item in _parse_list_header(value): + if item[:1] == item[-1:] == '"': + item = unquote_header_value(item[1:-1]) + result.append(item) + return result + + +def parse_dict_header(value: str, cls: t.Type[dict] = dict) -> t.Dict[str, str]: + """Parse lists of key, value pairs as described by RFC 2068 Section 2 and + convert them into a python dict (or any other mapping object created from + the type with a dict like interface provided by the `cls` argument): + + >>> d = parse_dict_header('foo="is a fish", bar="as well"') + >>> type(d) is dict + True + >>> sorted(d.items()) + [('bar', 'as well'), ('foo', 'is a fish')] + + If there is no value for a key it will be `None`: + + >>> parse_dict_header('key_without_value') + {'key_without_value': None} + + To create a header from the :class:`dict` again, use the + :func:`dump_header` function. + + .. versionchanged:: 0.9 + Added support for `cls` argument. + + :param value: a string with a dict header. + :param cls: callable to use for storage of parsed results. + :return: an instance of `cls` + """ + result = cls() + if isinstance(value, bytes): + value = value.decode("latin1") + for item in _parse_list_header(value): + if "=" not in item: + result[item] = None + continue + name, value = item.split("=", 1) + if value[:1] == value[-1:] == '"': + value = unquote_header_value(value[1:-1]) + result[name] = value + return result + + +@typing.overload +def parse_options_header( + value: t.Optional[str], multiple: "te.Literal[False]" = False +) -> t.Tuple[str, t.Dict[str, str]]: + ... + + +@typing.overload +def parse_options_header( + value: t.Optional[str], multiple: "te.Literal[True]" +) -> t.Tuple[t.Any, ...]: + ... + + +def parse_options_header( + value: t.Optional[str], multiple: bool = False +) -> t.Union[t.Tuple[str, t.Dict[str, str]], t.Tuple[t.Any, ...]]: + """Parse a ``Content-Type`` like header into a tuple with the content + type and the options: + + >>> parse_options_header('text/html; charset=utf8') + ('text/html', {'charset': 'utf8'}) + + This should not be used to parse ``Cache-Control`` like headers that use + a slightly different format. For these headers use the + :func:`parse_dict_header` function. + + .. versionchanged:: 0.15 + :rfc:`2231` parameter continuations are handled. + + .. versionadded:: 0.5 + + :param value: the header to parse. + :param multiple: Whether try to parse and return multiple MIME types + :return: (mimetype, options) or (mimetype, options, mimetype, options, …) + if multiple=True + """ + if not value: + return "", {} + + result: t.List[t.Any] = [] + + value = "," + value.replace("\n", ",") + while value: + match = _option_header_start_mime_type.match(value) + if not match: + break + result.append(match.group(1)) # mimetype + options: t.Dict[str, str] = {} + # Parse options + rest = match.group(2) + encoding: t.Optional[str] + continued_encoding: t.Optional[str] = None + while rest: + optmatch = _option_header_piece_re.match(rest) + if not optmatch: + break + option, count, encoding, language, option_value = optmatch.groups() + # Continuations don't have to supply the encoding after the + # first line. If we're in a continuation, track the current + # encoding to use for subsequent lines. Reset it when the + # continuation ends. + if not count: + continued_encoding = None + else: + if not encoding: + encoding = continued_encoding + continued_encoding = encoding + option = unquote_header_value(option) + if option_value is not None: + option_value = unquote_header_value(option_value, option == "filename") + if encoding is not None: + option_value = _unquote(option_value).decode(encoding) + if count: + # Continuations append to the existing value. For + # simplicity, this ignores the possibility of + # out-of-order indices, which shouldn't happen anyway. + options[option] = options.get(option, "") + option_value + else: + options[option] = option_value + rest = rest[optmatch.end() :] + result.append(options) + if multiple is False: + return tuple(result) + value = rest + + return tuple(result) if result else ("", {}) + + +_TAnyAccept = t.TypeVar("_TAnyAccept", bound="ds.Accept") + + +@typing.overload +def parse_accept_header(value: t.Optional[str]) -> "ds.Accept": + ... + + +@typing.overload +def parse_accept_header( + value: t.Optional[str], cls: t.Type[_TAnyAccept] +) -> _TAnyAccept: + ... + + +def parse_accept_header( + value: t.Optional[str], cls: t.Optional[t.Type[_TAnyAccept]] = None +) -> _TAnyAccept: + """Parses an HTTP Accept-* header. This does not implement a complete + valid algorithm but one that supports at least value and quality + extraction. + + Returns a new :class:`Accept` object (basically a list of ``(value, quality)`` + tuples sorted by the quality with some additional accessor methods). + + The second parameter can be a subclass of :class:`Accept` that is created + with the parsed values and returned. + + :param value: the accept header string to be parsed. + :param cls: the wrapper class for the return value (can be + :class:`Accept` or a subclass thereof) + :return: an instance of `cls`. + """ + if cls is None: + cls = t.cast(t.Type[_TAnyAccept], ds.Accept) + + if not value: + return cls(None) + + result = [] + for match in _accept_re.finditer(value): + quality_match = match.group(2) + if not quality_match: + quality: float = 1 + else: + quality = max(min(float(quality_match), 1), 0) + result.append((match.group(1), quality)) + return cls(result) + + +_TAnyCC = t.TypeVar("_TAnyCC", bound="ds._CacheControl") +_t_cc_update = t.Optional[t.Callable[[_TAnyCC], None]] + + +@typing.overload +def parse_cache_control_header( + value: t.Optional[str], on_update: _t_cc_update, cls: None = None +) -> "ds.RequestCacheControl": + ... + + +@typing.overload +def parse_cache_control_header( + value: t.Optional[str], on_update: _t_cc_update, cls: t.Type[_TAnyCC] +) -> _TAnyCC: + ... + + +def parse_cache_control_header( + value: t.Optional[str], + on_update: _t_cc_update = None, + cls: t.Optional[t.Type[_TAnyCC]] = None, +) -> _TAnyCC: + """Parse a cache control header. The RFC differs between response and + request cache control, this method does not. It's your responsibility + to not use the wrong control statements. + + .. versionadded:: 0.5 + The `cls` was added. If not specified an immutable + :class:`~werkzeug.datastructures.RequestCacheControl` is returned. + + :param value: a cache control header to be parsed. + :param on_update: an optional callable that is called every time a value + on the :class:`~werkzeug.datastructures.CacheControl` + object is changed. + :param cls: the class for the returned object. By default + :class:`~werkzeug.datastructures.RequestCacheControl` is used. + :return: a `cls` object. + """ + if cls is None: + cls = t.cast(t.Type[_TAnyCC], ds.RequestCacheControl) + + if not value: + return cls((), on_update) + + return cls(parse_dict_header(value), on_update) + + +_TAnyCSP = t.TypeVar("_TAnyCSP", bound="ds.ContentSecurityPolicy") +_t_csp_update = t.Optional[t.Callable[[_TAnyCSP], None]] + + +@typing.overload +def parse_csp_header( + value: t.Optional[str], on_update: _t_csp_update, cls: None = None +) -> "ds.ContentSecurityPolicy": + ... + + +@typing.overload +def parse_csp_header( + value: t.Optional[str], on_update: _t_csp_update, cls: t.Type[_TAnyCSP] +) -> _TAnyCSP: + ... + + +def parse_csp_header( + value: t.Optional[str], + on_update: _t_csp_update = None, + cls: t.Optional[t.Type[_TAnyCSP]] = None, +) -> _TAnyCSP: + """Parse a Content Security Policy header. + + .. versionadded:: 1.0.0 + Support for Content Security Policy headers was added. + + :param value: a csp header to be parsed. + :param on_update: an optional callable that is called every time a value + on the object is changed. + :param cls: the class for the returned object. By default + :class:`~werkzeug.datastructures.ContentSecurityPolicy` is used. + :return: a `cls` object. + """ + if cls is None: + cls = t.cast(t.Type[_TAnyCSP], ds.ContentSecurityPolicy) + + if value is None: + return cls((), on_update) + + items = [] + + for policy in value.split(";"): + policy = policy.strip() + + # Ignore badly formatted policies (no space) + if " " in policy: + directive, value = policy.strip().split(" ", 1) + items.append((directive.strip(), value.strip())) + + return cls(items, on_update) + + +def parse_set_header( + value: t.Optional[str], + on_update: t.Optional[t.Callable[["ds.HeaderSet"], None]] = None, +) -> "ds.HeaderSet": + """Parse a set-like header and return a + :class:`~werkzeug.datastructures.HeaderSet` object: + + >>> hs = parse_set_header('token, "quoted value"') + + The return value is an object that treats the items case-insensitively + and keeps the order of the items: + + >>> 'TOKEN' in hs + True + >>> hs.index('quoted value') + 1 + >>> hs + HeaderSet(['token', 'quoted value']) + + To create a header from the :class:`HeaderSet` again, use the + :func:`dump_header` function. + + :param value: a set header to be parsed. + :param on_update: an optional callable that is called every time a + value on the :class:`~werkzeug.datastructures.HeaderSet` + object is changed. + :return: a :class:`~werkzeug.datastructures.HeaderSet` + """ + if not value: + return ds.HeaderSet(None, on_update) + return ds.HeaderSet(parse_list_header(value), on_update) + + +def parse_authorization_header( + value: t.Optional[str], +) -> t.Optional["ds.Authorization"]: + """Parse an HTTP basic/digest authorization header transmitted by the web + browser. The return value is either `None` if the header was invalid or + not given, otherwise an :class:`~werkzeug.datastructures.Authorization` + object. + + :param value: the authorization header to parse. + :return: a :class:`~werkzeug.datastructures.Authorization` object or `None`. + """ + if not value: + return None + value = _wsgi_decoding_dance(value) + try: + auth_type, auth_info = value.split(None, 1) + auth_type = auth_type.lower() + except ValueError: + return None + if auth_type == "basic": + try: + username, password = base64.b64decode(auth_info).split(b":", 1) + except Exception: + return None + try: + return ds.Authorization( + "basic", + { + "username": _to_str(username, "utf-8"), + "password": _to_str(password, "utf-8"), + }, + ) + except UnicodeDecodeError: + return None + elif auth_type == "digest": + auth_map = parse_dict_header(auth_info) + for key in "username", "realm", "nonce", "uri", "response": + if key not in auth_map: + return None + if "qop" in auth_map: + if not auth_map.get("nc") or not auth_map.get("cnonce"): + return None + return ds.Authorization("digest", auth_map) + return None + + +def parse_www_authenticate_header( + value: t.Optional[str], + on_update: t.Optional[t.Callable[["ds.WWWAuthenticate"], None]] = None, +) -> "ds.WWWAuthenticate": + """Parse an HTTP WWW-Authenticate header into a + :class:`~werkzeug.datastructures.WWWAuthenticate` object. + + :param value: a WWW-Authenticate header to parse. + :param on_update: an optional callable that is called every time a value + on the :class:`~werkzeug.datastructures.WWWAuthenticate` + object is changed. + :return: a :class:`~werkzeug.datastructures.WWWAuthenticate` object. + """ + if not value: + return ds.WWWAuthenticate(on_update=on_update) + try: + auth_type, auth_info = value.split(None, 1) + auth_type = auth_type.lower() + except (ValueError, AttributeError): + return ds.WWWAuthenticate(value.strip().lower(), on_update=on_update) + return ds.WWWAuthenticate(auth_type, parse_dict_header(auth_info), on_update) + + +def parse_if_range_header(value: t.Optional[str]) -> "ds.IfRange": + """Parses an if-range header which can be an etag or a date. Returns + a :class:`~werkzeug.datastructures.IfRange` object. + + .. versionchanged:: 2.0 + If the value represents a datetime, it is timezone-aware. + + .. versionadded:: 0.7 + """ + if not value: + return ds.IfRange() + date = parse_date(value) + if date is not None: + return ds.IfRange(date=date) + # drop weakness information + return ds.IfRange(unquote_etag(value)[0]) + + +def parse_range_header( + value: t.Optional[str], make_inclusive: bool = True +) -> t.Optional["ds.Range"]: + """Parses a range header into a :class:`~werkzeug.datastructures.Range` + object. If the header is missing or malformed `None` is returned. + `ranges` is a list of ``(start, stop)`` tuples where the ranges are + non-inclusive. + + .. versionadded:: 0.7 + """ + if not value or "=" not in value: + return None + + ranges = [] + last_end = 0 + units, rng = value.split("=", 1) + units = units.strip().lower() + + for item in rng.split(","): + item = item.strip() + if "-" not in item: + return None + if item.startswith("-"): + if last_end < 0: + return None + try: + begin = int(item) + except ValueError: + return None + end = None + last_end = -1 + elif "-" in item: + begin_str, end_str = item.split("-", 1) + begin_str = begin_str.strip() + end_str = end_str.strip() + if not begin_str.isdigit(): + return None + begin = int(begin_str) + if begin < last_end or last_end < 0: + return None + if end_str: + if not end_str.isdigit(): + return None + end = int(end_str) + 1 + if begin >= end: + return None + else: + end = None + last_end = end if end is not None else -1 + ranges.append((begin, end)) + + return ds.Range(units, ranges) + + +def parse_content_range_header( + value: t.Optional[str], + on_update: t.Optional[t.Callable[["ds.ContentRange"], None]] = None, +) -> t.Optional["ds.ContentRange"]: + """Parses a range header into a + :class:`~werkzeug.datastructures.ContentRange` object or `None` if + parsing is not possible. + + .. versionadded:: 0.7 + + :param value: a content range header to be parsed. + :param on_update: an optional callable that is called every time a value + on the :class:`~werkzeug.datastructures.ContentRange` + object is changed. + """ + if value is None: + return None + try: + units, rangedef = (value or "").strip().split(None, 1) + except ValueError: + return None + + if "/" not in rangedef: + return None + rng, length_str = rangedef.split("/", 1) + if length_str == "*": + length = None + elif length_str.isdigit(): + length = int(length_str) + else: + return None + + if rng == "*": + return ds.ContentRange(units, None, None, length, on_update=on_update) + elif "-" not in rng: + return None + + start_str, stop_str = rng.split("-", 1) + try: + start = int(start_str) + stop = int(stop_str) + 1 + except ValueError: + return None + + if is_byte_range_valid(start, stop, length): + return ds.ContentRange(units, start, stop, length, on_update=on_update) + + return None + + +def quote_etag(etag: str, weak: bool = False) -> str: + """Quote an etag. + + :param etag: the etag to quote. + :param weak: set to `True` to tag it "weak". + """ + if '"' in etag: + raise ValueError("invalid etag") + etag = f'"{etag}"' + if weak: + etag = f"W/{etag}" + return etag + + +def unquote_etag( + etag: t.Optional[str], +) -> t.Union[t.Tuple[str, bool], t.Tuple[None, None]]: + """Unquote a single etag: + + >>> unquote_etag('W/"bar"') + ('bar', True) + >>> unquote_etag('"bar"') + ('bar', False) + + :param etag: the etag identifier to unquote. + :return: a ``(etag, weak)`` tuple. + """ + if not etag: + return None, None + etag = etag.strip() + weak = False + if etag.startswith(("W/", "w/")): + weak = True + etag = etag[2:] + if etag[:1] == etag[-1:] == '"': + etag = etag[1:-1] + return etag, weak + + +def parse_etags(value: t.Optional[str]) -> "ds.ETags": + """Parse an etag header. + + :param value: the tag header to parse + :return: an :class:`~werkzeug.datastructures.ETags` object. + """ + if not value: + return ds.ETags() + strong = [] + weak = [] + end = len(value) + pos = 0 + while pos < end: + match = _etag_re.match(value, pos) + if match is None: + break + is_weak, quoted, raw = match.groups() + if raw == "*": + return ds.ETags(star_tag=True) + elif quoted: + raw = quoted + if is_weak: + weak.append(raw) + else: + strong.append(raw) + pos = match.end() + return ds.ETags(strong, weak) + + +def generate_etag(data: bytes) -> str: + """Generate an etag for some data. + + .. versionchanged:: 2.0 + Use SHA-1. MD5 may not be available in some environments. + """ + return sha1(data).hexdigest() + + +def parse_date(value: t.Optional[str]) -> t.Optional[datetime]: + """Parse an :rfc:`2822` date into a timezone-aware + :class:`datetime.datetime` object, or ``None`` if parsing fails. + + This is a wrapper for :func:`email.utils.parsedate_to_datetime`. It + returns ``None`` if parsing fails instead of raising an exception, + and always returns a timezone-aware datetime object. If the string + doesn't have timezone information, it is assumed to be UTC. + + :param value: A string with a supported date format. + + .. versionchanged:: 2.0 + Return a timezone-aware datetime object. Use + ``email.utils.parsedate_to_datetime``. + """ + if value is None: + return None + + try: + dt = email.utils.parsedate_to_datetime(value) + except (TypeError, ValueError): + return None + + if dt.tzinfo is None: + return dt.replace(tzinfo=timezone.utc) + + return dt + + +def cookie_date( + expires: t.Optional[t.Union[datetime, date, int, float, struct_time]] = None +) -> str: + """Format a datetime object or timestamp into an :rfc:`2822` date + string for ``Set-Cookie expires``. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Use :func:`http_date` instead. + """ + warnings.warn( + "'cookie_date' is deprecated and will be removed in Werkzeug" + " 2.1. Use 'http_date' instead.", + DeprecationWarning, + stacklevel=2, + ) + return http_date(expires) + + +def http_date( + timestamp: t.Optional[t.Union[datetime, date, int, float, struct_time]] = None +) -> str: + """Format a datetime object or timestamp into an :rfc:`2822` date + string. + + This is a wrapper for :func:`email.utils.format_datetime`. It + assumes naive datetime objects are in UTC instead of raising an + exception. + + :param timestamp: The datetime or timestamp to format. Defaults to + the current time. + + .. versionchanged:: 2.0 + Use ``email.utils.format_datetime``. Accept ``date`` objects. + """ + if isinstance(timestamp, date): + if not isinstance(timestamp, datetime): + # Assume plain date is midnight UTC. + timestamp = datetime.combine(timestamp, time(), tzinfo=timezone.utc) + else: + # Ensure datetime is timezone-aware. + timestamp = _dt_as_utc(timestamp) + + return email.utils.format_datetime(timestamp, usegmt=True) + + if isinstance(timestamp, struct_time): + timestamp = mktime(timestamp) + + return email.utils.formatdate(timestamp, usegmt=True) + + +def parse_age(value: t.Optional[str] = None) -> t.Optional[timedelta]: + """Parses a base-10 integer count of seconds into a timedelta. + + If parsing fails, the return value is `None`. + + :param value: a string consisting of an integer represented in base-10 + :return: a :class:`datetime.timedelta` object or `None`. + """ + if not value: + return None + try: + seconds = int(value) + except ValueError: + return None + if seconds < 0: + return None + try: + return timedelta(seconds=seconds) + except OverflowError: + return None + + +def dump_age(age: t.Optional[t.Union[timedelta, int]] = None) -> t.Optional[str]: + """Formats the duration as a base-10 integer. + + :param age: should be an integer number of seconds, + a :class:`datetime.timedelta` object, or, + if the age is unknown, `None` (default). + """ + if age is None: + return None + if isinstance(age, timedelta): + age = int(age.total_seconds()) + else: + age = int(age) + + if age < 0: + raise ValueError("age cannot be negative") + + return str(age) + + +def is_resource_modified( + environ: "WSGIEnvironment", + etag: t.Optional[str] = None, + data: t.Optional[bytes] = None, + last_modified: t.Optional[t.Union[datetime, str]] = None, + ignore_if_range: bool = True, +) -> bool: + """Convenience method for conditional requests. + + :param environ: the WSGI environment of the request to be checked. + :param etag: the etag for the response for comparison. + :param data: or alternatively the data of the response to automatically + generate an etag using :func:`generate_etag`. + :param last_modified: an optional date of the last modification. + :param ignore_if_range: If `False`, `If-Range` header will be taken into + account. + :return: `True` if the resource was modified, otherwise `False`. + + .. versionchanged:: 2.0 + SHA-1 is used to generate an etag value for the data. MD5 may + not be available in some environments. + + .. versionchanged:: 1.0.0 + The check is run for methods other than ``GET`` and ``HEAD``. + """ + if etag is None and data is not None: + etag = generate_etag(data) + elif data is not None: + raise TypeError("both data and etag given") + + unmodified = False + if isinstance(last_modified, str): + last_modified = parse_date(last_modified) + + # HTTP doesn't use microsecond, remove it to avoid false positive + # comparisons. Mark naive datetimes as UTC. + if last_modified is not None: + last_modified = _dt_as_utc(last_modified.replace(microsecond=0)) + + if_range = None + if not ignore_if_range and "HTTP_RANGE" in environ: + # https://tools.ietf.org/html/rfc7233#section-3.2 + # A server MUST ignore an If-Range header field received in a request + # that does not contain a Range header field. + if_range = parse_if_range_header(environ.get("HTTP_IF_RANGE")) + + if if_range is not None and if_range.date is not None: + modified_since: t.Optional[datetime] = if_range.date + else: + modified_since = parse_date(environ.get("HTTP_IF_MODIFIED_SINCE")) + + if modified_since and last_modified and last_modified <= modified_since: + unmodified = True + + if etag: + etag, _ = unquote_etag(etag) + etag = t.cast(str, etag) + + if if_range is not None and if_range.etag is not None: + unmodified = parse_etags(if_range.etag).contains(etag) + else: + if_none_match = parse_etags(environ.get("HTTP_IF_NONE_MATCH")) + if if_none_match: + # https://tools.ietf.org/html/rfc7232#section-3.2 + # "A recipient MUST use the weak comparison function when comparing + # entity-tags for If-None-Match" + unmodified = if_none_match.contains_weak(etag) + + # https://tools.ietf.org/html/rfc7232#section-3.1 + # "Origin server MUST use the strong comparison function when + # comparing entity-tags for If-Match" + if_match = parse_etags(environ.get("HTTP_IF_MATCH")) + if if_match: + unmodified = not if_match.is_strong(etag) + + return not unmodified + + +def remove_entity_headers( + headers: t.Union["ds.Headers", t.List[t.Tuple[str, str]]], + allowed: t.Iterable[str] = ("expires", "content-location"), +) -> None: + """Remove all entity headers from a list or :class:`Headers` object. This + operation works in-place. `Expires` and `Content-Location` headers are + by default not removed. The reason for this is :rfc:`2616` section + 10.3.5 which specifies some entity headers that should be sent. + + .. versionchanged:: 0.5 + added `allowed` parameter. + + :param headers: a list or :class:`Headers` object. + :param allowed: a list of headers that should still be allowed even though + they are entity headers. + """ + allowed = {x.lower() for x in allowed} + headers[:] = [ + (key, value) + for key, value in headers + if not is_entity_header(key) or key.lower() in allowed + ] + + +def remove_hop_by_hop_headers( + headers: t.Union["ds.Headers", t.List[t.Tuple[str, str]]] +) -> None: + """Remove all HTTP/1.1 "Hop-by-Hop" headers from a list or + :class:`Headers` object. This operation works in-place. + + .. versionadded:: 0.5 + + :param headers: a list or :class:`Headers` object. + """ + headers[:] = [ + (key, value) for key, value in headers if not is_hop_by_hop_header(key) + ] + + +def is_entity_header(header: str) -> bool: + """Check if a header is an entity header. + + .. versionadded:: 0.5 + + :param header: the header to test. + :return: `True` if it's an entity header, `False` otherwise. + """ + return header.lower() in _entity_headers + + +def is_hop_by_hop_header(header: str) -> bool: + """Check if a header is an HTTP/1.1 "Hop-by-Hop" header. + + .. versionadded:: 0.5 + + :param header: the header to test. + :return: `True` if it's an HTTP/1.1 "Hop-by-Hop" header, `False` otherwise. + """ + return header.lower() in _hop_by_hop_headers + + +def parse_cookie( + header: t.Union["WSGIEnvironment", str, bytes, None], + charset: str = "utf-8", + errors: str = "replace", + cls: t.Optional[t.Type["ds.MultiDict"]] = None, +) -> "ds.MultiDict[str, str]": + """Parse a cookie from a string or WSGI environ. + + The same key can be provided multiple times, the values are stored + in-order. The default :class:`MultiDict` will have the first value + first, and all values can be retrieved with + :meth:`MultiDict.getlist`. + + :param header: The cookie header as a string, or a WSGI environ dict + with a ``HTTP_COOKIE`` key. + :param charset: The charset for the cookie values. + :param errors: The error behavior for the charset decoding. + :param cls: A dict-like class to store the parsed cookies in. + Defaults to :class:`MultiDict`. + + .. versionchanged:: 1.0.0 + Returns a :class:`MultiDict` instead of a + ``TypeConversionDict``. + + .. versionchanged:: 0.5 + Returns a :class:`TypeConversionDict` instead of a regular dict. + The ``cls`` parameter was added. + """ + if isinstance(header, dict): + header = header.get("HTTP_COOKIE", "") + elif header is None: + header = "" + + # PEP 3333 sends headers through the environ as latin1 decoded + # strings. Encode strings back to bytes for parsing. + if isinstance(header, str): + header = header.encode("latin1", "replace") + + if cls is None: + cls = ds.MultiDict + + def _parse_pairs() -> t.Iterator[t.Tuple[str, str]]: + for key, val in _cookie_parse_impl(header): # type: ignore + key_str = _to_str(key, charset, errors, allow_none_charset=True) + + if not key_str: + continue + + val_str = _to_str(val, charset, errors, allow_none_charset=True) + yield key_str, val_str + + return cls(_parse_pairs()) + + +def dump_cookie( + key: str, + value: t.Union[bytes, str] = "", + max_age: t.Optional[t.Union[timedelta, int]] = None, + expires: t.Optional[t.Union[str, datetime, int, float]] = None, + path: t.Optional[str] = "/", + domain: t.Optional[str] = None, + secure: bool = False, + httponly: bool = False, + charset: str = "utf-8", + sync_expires: bool = True, + max_size: int = 4093, + samesite: t.Optional[str] = None, +) -> str: + """Create a Set-Cookie header without the ``Set-Cookie`` prefix. + + The return value is usually restricted to ascii as the vast majority + of values are properly escaped, but that is no guarantee. It's + tunneled through latin1 as required by :pep:`3333`. + + The return value is not ASCII safe if the key contains unicode + characters. This is technically against the specification but + happens in the wild. It's strongly recommended to not use + non-ASCII values for the keys. + + :param max_age: should be a number of seconds, or `None` (default) if + the cookie should last only as long as the client's + browser session. Additionally `timedelta` objects + are accepted, too. + :param expires: should be a `datetime` object or unix timestamp. + :param path: limits the cookie to a given path, per default it will + span the whole domain. + :param domain: Use this if you want to set a cross-domain cookie. For + example, ``domain=".example.com"`` will set a cookie + that is readable by the domain ``www.example.com``, + ``foo.example.com`` etc. Otherwise, a cookie will only + be readable by the domain that set it. + :param secure: The cookie will only be available via HTTPS + :param httponly: disallow JavaScript to access the cookie. This is an + extension to the cookie standard and probably not + supported by all browsers. + :param charset: the encoding for string values. + :param sync_expires: automatically set expires if max_age is defined + but expires not. + :param max_size: Warn if the final header value exceeds this size. The + default, 4093, should be safely `supported by most browsers + `_. Set to 0 to disable this check. + :param samesite: Limits the scope of the cookie such that it will + only be attached to requests if those requests are same-site. + + .. _`cookie`: http://browsercookielimits.squawky.net/ + + .. versionchanged:: 1.0.0 + The string ``'None'`` is accepted for ``samesite``. + """ + key = _to_bytes(key, charset) + value = _to_bytes(value, charset) + + if path is not None: + from .urls import iri_to_uri + + path = iri_to_uri(path, charset) + + domain = _make_cookie_domain(domain) + + if isinstance(max_age, timedelta): + max_age = int(max_age.total_seconds()) + + if expires is not None: + if not isinstance(expires, str): + expires = http_date(expires) + elif max_age is not None and sync_expires: + expires = http_date(datetime.now(tz=timezone.utc).timestamp() + max_age) + + if samesite is not None: + samesite = samesite.title() + + if samesite not in {"Strict", "Lax", "None"}: + raise ValueError("SameSite must be 'Strict', 'Lax', or 'None'.") + + buf = [key + b"=" + _cookie_quote(value)] + + # XXX: In theory all of these parameters that are not marked with `None` + # should be quoted. Because stdlib did not quote it before I did not + # want to introduce quoting there now. + for k, v, q in ( + (b"Domain", domain, True), + (b"Expires", expires, False), + (b"Max-Age", max_age, False), + (b"Secure", secure, None), + (b"HttpOnly", httponly, None), + (b"Path", path, False), + (b"SameSite", samesite, False), + ): + if q is None: + if v: + buf.append(k) + continue + + if v is None: + continue + + tmp = bytearray(k) + if not isinstance(v, (bytes, bytearray)): + v = _to_bytes(str(v), charset) + if q: + v = _cookie_quote(v) + tmp += b"=" + v + buf.append(bytes(tmp)) + + # The return value will be an incorrectly encoded latin1 header for + # consistency with the headers object. + rv = b"; ".join(buf) + rv = rv.decode("latin1") + + # Warn if the final value of the cookie is larger than the limit. If the + # cookie is too large, then it may be silently ignored by the browser, + # which can be quite hard to debug. + cookie_size = len(rv) + + if max_size and cookie_size > max_size: + value_size = len(value) + warnings.warn( + f"The {key.decode(charset)!r} cookie is too large: the value was" + f" {value_size} bytes but the" + f" header required {cookie_size - value_size} extra bytes. The final size" + f" was {cookie_size} bytes but the limit is {max_size} bytes. Browsers may" + f" silently ignore cookies larger than this.", + stacklevel=2, + ) + + return rv + + +def is_byte_range_valid( + start: t.Optional[int], stop: t.Optional[int], length: t.Optional[int] +) -> bool: + """Checks if a given byte content range is valid for the given length. + + .. versionadded:: 0.7 + """ + if (start is None) != (stop is None): + return False + elif start is None: + return length is None or length >= 0 + elif length is None: + return 0 <= start < stop # type: ignore + elif start >= stop: # type: ignore + return False + return 0 <= start < length + + +# circular dependencies +from . import datastructures as ds diff --git a/venv/lib/python3.9/site-packages/werkzeug/local.py b/venv/lib/python3.9/site-packages/werkzeug/local.py new file mode 100644 index 0000000..a5a7870 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/local.py @@ -0,0 +1,666 @@ +import copy +import math +import operator +import sys +import typing as t +import warnings +from functools import partial +from functools import update_wrapper + +from .wsgi import ClosingIterator + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +try: + from greenlet import getcurrent as _get_ident +except ImportError: + from threading import get_ident as _get_ident + + +def get_ident() -> int: + warnings.warn( + "'get_ident' is deprecated and will be removed in Werkzeug" + " 2.1. Use 'greenlet.getcurrent' or 'threading.get_ident' for" + " previous behavior.", + DeprecationWarning, + stacklevel=2, + ) + return _get_ident() # type: ignore + + +class _CannotUseContextVar(Exception): + pass + + +try: + from contextvars import ContextVar + + if "gevent" in sys.modules or "eventlet" in sys.modules: + # Both use greenlet, so first check it has patched + # ContextVars, Greenlet <0.4.17 does not. + import greenlet + + greenlet_patched = getattr(greenlet, "GREENLET_USE_CONTEXT_VARS", False) + + if not greenlet_patched: + # If Gevent is used, check it has patched ContextVars, + # <20.5 does not. + try: + from gevent.monkey import is_object_patched + except ImportError: + # Gevent isn't used, but Greenlet is and hasn't patched + raise _CannotUseContextVar() + else: + if is_object_patched("threading", "local") and not is_object_patched( + "contextvars", "ContextVar" + ): + raise _CannotUseContextVar() + + +except (ImportError, _CannotUseContextVar): + + class ContextVar: # type: ignore + """A fake ContextVar based on the previous greenlet/threading + ident function. Used on Python 3.6, eventlet, and old versions + of gevent. + """ + + def __init__(self, _name: str) -> None: + self.storage: t.Dict[int, t.Dict[str, t.Any]] = {} + + def get(self, default: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]: + return self.storage.get(_get_ident(), default) + + def set(self, value: t.Dict[str, t.Any]) -> None: + self.storage[_get_ident()] = value + + +def release_local(local: t.Union["Local", "LocalStack"]) -> None: + """Releases the contents of the local for the current context. + This makes it possible to use locals without a manager. + + Example:: + + >>> loc = Local() + >>> loc.foo = 42 + >>> release_local(loc) + >>> hasattr(loc, 'foo') + False + + With this function one can release :class:`Local` objects as well + as :class:`LocalStack` objects. However it is not possible to + release data held by proxies that way, one always has to retain + a reference to the underlying local object in order to be able + to release it. + + .. versionadded:: 0.6.1 + """ + local.__release_local__() + + +class Local: + __slots__ = ("_storage",) + + def __init__(self) -> None: + object.__setattr__(self, "_storage", ContextVar("local_storage")) + + @property + def __storage__(self) -> t.Dict[str, t.Any]: + warnings.warn( + "'__storage__' is deprecated and will be removed in Werkzeug 2.1.", + DeprecationWarning, + stacklevel=2, + ) + return self._storage.get({}) # type: ignore + + @property + def __ident_func__(self) -> t.Callable[[], int]: + warnings.warn( + "'__ident_func__' is deprecated and will be removed in" + " Werkzeug 2.1. It should not be used in Python 3.7+.", + DeprecationWarning, + stacklevel=2, + ) + return _get_ident # type: ignore + + @__ident_func__.setter + def __ident_func__(self, func: t.Callable[[], int]) -> None: + warnings.warn( + "'__ident_func__' is deprecated and will be removed in" + " Werkzeug 2.1. Setting it no longer has any effect.", + DeprecationWarning, + stacklevel=2, + ) + + def __iter__(self) -> t.Iterator[t.Tuple[int, t.Any]]: + return iter(self._storage.get({}).items()) + + def __call__(self, proxy: str) -> "LocalProxy": + """Create a proxy for a name.""" + return LocalProxy(self, proxy) + + def __release_local__(self) -> None: + self._storage.set({}) + + def __getattr__(self, name: str) -> t.Any: + values = self._storage.get({}) + try: + return values[name] + except KeyError: + raise AttributeError(name) + + def __setattr__(self, name: str, value: t.Any) -> None: + values = self._storage.get({}).copy() + values[name] = value + self._storage.set(values) + + def __delattr__(self, name: str) -> None: + values = self._storage.get({}).copy() + try: + del values[name] + self._storage.set(values) + except KeyError: + raise AttributeError(name) + + +class LocalStack: + """This class works similar to a :class:`Local` but keeps a stack + of objects instead. This is best explained with an example:: + + >>> ls = LocalStack() + >>> ls.push(42) + >>> ls.top + 42 + >>> ls.push(23) + >>> ls.top + 23 + >>> ls.pop() + 23 + >>> ls.top + 42 + + They can be force released by using a :class:`LocalManager` or with + the :func:`release_local` function but the correct way is to pop the + item from the stack after using. When the stack is empty it will + no longer be bound to the current context (and as such released). + + By calling the stack without arguments it returns a proxy that resolves to + the topmost item on the stack. + + .. versionadded:: 0.6.1 + """ + + def __init__(self) -> None: + self._local = Local() + + def __release_local__(self) -> None: + self._local.__release_local__() + + @property + def __ident_func__(self) -> t.Callable[[], int]: + return self._local.__ident_func__ + + @__ident_func__.setter + def __ident_func__(self, value: t.Callable[[], int]) -> None: + object.__setattr__(self._local, "__ident_func__", value) + + def __call__(self) -> "LocalProxy": + def _lookup() -> t.Any: + rv = self.top + if rv is None: + raise RuntimeError("object unbound") + return rv + + return LocalProxy(_lookup) + + def push(self, obj: t.Any) -> t.List[t.Any]: + """Pushes a new item to the stack""" + rv = getattr(self._local, "stack", []).copy() + rv.append(obj) + self._local.stack = rv + return rv # type: ignore + + def pop(self) -> t.Any: + """Removes the topmost item from the stack, will return the + old value or `None` if the stack was already empty. + """ + stack = getattr(self._local, "stack", None) + if stack is None: + return None + elif len(stack) == 1: + release_local(self._local) + return stack[-1] + else: + return stack.pop() + + @property + def top(self) -> t.Any: + """The topmost item on the stack. If the stack is empty, + `None` is returned. + """ + try: + return self._local.stack[-1] + except (AttributeError, IndexError): + return None + + +class LocalManager: + """Local objects cannot manage themselves. For that you need a local + manager. You can pass a local manager multiple locals or add them + later y appending them to `manager.locals`. Every time the manager + cleans up, it will clean up all the data left in the locals for this + context. + + .. versionchanged:: 2.0 + ``ident_func`` is deprecated and will be removed in Werkzeug + 2.1. + + .. versionchanged:: 0.6.1 + The :func:`release_local` function can be used instead of a + manager. + + .. versionchanged:: 0.7 + The ``ident_func`` parameter was added. + """ + + def __init__( + self, + locals: t.Optional[t.Iterable[t.Union[Local, LocalStack]]] = None, + ident_func: None = None, + ) -> None: + if locals is None: + self.locals = [] + elif isinstance(locals, Local): + self.locals = [locals] + else: + self.locals = list(locals) + + if ident_func is not None: + warnings.warn( + "'ident_func' is deprecated and will be removed in" + " Werkzeug 2.1. Setting it no longer has any effect.", + DeprecationWarning, + stacklevel=2, + ) + + @property + def ident_func(self) -> t.Callable[[], int]: + warnings.warn( + "'ident_func' is deprecated and will be removed in Werkzeug 2.1.", + DeprecationWarning, + stacklevel=2, + ) + return _get_ident # type: ignore + + @ident_func.setter + def ident_func(self, func: t.Callable[[], int]) -> None: + warnings.warn( + "'ident_func' is deprecated and will be removedin Werkzeug" + " 2.1. Setting it no longer has any effect.", + DeprecationWarning, + stacklevel=2, + ) + + def get_ident(self) -> int: + """Return the context identifier the local objects use internally for + this context. You cannot override this method to change the behavior + but use it to link other context local objects (such as SQLAlchemy's + scoped sessions) to the Werkzeug locals. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. + + .. versionchanged:: 0.7 + You can pass a different ident function to the local manager that + will then be propagated to all the locals passed to the + constructor. + """ + warnings.warn( + "'get_ident' is deprecated and will be removed in Werkzeug 2.1.", + DeprecationWarning, + stacklevel=2, + ) + return self.ident_func() + + def cleanup(self) -> None: + """Manually clean up the data in the locals for this context. Call + this at the end of the request or use `make_middleware()`. + """ + for local in self.locals: + release_local(local) + + def make_middleware(self, app: "WSGIApplication") -> "WSGIApplication": + """Wrap a WSGI application so that cleaning up happens after + request end. + """ + + def application( + environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + return ClosingIterator(app(environ, start_response), self.cleanup) + + return application + + def middleware(self, func: "WSGIApplication") -> "WSGIApplication": + """Like `make_middleware` but for decorating functions. + + Example usage:: + + @manager.middleware + def application(environ, start_response): + ... + + The difference to `make_middleware` is that the function passed + will have all the arguments copied from the inner application + (name, docstring, module). + """ + return update_wrapper(self.make_middleware(func), func) + + def __repr__(self) -> str: + return f"<{type(self).__name__} storages: {len(self.locals)}>" + + +class _ProxyLookup: + """Descriptor that handles proxied attribute lookup for + :class:`LocalProxy`. + + :param f: The built-in function this attribute is accessed through. + Instead of looking up the special method, the function call + is redone on the object. + :param fallback: Call this method if the proxy is unbound instead of + raising a :exc:`RuntimeError`. + :param class_value: Value to return when accessed from the class. + Used for ``__doc__`` so building docs still works. + """ + + __slots__ = ("bind_f", "fallback", "class_value", "name") + + def __init__( + self, + f: t.Optional[t.Callable] = None, + fallback: t.Optional[t.Callable] = None, + class_value: t.Optional[t.Any] = None, + ) -> None: + bind_f: t.Optional[t.Callable[["LocalProxy", t.Any], t.Callable]] + + if hasattr(f, "__get__"): + # A Python function, can be turned into a bound method. + + def bind_f(instance: "LocalProxy", obj: t.Any) -> t.Callable: + return f.__get__(obj, type(obj)) # type: ignore + + elif f is not None: + # A C function, use partial to bind the first argument. + + def bind_f(instance: "LocalProxy", obj: t.Any) -> t.Callable: + return partial(f, obj) # type: ignore + + else: + # Use getattr, which will produce a bound method. + bind_f = None + + self.bind_f = bind_f + self.fallback = fallback + self.class_value = class_value + + def __set_name__(self, owner: "LocalProxy", name: str) -> None: + self.name = name + + def __get__(self, instance: "LocalProxy", owner: t.Optional[type] = None) -> t.Any: + if instance is None: + if self.class_value is not None: + return self.class_value + + return self + + try: + obj = instance._get_current_object() + except RuntimeError: + if self.fallback is None: + raise + + return self.fallback.__get__(instance, owner) # type: ignore + + if self.bind_f is not None: + return self.bind_f(instance, obj) + + return getattr(obj, self.name) + + def __repr__(self) -> str: + return f"proxy {self.name}" + + def __call__(self, instance: "LocalProxy", *args: t.Any, **kwargs: t.Any) -> t.Any: + """Support calling unbound methods from the class. For example, + this happens with ``copy.copy``, which does + ``type(x).__copy__(x)``. ``type(x)`` can't be proxied, so it + returns the proxy type and descriptor. + """ + return self.__get__(instance, type(instance))(*args, **kwargs) + + +class _ProxyIOp(_ProxyLookup): + """Look up an augmented assignment method on a proxied object. The + method is wrapped to return the proxy instead of the object. + """ + + __slots__ = () + + def __init__( + self, f: t.Optional[t.Callable] = None, fallback: t.Optional[t.Callable] = None + ) -> None: + super().__init__(f, fallback) + + def bind_f(instance: "LocalProxy", obj: t.Any) -> t.Callable: + def i_op(self: t.Any, other: t.Any) -> "LocalProxy": + f(self, other) # type: ignore + return instance + + return i_op.__get__(obj, type(obj)) # type: ignore + + self.bind_f = bind_f + + +def _l_to_r_op(op: F) -> F: + """Swap the argument order to turn an l-op into an r-op.""" + + def r_op(obj: t.Any, other: t.Any) -> t.Any: + return op(other, obj) + + return t.cast(F, r_op) + + +class LocalProxy: + """A proxy to the object bound to a :class:`Local`. All operations + on the proxy are forwarded to the bound object. If no object is + bound, a :exc:`RuntimeError` is raised. + + .. code-block:: python + + from werkzeug.local import Local + l = Local() + + # a proxy to whatever l.user is set to + user = l("user") + + from werkzeug.local import LocalStack + _request_stack = LocalStack() + + # a proxy to _request_stack.top + request = _request_stack() + + # a proxy to the session attribute of the request proxy + session = LocalProxy(lambda: request.session) + + ``__repr__`` and ``__class__`` are forwarded, so ``repr(x)`` and + ``isinstance(x, cls)`` will look like the proxied object. Use + ``issubclass(type(x), LocalProxy)`` to check if an object is a + proxy. + + .. code-block:: python + + repr(user) # + isinstance(user, User) # True + issubclass(type(user), LocalProxy) # True + + :param local: The :class:`Local` or callable that provides the + proxied object. + :param name: The attribute name to look up on a :class:`Local`. Not + used if a callable is given. + + .. versionchanged:: 2.0 + Updated proxied attributes and methods to reflect the current + data model. + + .. versionchanged:: 0.6.1 + The class can be instantiated with a callable. + """ + + __slots__ = ("__local", "__name", "__wrapped__") + + def __init__( + self, + local: t.Union["Local", t.Callable[[], t.Any]], + name: t.Optional[str] = None, + ) -> None: + object.__setattr__(self, "_LocalProxy__local", local) + object.__setattr__(self, "_LocalProxy__name", name) + + if callable(local) and not hasattr(local, "__release_local__"): + # "local" is a callable that is not an instance of Local or + # LocalManager: mark it as a wrapped function. + object.__setattr__(self, "__wrapped__", local) + + def _get_current_object(self) -> t.Any: + """Return the current object. This is useful if you want the real + object behind the proxy at a time for performance reasons or because + you want to pass the object into a different context. + """ + if not hasattr(self.__local, "__release_local__"): # type: ignore + return self.__local() # type: ignore + + try: + return getattr(self.__local, self.__name) # type: ignore + except AttributeError: + raise RuntimeError(f"no object bound to {self.__name}") # type: ignore + + __doc__ = _ProxyLookup( # type: ignore + class_value=__doc__, fallback=lambda self: type(self).__doc__ + ) + # __del__ should only delete the proxy + __repr__ = _ProxyLookup( # type: ignore + repr, fallback=lambda self: f"<{type(self).__name__} unbound>" + ) + __str__ = _ProxyLookup(str) # type: ignore + __bytes__ = _ProxyLookup(bytes) + __format__ = _ProxyLookup() # type: ignore + __lt__ = _ProxyLookup(operator.lt) + __le__ = _ProxyLookup(operator.le) + __eq__ = _ProxyLookup(operator.eq) # type: ignore + __ne__ = _ProxyLookup(operator.ne) # type: ignore + __gt__ = _ProxyLookup(operator.gt) + __ge__ = _ProxyLookup(operator.ge) + __hash__ = _ProxyLookup(hash) # type: ignore + __bool__ = _ProxyLookup(bool, fallback=lambda self: False) + __getattr__ = _ProxyLookup(getattr) + # __getattribute__ triggered through __getattr__ + __setattr__ = _ProxyLookup(setattr) # type: ignore + __delattr__ = _ProxyLookup(delattr) # type: ignore + __dir__ = _ProxyLookup(dir, fallback=lambda self: []) # type: ignore + # __get__ (proxying descriptor not supported) + # __set__ (descriptor) + # __delete__ (descriptor) + # __set_name__ (descriptor) + # __objclass__ (descriptor) + # __slots__ used by proxy itself + # __dict__ (__getattr__) + # __weakref__ (__getattr__) + # __init_subclass__ (proxying metaclass not supported) + # __prepare__ (metaclass) + __class__ = _ProxyLookup(fallback=lambda self: type(self)) # type: ignore + __instancecheck__ = _ProxyLookup(lambda self, other: isinstance(other, self)) + __subclasscheck__ = _ProxyLookup(lambda self, other: issubclass(other, self)) + # __class_getitem__ triggered through __getitem__ + __call__ = _ProxyLookup(lambda self, *args, **kwargs: self(*args, **kwargs)) + __len__ = _ProxyLookup(len) + __length_hint__ = _ProxyLookup(operator.length_hint) + __getitem__ = _ProxyLookup(operator.getitem) + __setitem__ = _ProxyLookup(operator.setitem) + __delitem__ = _ProxyLookup(operator.delitem) + # __missing__ triggered through __getitem__ + __iter__ = _ProxyLookup(iter) + __next__ = _ProxyLookup(next) + __reversed__ = _ProxyLookup(reversed) + __contains__ = _ProxyLookup(operator.contains) + __add__ = _ProxyLookup(operator.add) + __sub__ = _ProxyLookup(operator.sub) + __mul__ = _ProxyLookup(operator.mul) + __matmul__ = _ProxyLookup(operator.matmul) + __truediv__ = _ProxyLookup(operator.truediv) + __floordiv__ = _ProxyLookup(operator.floordiv) + __mod__ = _ProxyLookup(operator.mod) + __divmod__ = _ProxyLookup(divmod) + __pow__ = _ProxyLookup(pow) + __lshift__ = _ProxyLookup(operator.lshift) + __rshift__ = _ProxyLookup(operator.rshift) + __and__ = _ProxyLookup(operator.and_) + __xor__ = _ProxyLookup(operator.xor) + __or__ = _ProxyLookup(operator.or_) + __radd__ = _ProxyLookup(_l_to_r_op(operator.add)) + __rsub__ = _ProxyLookup(_l_to_r_op(operator.sub)) + __rmul__ = _ProxyLookup(_l_to_r_op(operator.mul)) + __rmatmul__ = _ProxyLookup(_l_to_r_op(operator.matmul)) + __rtruediv__ = _ProxyLookup(_l_to_r_op(operator.truediv)) + __rfloordiv__ = _ProxyLookup(_l_to_r_op(operator.floordiv)) + __rmod__ = _ProxyLookup(_l_to_r_op(operator.mod)) + __rdivmod__ = _ProxyLookup(_l_to_r_op(divmod)) + __rpow__ = _ProxyLookup(_l_to_r_op(pow)) + __rlshift__ = _ProxyLookup(_l_to_r_op(operator.lshift)) + __rrshift__ = _ProxyLookup(_l_to_r_op(operator.rshift)) + __rand__ = _ProxyLookup(_l_to_r_op(operator.and_)) + __rxor__ = _ProxyLookup(_l_to_r_op(operator.xor)) + __ror__ = _ProxyLookup(_l_to_r_op(operator.or_)) + __iadd__ = _ProxyIOp(operator.iadd) + __isub__ = _ProxyIOp(operator.isub) + __imul__ = _ProxyIOp(operator.imul) + __imatmul__ = _ProxyIOp(operator.imatmul) + __itruediv__ = _ProxyIOp(operator.itruediv) + __ifloordiv__ = _ProxyIOp(operator.ifloordiv) + __imod__ = _ProxyIOp(operator.imod) + __ipow__ = _ProxyIOp(operator.ipow) + __ilshift__ = _ProxyIOp(operator.ilshift) + __irshift__ = _ProxyIOp(operator.irshift) + __iand__ = _ProxyIOp(operator.iand) + __ixor__ = _ProxyIOp(operator.ixor) + __ior__ = _ProxyIOp(operator.ior) + __neg__ = _ProxyLookup(operator.neg) + __pos__ = _ProxyLookup(operator.pos) + __abs__ = _ProxyLookup(abs) + __invert__ = _ProxyLookup(operator.invert) + __complex__ = _ProxyLookup(complex) + __int__ = _ProxyLookup(int) + __float__ = _ProxyLookup(float) + __index__ = _ProxyLookup(operator.index) + __round__ = _ProxyLookup(round) + __trunc__ = _ProxyLookup(math.trunc) + __floor__ = _ProxyLookup(math.floor) + __ceil__ = _ProxyLookup(math.ceil) + __enter__ = _ProxyLookup() + __exit__ = _ProxyLookup() + __await__ = _ProxyLookup() + __aiter__ = _ProxyLookup() + __anext__ = _ProxyLookup() + __aenter__ = _ProxyLookup() + __aexit__ = _ProxyLookup() + __copy__ = _ProxyLookup(copy.copy) + __deepcopy__ = _ProxyLookup(copy.deepcopy) + # __getnewargs_ex__ (pickle through proxy not supported) + # __getnewargs__ (pickle) + # __getstate__ (pickle) + # __setstate__ (pickle) + # __reduce__ (pickle) + # __reduce_ex__ (pickle) diff --git a/venv/lib/python3.9/site-packages/werkzeug/middleware/__init__.py b/venv/lib/python3.9/site-packages/werkzeug/middleware/__init__.py new file mode 100644 index 0000000..6ddcf7f --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/middleware/__init__.py @@ -0,0 +1,22 @@ +""" +Middleware +========== + +A WSGI middleware is a WSGI application that wraps another application +in order to observe or change its behavior. Werkzeug provides some +middleware for common use cases. + +.. toctree:: + :maxdepth: 1 + + proxy_fix + shared_data + dispatcher + http_proxy + lint + profiler + +The :doc:`interactive debugger ` is also a middleware that can +be applied manually, although it is typically used automatically with +the :doc:`development server `. +""" diff --git a/venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e1ccf19fd27b122653690bb635b49bab72b1059 GIT binary patch literal 710 zcmYjP!HN_y5bfEEOJM&Y*9Gk$o@~}ZL0CK}!U_vsda64$oiOPnB-K4T{*k}5SFZ{S zdh%p-W?82oq3XRhcVJF(E!$ ztsU+mp?LFTLcEi=H`gEJ_{2(^B^*JB(b*oz1~16~$$f&ztPf-`$rD;wFGJD{Qjnp` zm}X=^_6Gcb(o&Wk8klWJwY4iofbc`%LLGz>iKl`8IfQ$%w)uyQA36wP|@qQj$DsO1QL0_P6T zB{(u+8Vswmq|+g?*32v;YY7vDk)=OEdrL;J=#R~4oY93iq9<9jURqfk>xcEG7N0Ix z_s`mv8*kh1RXXGEP`1B88J1d+9r+2lpoVO4R_`(IC`5J5Wu{Jj4vDtG*`Q|hvvRgm x@xaacSM_U^E#Zp@{SF4qYXA6_>i^iPZLPP|wskz*pI?nZPY&11-~7$1`Uj+P=kWjl literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..68739747388e8c6e294eea975125926714f4e578 GIT binary patch literal 2769 zcmZ`*TW=f372X>!T2qcuxF}qpz`!rA0GSMGphelFh$^|3Tw4(=6-9`m+u_bo9D8q? z8B%6SJ;e|G4`~7Cv43e_`xKxLeGb~9-k~7E*X!< zJbfh#!S+sIG`^fobP3g%k~mD5D%ev#=clPwm1T`LB|L`dOqVlK8H0zGV_jYvIHX}E zKHx2wmKQT=oMA$(T&ZB0Ayv6Mhck1j`v|UF>xV}-K|MTs{><6;^ps5$+;wJ{X*tUT z8%yQ{2sSA-xE3)*3EM^qXt_V&mAa3Zxzw%V^-e-?sEI&Tu~{KtdUI%(2wdcF4;hVb zNVIdGhzOV?UE4!$IJcSzlBHOZQCZgHI=&8v84lx^;elNC@dogo-$3i9&Z%UTk6rc` zcYqE(AeSBtaabh~u)9eh+lWNpHSuaEj*kjf=~B#6!uqa5L9WiH78y2Hasf;ffHi!f z&{L`qj?gV5It+Og$3z;Ci@*q9qY8CcEArq22diH>g| zw~8+i?D8pjO4(yVR#~~g(MyGN0t>R@K-P7MHPUxuN&;DGENVEtwyF`d28K{trZ!u! z@#5QV0T}&0<1<^P88^twdy^5z!?dgxn&LHNKl|{*U$7G-Raz4d(LQ8hv1txD83xEp3>pXr;WuYc+E2m z(i{0`gMsizq3DTFMlV}<+p;6VNpR1*=ZQc>e+xxRwBNMQ?mD6i`j(7A*}{G-ZoP>{ zw_F?CuJ5kf-Wq-UsqcCFWjhf*#=c6+iF%Ftei!vky{}ZGDjG4zIz-}j!a9V>b-NK) zx3#o0U8F=?Jv0yS?&CFgF)aP1mw3yd>M0L1WFD87f4mcD0)_5ifZWK)Y_i_@ho|XI z{pMmYEps`rD#ul`sFdJlD(8a(XpO6;@)j+;TGZVnQH8Qe@(2bPT(O?lYWtu6NU#xD_%`}n*4?@9T-8CP~S#TYn$ln+RgP zkG9aWY=R8sqq`-#lPY+YG`vZ{bNrDZ5pK9ea*&)9eJe?Rg_Zd+1~2USQPA~c{DR<) zehs$$L*5Qyq6>wGoD>jI!PkR6x+V7yPsBc{qU@g z4peIE&{(Z|&a@*dH6LfPZjBfCOQnB^-3|M1oX{;0cJR9L==xF5`)?2g{tx`%KfSHU z@BXjh*wXh%ZrcL)#knSD>+Q48P97)whmZGvcXa$@bUOi2q9jEB(wr*?Kv$^^9!b&r YEU3F5HLm`ea%#x@h;@TD!iHb?e}D)w!vFvP literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e9b0c25c0c10036fec95a33d6f0d5cf83742f111 GIT binary patch literal 6814 zcmbVRO>i4WcAh^BfFTG{v@DDA&(6xSB_t#v%Z|5}t5qyZw4|&|DI#}WLS+LC(G6nA z!3@~lphPa1L#SQRsdAN4Ia-?{kG}0`FFBP5s#2*vD~X)%^#C9#+vQ4z zHI1IvJ+EKC_r0GU2IJ$Nf$Kli9~!@T(=h&>9*$l%9zMb?pP*qz&0r?8BC}@U*N*It zQ*%s%IV>0DI&RI?eHZk6EwB6esL(0ain?Dw->Z4LUyQ~&rCP}}xV1Je{tDc@sN9*T zO<>eyW9U!TCUw7r{)yTN)3{-3Z$H$&!&AEG8XX%f#9Au-%Pq&B3x~&dH>SIi$C)322sS7^yZ_m z$z#dq{g0Qf&%Qrn9pSB(Vz1R~`y&DM0hYuUQMA5_KDp&O|?)Fq&D#3#eXyZ#N5b7S6-2}pbF!9;a zjayf{U5FQ`Fo}nx!TKG@)Fc^?UU@uxgj;T+;YQ7bHDSe?%}y|fJ8L=aqRs2J(6Xit zx_OZoS&q3+b1csak8(Bd_#Di3Vg2G$hk0!5ky9IEB{q&ZB|bh4OFgyO1e*lC%yO{T zR63z;bg2B`A0d~f`GRlsxKz^b#n7G~_}xIYeUe6;R%+o}GVbM32HX;4&CH+g7SO zU#-4(=|^)H@%P^RpIp57UiIwEF>X7fr=3bB%t8PYX>r@IJ;~lmq9}Qw;ngKY%7NI8 zMz&a^F+bw6jQJVW|M|V!v||=ZAQwDUGB6*kN%#r{DVv0DGz9M?o4lTB@+iO0+FWA@ zjIudeqJhR+BI)R7T55&E{Cu<=i5sesTmvu2L?bycledCiq7*g`DBs#!<}s7AgFSb;l5V6vV{^!|xS7N-z* z{ca+ZPd=P2{}R-`0j^Bu%-a#7wL~wiIB+8@ocY!f*ubOYU^nwf%t40&)V#*Hj_`OI zW?RzV0}&v-5UvKZv(@FGx)_E8*r*k*_Jq#Ta?W4kDb&23-B?2;JmK;bP!Yo1(98L$uW6V|9;Ygg|%pn<*!x%ydvCA_l z>D6E;e=7*1p;}Ny!Jv}B%@}7Wq!432&^mZVmBllvBn35#m0W5=VQGG#mDD@j7KoV? zsVlhZiMW}=E5nQW4sIK_`~@0iteMI}Yg0XP{E3-QEoL$Mk@LCHH~U82d2F;yszx6b z`qqB#z_@Pg65Z|FX!CssZGjo6MBK%Sl{!gRN%0C+X_{z;7xhVoCEW4@G<{=V*S!ap zne}bvjQY9I81-E?=wpTaVmf{-%72nN1mWjy7Fg5#AULFBN4y!8oF};&23%8|#QI+u z;&uEy->9~e4zEIgD0{ZLAq!-iZ&t5!xvr9K^#-C;Z>4${Zi5UKCe=+IZ&sslrP_rX zCh_}oKdwrEW40SK*Mn6qs}HzX-{!s5>S1+Mr7ViPgvw~HyOoaDAx(WCjy8zY2L`h= z_}i}DrMZU{-CP~zYpCk=xyw<4JRq;k9piCK)nsNDH`zd5Kodg2zx4mY+A()52BSjp z#)0`I+TYrHM&H^s|IXTQpkDL2S%tE4@PM%Um7Q917gKXRH8;O91r9Qq#>5-wrQT&K zVwy>(d*v@_9jew{b9?6d1wVYTQcO*iI@iG{wXtSuBcF%~VxNObJ5o%dFHTT1g$5qr zNFKHHl$XY|F~vEWs^u#THFgIiSw>^zFXUa*Gu^KXHY7d$U6NKDjgQo!QaN?A@Rk9Z z06e_Nsi^$dPIVm}W$c;EoQ89Jo>S(&rR=@j8X*0-LGGl?wVZNMzB^Ct$HrsxvGv$~ z>^#o3TsjIoD(yIZvH$??X8tY4z*7{_zz}(Wjt)U-8D*PLbul=$WMYx-hZkwDfLj~? zcNkHIg17EMpaZl30M43^V07)pfCDprZC%FmzRm0d(=_%h=0MEcx+QLFs=H^lEEePEGJB=3kqAcmKqJVH#?xkLR5{baZCg*eUc2 zSo!b!dF<--enIal-*?wu!T1}~MnBIc*_&V3h=#DuFE7Adi#uMwxPS7%U~g$@{+0az z6nFpCezEUSe0*YV{2tGz^lGn>m3PMaWBaEeX)8a(tToWT)}CV$AzMsIfB+8KwG z^P2HvMz|=HS%iy0l;l;e<(dVv^gr8I zUydGK3fOg=PDTOxNO5yWygcHGROz9TjJZBmrnzR6ph_dz#A|3$=O*%6tw^O}{pOve zWpSE@UZv(O8ZTeFv$(vlxLm)zuy|wn<|p81EN+*<5@!Q7dt2`nyFalkf>^e=m|cjQ zDD30aG_MN>&X$opk(i#{1;2`^Lu{HOiVXh&`C3d9-OA{Bt;C0Fdv;luK)!6Yc?YN4 z9*(3q^q!~p&ign!>z+J6Cb<@aPNM7Y5Cr*#T(DfKTXT`7C>5Bu7A3) zeDltAWSpX054-r9BNeKeky6Bm5J2nwormMzJ969;6m2P;e;lwIfx@Szt>>oy-FTsV zpz-p?x8dawC))NSOsG&r_~L+fU&4f-!sVZEOUkbr3@@NKinUGLql=0ig3J53U zhd?aIDa9Y5NnJpl$1HW}ixPfqI9lpPx{469dWO&ssg17+shdGZP})k%1n?t%;Lrgj zgWQBZCLI|o-Rs3v=j#0f#TifpW#QDr$GyS9OOV>rA_!SAn0gRuP!|d^i`Gr1P1F+* zcno5VQtB^p^6Ac9NZOL~&(>p&tAdw6BY^Ie)yxP`B2fl5T0TiH@vRwl%I zwALkR$aiaFRJkgApP;&87?kRRphPH1ZEPv^2Gj60vo?m4q}U?e#jD~haeABPK^Tb9 z5r0M$5>M~wD>n-tRNZQ|i#h6PTvX8mQh!DST_24d2~TUF%D+Kl*psGfSue`2XO%Qy zPFhpel<8On^OSkY@^o(!MHKZM0Ln2ZQBKjXMKsg>??T=}-}&18+Q}6VEDH#kW$PsP zmGRCbIAK0$4(`)dS<_2cg#ZeVdf~iqif2mOv;QZER`P;8QfNy!%>eqjfajVQ$YvO3 zfh9B03Ot*9wUWye^OCYc;-Ygvn|fI(IgITLBw0dZV8>x z!9NN%u56&}p{%z{pYN^3TJi4H<(u_ei=W)VE~y~QYGv)Ko-QCIeJ~LbhM+kOkVCAJ z!)9-3_-F-bjU1*%6xZ}Is$Ty$%*_IfU4ZqbfPpf8zp0bq3y87f#GeZC%0voAanRxQ zdg|5d`0Uh+s9&nrH+n%d7|GY`ENRy3nQ`-<0=VQ2WM6TfnhKiK4r3*#JkYxm>(nDV z3(DO`!uV(tf(%I+PWosHrt@RO-2bwG!_&Yo{+^dkO_|n<(nGSdo?UrG2+T!=j&mYJ zAhd~}P(z^%pW_jZfjoRD?jf3F0a8~P4t!Z=2qnYUoCk6>)S)OHU%r2Lp?>Y=!nL0v zJJ!l|@a8yyvN=76>VJLw&%i`7f7@o#!sSeRS19#J3O7y>g$lfD@CR?xJ^OzF2I(be literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/lint.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/lint.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40725f6784f71c2723872b484bd628b01db17d54 GIT binary patch literal 12711 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 jAO}qn6gL9#nMb^thD?;w!92E literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..811b8fc165ad63a0bc5274e2c420d5802830a1e4 GIT binary patch literal 4962 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f53b0c09014aada55751c9ee811f82dbc5df9cf GIT binary patch literal 9865 zcmbVSOKcoRdhXXeIm4Hzm!G|UNwX1$S}U>FjO|FKWSg-}38oxpCr)OX(>HaGW&N zHC5HsfBp5>_dn`yS=DM;!SyToAFW^hP*MJs8sk?Ujq|v}_f$o(m4;%gw&tk~m4CH{ z#=m+)=U<~?@Nce>$FJ@cdWA+orFRU}i;W`Jb6%-eZj`y6_a=H1jR~$7yh^XysG?r9 zOWtH}sxig&vNzqEY0Pka0`=L(EY~aEk=|Tmj_XzLXzy6#7}qDgb!Fj%;pHw>9Nu}`uJ;VK?W1dvj)pQKExc7x*9FP40dS3duD$Zg} z)85OyR~oNi9@U;f{nf^+T%Se#wZ?0z@_}L>vFC0n_S~-4IAv?AO6}vhu_$e`_6VYs-MzJ1Y>*2k`Gd(IY!l}%iWJ*T(k zh;Y$#!=~kV!Ioo}%Zu%xzb)MLu3R)9~$fgF>t0G&cg*M`N0ZwF6%| zzHG|vKD}6_zP=^9P1o-P^v0I3`aC5)g=B^N#0mQW)`yO%&sINJzR>Su#SnQwRJrSt zf5R1l-vi|~EqnZ`pm82|_-ho70@y1AdBFWeJMS19Iox@GiE309Q5Fa&*^RzZ+W*us z$!J@1%FcvSur<4Iw?HazE7z!iUfC|+)$9qoa?5B`(VpaX)t*Fq3hilbPubIG&(Qqn znYpXmv-T16%yN4U6pq@*&_3eK(JYwf_+7(3VV^|bQTrMDS?2WENyUB+?>=w8fd1nQ zSu>tXuzDD6*0&`^xnPn|&E5!u=2q8jcg?;CZn(A+nqdO(bmz=YAWYl2;dnuxzJtoA)$^b(e4DE4e_*E^>n6I z%iMB3&-8;WbImcW83}tW4q``HV%~hK$^nAX2HB%F=aq}@kj_g(`3+MZkQkmCy}Jdn|rY5 zgg)3wI|KusIqID?3;PPzA>`y~I&rdq zu%2w+a>s1-H`hl-E^LvQ4>o8!7#xU2I^d1gFvd6dVxcl;Y*9_db>C`ll19)v$JOBf z3{_TAK=t&g-uBqaPZ21SXHNnp7Qu)Ew|>GPGu~dLeRdot#;Sp{emF^K$z*)`#>;y z{Q!)#yQCjo$AUUyS3xy|WlLAGG!OzUZ~M_LwF7WO(}#mT+blou=P#@-EiW^VWE;rn zF{*gZ%zI{vLMt&7&uVtDXK><#UtT>=cJM+1%}+mBHeHDU+e~jO5S!-O0Ba((ZwCX< z&h*k;+a{^Neq$ZxXP8F9KdxgD;b46ongSi9H8Zrg##&Va|>!n3E;sVhZCtB1gY9wpm}7y%oaY>+EY!7uo1=&<~byFS1U1iUU7O&EFF zH>{f{>yYBFL2H<6jBim7bu>p)q`WRN*i1-vk+~aF3z9QM8VLuay>{TA!W5QI5aDO0 zl~`T!1=%%DBGdUk!Z~7Z(YXout_1RZ*h9NjX9iOqoSTFYM06S4;X~av!#;Tg8}n)bT!>L*vS+&L}cJ^!vFb+IMSU&gn@PAsQ)WD$;Z?U<1KFAXG3@0CuP`LGjco;*+{~67tb?Cn6=&;jj2OGX zfi@#Tt`zM~Zd@+p(xmJjE42TOUWN~~*jdz@5 zvT^kg^?2qnamRUt9|PgH3!s->bVkkL)^Ugbf+A8QrKzkdDAmY7sYN-Ix-=q9=5{sl z!${lD-&1z9NV}-~@y6%cPGP5rr$t%7)60>vQH+XTDmx|rZSF0hcPPsn6Z@5@cuy66 zr0iFzwo|&khx%kv_b26)twzPKw6C>Y_0Pe@hPpo;6{1o{yQiwk_4*!8$pcmVGs1Y? zo9WHmLGNwlw%XBb!_M6*g3H+`kMfAE;5?XL8CEjT0)(c(F`Eugh17wyshwR^ClMUM z9n#Tc4-D)nyIKXLzEM}cK@qDrztO~TJQUAS@dAqbVxb%KoCRoJAiLXr*S5m0b7SG6 z6K=|&zwm)8yMwibtFSV#9&WIJc<07~=dLaE**%}DzqJq|;+{|4bhwa3)C&jZJdGte zqOSM1aUS?~e4B+!oMdNg@eEk2m184xyv`Wg zyb~kdc~q=#I@@vXhUE>MIG-@c`y_rqYkY~;Sj?p2pcTG`LaF3c{?p28QLCtBHMuKV zMVr)SwW3@WHK2dfDd;FNNNEz8Ckuu&^I-C`|RfN#=l{UH#U6e{=%{_~Xgx=cft|rwDP3jxQ zer`{>r^@^W&i`L%vdDcU>f2R2IundFu?GFt5l2e6B^!nnr&?nB& zgCelZ4+QZT>jT-2b=Q}10S`iV=p+JC$7I7|c^RYs3U^pUp{Pamm^%5JVf~51X%Zif zcwBcAF~0=@No|R0L_RL0@BAeiiR9JcbKgb$>0+M*iPX3vEtv`aQIknXX2Fvkkz}zo z66~J3uhVY_c{%Ys9@UI-;jLMS<4H{};*od}1)#(zVmvXFM&i0lV_rcqeB+5LdBn{8 z@8Wu&2r~IPYG2{bMD@z|nV_b}h16Kbm9)aCvP9_#57|Y2m7qy|>|3R>uS#u0zo*_& zC4d>JsOd7lha4}wWNS~~FL0kBiyI|bKB?e$Vys@0l`N%oSG%p=)@~ae-PUd6R%J)` zZMIAbQAt7+JfPTlq#? zdEAQ7b}@sqsO+gAh;m=OrzCbF0kRhBu<>jF*vqgA!uFTQ*>GqV7c;3O>N!I4KY=VG z`Tp`#ftCR(aa{*sezcwW@iu54x<-q@CkGfp(n&(xzOkolIW(-eh$Xj)f3Hn8O>kd=1@veHPuk39~ye) zziS0Cf&RGE4?_1Q1q|X6wX0<8MsSJ?S5`SD5U=8)AS;tWi$>RUu|oYHqM)FbpeH_| z9+veRsQn%8kXnjfR1K{RA5NvFPQterxmI~#pArGj>B3`+CVyoiEz zh+|suDfRsUidrtNA}HW6hCglaTyZf?dW+bgEGCB?HC6l}y*AqNU!oNfSBJOUz=j(L zSibBCG0AGe8oOp2TRSIs8as9+I!&BcA`efin zq5I>}E!l(|Zu$*r4T;%-`%*Uau{xYy>b_LCujJ@PX1YR$Nw^ij_4o1iA;ls$GJ-2T zWyMmF)c|Y{Db*{aHa-m9jzY0t;xfehT!;E`Sc0Q$qEIxp2BSynQOhTA9qpH3kTP%y zsel@}HJBh5KZ&3Z;7{xQ74C2v1!0ejO2 z1gWvGQNRH5ZZkVHf8uF2sKy9bK<(dgCvhhDIq_h2dRY73ywr?1$MJ1kA`mtyq>Zbv zv>xl`!5N2kCc7xqp?e8;cpimRB3&Y|36DkkK4S4*$bLtU)O`c#14HH_eHUTpbJZBS<~`>BFDu$}qn*4DH_heRUoi_A2`0+!}o$)46SBr$ z=n+BzLCF$I>*TNt%Fpm+^^y1SUjeR1*AX&Os1|;SR81}_fYM*1mPeWhVI+dL!hVr@ zkpe13MH^K5{{Rllwhnh!ii}<5bA6}0GqF>#4LPxkz-(RJsbWM0pZc%jx4JXQNuY_S z0y_H6R8&Q%nUAJ`g#6b!+!?;uMw4ijsI{(P4OKaX`KO`@yZnXzb2WS;D(_FHz$k|;bnmkUvn%)21u$=lQ^DNlDLr~M)d@n z^;z_l)j5>(ERT4S0*lE9`P?+d!#-%wz}XsF9`*8Xw1-BatUfh!l*|jacTF6@v|>3REOrJoOF7(V94;qsUP~?W~I+G@!z={3DMbO%xBv|Bn69Bvma4O+h6h^rSq$Ph9 U_#ys7urc None: + self.app = app + self.mounts = mounts or {} + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + script = environ.get("PATH_INFO", "") + path_info = "" + + while "/" in script: + if script in self.mounts: + app = self.mounts[script] + break + + script, last_item = script.rsplit("/", 1) + path_info = f"/{last_item}{path_info}" + else: + app = self.mounts.get(script, self.app) + + original_script_name = environ.get("SCRIPT_NAME", "") + environ["SCRIPT_NAME"] = original_script_name + script + environ["PATH_INFO"] = path_info + return app(environ, start_response) diff --git a/venv/lib/python3.9/site-packages/werkzeug/middleware/http_proxy.py b/venv/lib/python3.9/site-packages/werkzeug/middleware/http_proxy.py new file mode 100644 index 0000000..1cde458 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/middleware/http_proxy.py @@ -0,0 +1,230 @@ +""" +Basic HTTP Proxy +================ + +.. autoclass:: ProxyMiddleware + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import typing as t +from http import client + +from ..datastructures import EnvironHeaders +from ..http import is_hop_by_hop_header +from ..urls import url_parse +from ..urls import url_quote +from ..wsgi import get_input_stream + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class ProxyMiddleware: + """Proxy requests under a path to an external server, routing other + requests to the app. + + This middleware can only proxy HTTP requests, as HTTP is the only + protocol handled by the WSGI server. Other protocols, such as + WebSocket requests, cannot be proxied at this layer. This should + only be used for development, in production a real proxy server + should be used. + + The middleware takes a dict mapping a path prefix to a dict + describing the host to be proxied to:: + + app = ProxyMiddleware(app, { + "/static/": { + "target": "http://127.0.0.1:5001/", + } + }) + + Each host has the following options: + + ``target``: + The target URL to dispatch to. This is required. + ``remove_prefix``: + Whether to remove the prefix from the URL before dispatching it + to the target. The default is ``False``. + ``host``: + ``""`` (default): + The host header is automatically rewritten to the URL of the + target. + ``None``: + The host header is unmodified from the client request. + Any other value: + The host header is overwritten with the value. + ``headers``: + A dictionary of headers to be sent with the request to the + target. The default is ``{}``. + ``ssl_context``: + A :class:`ssl.SSLContext` defining how to verify requests if the + target is HTTPS. The default is ``None``. + + In the example above, everything under ``"/static/"`` is proxied to + the server on port 5001. The host header is rewritten to the target, + and the ``"/static/"`` prefix is removed from the URLs. + + :param app: The WSGI application to wrap. + :param targets: Proxy target configurations. See description above. + :param chunk_size: Size of chunks to read from input stream and + write to target. + :param timeout: Seconds before an operation to a target fails. + + .. versionadded:: 0.14 + """ + + def __init__( + self, + app: "WSGIApplication", + targets: t.Mapping[str, t.Dict[str, t.Any]], + chunk_size: int = 2 << 13, + timeout: int = 10, + ) -> None: + def _set_defaults(opts: t.Dict[str, t.Any]) -> t.Dict[str, t.Any]: + opts.setdefault("remove_prefix", False) + opts.setdefault("host", "") + opts.setdefault("headers", {}) + opts.setdefault("ssl_context", None) + return opts + + self.app = app + self.targets = { + f"/{k.strip('/')}/": _set_defaults(v) for k, v in targets.items() + } + self.chunk_size = chunk_size + self.timeout = timeout + + def proxy_to( + self, opts: t.Dict[str, t.Any], path: str, prefix: str + ) -> "WSGIApplication": + target = url_parse(opts["target"]) + host = t.cast(str, target.ascii_host) + + def application( + environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + headers = list(EnvironHeaders(environ).items()) + headers[:] = [ + (k, v) + for k, v in headers + if not is_hop_by_hop_header(k) + and k.lower() not in ("content-length", "host") + ] + headers.append(("Connection", "close")) + + if opts["host"] == "": + headers.append(("Host", host)) + elif opts["host"] is None: + headers.append(("Host", environ["HTTP_HOST"])) + else: + headers.append(("Host", opts["host"])) + + headers.extend(opts["headers"].items()) + remote_path = path + + if opts["remove_prefix"]: + remote_path = remote_path[len(prefix) :].lstrip("/") + remote_path = f"{target.path.rstrip('/')}/{remote_path}" + + content_length = environ.get("CONTENT_LENGTH") + chunked = False + + if content_length not in ("", None): + headers.append(("Content-Length", content_length)) # type: ignore + elif content_length is not None: + headers.append(("Transfer-Encoding", "chunked")) + chunked = True + + try: + if target.scheme == "http": + con = client.HTTPConnection( + host, target.port or 80, timeout=self.timeout + ) + elif target.scheme == "https": + con = client.HTTPSConnection( + host, + target.port or 443, + timeout=self.timeout, + context=opts["ssl_context"], + ) + else: + raise RuntimeError( + "Target scheme must be 'http' or 'https', got" + f" {target.scheme!r}." + ) + + con.connect() + remote_url = url_quote(remote_path) + querystring = environ["QUERY_STRING"] + + if querystring: + remote_url = f"{remote_url}?{querystring}" + + con.putrequest(environ["REQUEST_METHOD"], remote_url, skip_host=True) + + for k, v in headers: + if k.lower() == "connection": + v = "close" + + con.putheader(k, v) + + con.endheaders() + stream = get_input_stream(environ) + + while True: + data = stream.read(self.chunk_size) + + if not data: + break + + if chunked: + con.send(b"%x\r\n%s\r\n" % (len(data), data)) + else: + con.send(data) + + resp = con.getresponse() + except OSError: + from ..exceptions import BadGateway + + return BadGateway()(environ, start_response) + + start_response( + f"{resp.status} {resp.reason}", + [ + (k.title(), v) + for k, v in resp.getheaders() + if not is_hop_by_hop_header(k) + ], + ) + + def read() -> t.Iterator[bytes]: + while True: + try: + data = resp.read(self.chunk_size) + except OSError: + break + + if not data: + break + + yield data + + return read() + + return application + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + path = environ["PATH_INFO"] + app = self.app + + for prefix, opts in self.targets.items(): + if path.startswith(prefix): + app = self.proxy_to(opts, path, prefix) + break + + return app(environ, start_response) diff --git a/venv/lib/python3.9/site-packages/werkzeug/middleware/lint.py b/venv/lib/python3.9/site-packages/werkzeug/middleware/lint.py new file mode 100644 index 0000000..80c423d --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/middleware/lint.py @@ -0,0 +1,420 @@ +""" +WSGI Protocol Linter +==================== + +This module provides a middleware that performs sanity checks on the +behavior of the WSGI server and application. It checks that the +:pep:`3333` WSGI spec is properly implemented. It also warns on some +common HTTP errors such as non-empty responses for 304 status codes. + +.. autoclass:: LintMiddleware + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import typing as t +from types import TracebackType +from urllib.parse import urlparse +from warnings import warn + +from ..datastructures import Headers +from ..http import is_entity_header +from ..wsgi import FileWrapper + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class WSGIWarning(Warning): + """Warning class for WSGI warnings.""" + + +class HTTPWarning(Warning): + """Warning class for HTTP warnings.""" + + +def check_type(context: str, obj: object, need: t.Type = str) -> None: + if type(obj) is not need: + warn( + f"{context!r} requires {need.__name__!r}, got {type(obj).__name__!r}.", + WSGIWarning, + stacklevel=3, + ) + + +class InputStream: + def __init__(self, stream: t.BinaryIO) -> None: + self._stream = stream + + def read(self, *args: t.Any) -> bytes: + if len(args) == 0: + warn( + "WSGI does not guarantee an EOF marker on the input stream, thus making" + " calls to 'wsgi.input.read()' unsafe. Conforming servers may never" + " return from this call.", + WSGIWarning, + stacklevel=2, + ) + elif len(args) != 1: + warn( + "Too many parameters passed to 'wsgi.input.read()'.", + WSGIWarning, + stacklevel=2, + ) + return self._stream.read(*args) + + def readline(self, *args: t.Any) -> bytes: + if len(args) == 0: + warn( + "Calls to 'wsgi.input.readline()' without arguments are unsafe. Use" + " 'wsgi.input.read()' instead.", + WSGIWarning, + stacklevel=2, + ) + elif len(args) == 1: + warn( + "'wsgi.input.readline()' was called with a size hint. WSGI does not" + " support this, although it's available on all major servers.", + WSGIWarning, + stacklevel=2, + ) + else: + raise TypeError("Too many arguments passed to 'wsgi.input.readline()'.") + return self._stream.readline(*args) + + def __iter__(self) -> t.Iterator[bytes]: + try: + return iter(self._stream) + except TypeError: + warn("'wsgi.input' is not iterable.", WSGIWarning, stacklevel=2) + return iter(()) + + def close(self) -> None: + warn("The application closed the input stream!", WSGIWarning, stacklevel=2) + self._stream.close() + + +class ErrorStream: + def __init__(self, stream: t.TextIO) -> None: + self._stream = stream + + def write(self, s: str) -> None: + check_type("wsgi.error.write()", s, str) + self._stream.write(s) + + def flush(self) -> None: + self._stream.flush() + + def writelines(self, seq: t.Iterable[str]) -> None: + for line in seq: + self.write(line) + + def close(self) -> None: + warn("The application closed the error stream!", WSGIWarning, stacklevel=2) + self._stream.close() + + +class GuardedWrite: + def __init__(self, write: t.Callable[[bytes], None], chunks: t.List[int]) -> None: + self._write = write + self._chunks = chunks + + def __call__(self, s: bytes) -> None: + check_type("write()", s, bytes) + self._write(s) + self._chunks.append(len(s)) + + +class GuardedIterator: + def __init__( + self, + iterator: t.Iterable[bytes], + headers_set: t.Tuple[int, Headers], + chunks: t.List[int], + ) -> None: + self._iterator = iterator + self._next = iter(iterator).__next__ + self.closed = False + self.headers_set = headers_set + self.chunks = chunks + + def __iter__(self) -> "GuardedIterator": + return self + + def __next__(self) -> bytes: + if self.closed: + warn("Iterated over closed 'app_iter'.", WSGIWarning, stacklevel=2) + + rv = self._next() + + if not self.headers_set: + warn( + "The application returned before it started the response.", + WSGIWarning, + stacklevel=2, + ) + + check_type("application iterator items", rv, bytes) + self.chunks.append(len(rv)) + return rv + + def close(self) -> None: + self.closed = True + + if hasattr(self._iterator, "close"): + self._iterator.close() # type: ignore + + if self.headers_set: + status_code, headers = self.headers_set + bytes_sent = sum(self.chunks) + content_length = headers.get("content-length", type=int) + + if status_code == 304: + for key, _value in headers: + key = key.lower() + if key not in ("expires", "content-location") and is_entity_header( + key + ): + warn( + f"Entity header {key!r} found in 304 response.", HTTPWarning + ) + if bytes_sent: + warn("304 responses must not have a body.", HTTPWarning) + elif 100 <= status_code < 200 or status_code == 204: + if content_length != 0: + warn( + f"{status_code} responses must have an empty content length.", + HTTPWarning, + ) + if bytes_sent: + warn(f"{status_code} responses must not have a body.", HTTPWarning) + elif content_length is not None and content_length != bytes_sent: + warn( + "Content-Length and the number of bytes sent to the" + " client do not match.", + WSGIWarning, + ) + + def __del__(self) -> None: + if not self.closed: + try: + warn( + "Iterator was garbage collected before it was closed.", WSGIWarning + ) + except Exception: + pass + + +class LintMiddleware: + """Warns about common errors in the WSGI and HTTP behavior of the + server and wrapped application. Some of the issues it checks are: + + - invalid status codes + - non-bytes sent to the WSGI server + - strings returned from the WSGI application + - non-empty conditional responses + - unquoted etags + - relative URLs in the Location header + - unsafe calls to wsgi.input + - unclosed iterators + + Error information is emitted using the :mod:`warnings` module. + + :param app: The WSGI application to wrap. + + .. code-block:: python + + from werkzeug.middleware.lint import LintMiddleware + app = LintMiddleware(app) + """ + + def __init__(self, app: "WSGIApplication") -> None: + self.app = app + + def check_environ(self, environ: "WSGIEnvironment") -> None: + if type(environ) is not dict: + warn( + "WSGI environment is not a standard Python dict.", + WSGIWarning, + stacklevel=4, + ) + for key in ( + "REQUEST_METHOD", + "SERVER_NAME", + "SERVER_PORT", + "wsgi.version", + "wsgi.input", + "wsgi.errors", + "wsgi.multithread", + "wsgi.multiprocess", + "wsgi.run_once", + ): + if key not in environ: + warn( + f"Required environment key {key!r} not found", + WSGIWarning, + stacklevel=3, + ) + if environ["wsgi.version"] != (1, 0): + warn("Environ is not a WSGI 1.0 environ.", WSGIWarning, stacklevel=3) + + script_name = environ.get("SCRIPT_NAME", "") + path_info = environ.get("PATH_INFO", "") + + if script_name and script_name[0] != "/": + warn( + f"'SCRIPT_NAME' does not start with a slash: {script_name!r}", + WSGIWarning, + stacklevel=3, + ) + + if path_info and path_info[0] != "/": + warn( + f"'PATH_INFO' does not start with a slash: {path_info!r}", + WSGIWarning, + stacklevel=3, + ) + + def check_start_response( + self, + status: str, + headers: t.List[t.Tuple[str, str]], + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ], + ) -> t.Tuple[int, Headers]: + check_type("status", status, str) + status_code_str = status.split(None, 1)[0] + + if len(status_code_str) != 3 or not status_code_str.isdigit(): + warn("Status code must be three digits.", WSGIWarning, stacklevel=3) + + if len(status) < 4 or status[3] != " ": + warn( + f"Invalid value for status {status!r}. Valid status strings are three" + " digits, a space and a status explanation.", + WSGIWarning, + stacklevel=3, + ) + + status_code = int(status_code_str) + + if status_code < 100: + warn("Status code < 100 detected.", WSGIWarning, stacklevel=3) + + if type(headers) is not list: + warn("Header list is not a list.", WSGIWarning, stacklevel=3) + + for item in headers: + if type(item) is not tuple or len(item) != 2: + warn("Header items must be 2-item tuples.", WSGIWarning, stacklevel=3) + name, value = item + if type(name) is not str or type(value) is not str: + warn( + "Header keys and values must be strings.", WSGIWarning, stacklevel=3 + ) + if name.lower() == "status": + warn( + "The status header is not supported due to" + " conflicts with the CGI spec.", + WSGIWarning, + stacklevel=3, + ) + + if exc_info is not None and not isinstance(exc_info, tuple): + warn("Invalid value for exc_info.", WSGIWarning, stacklevel=3) + + headers = Headers(headers) + self.check_headers(headers) + + return status_code, headers + + def check_headers(self, headers: Headers) -> None: + etag = headers.get("etag") + + if etag is not None: + if etag.startswith(("W/", "w/")): + if etag.startswith("w/"): + warn( + "Weak etag indicator should be upper case.", + HTTPWarning, + stacklevel=4, + ) + + etag = etag[2:] + + if not (etag[:1] == etag[-1:] == '"'): + warn("Unquoted etag emitted.", HTTPWarning, stacklevel=4) + + location = headers.get("location") + + if location is not None: + if not urlparse(location).netloc: + warn( + "Absolute URLs required for location header.", + HTTPWarning, + stacklevel=4, + ) + + def check_iterator(self, app_iter: t.Iterable[bytes]) -> None: + if isinstance(app_iter, bytes): + warn( + "The application returned a bytestring. The response will send one" + " character at a time to the client, which will kill performance." + " Return a list or iterable instead.", + WSGIWarning, + stacklevel=3, + ) + + def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Iterable[bytes]: + if len(args) != 2: + warn("A WSGI app takes two arguments.", WSGIWarning, stacklevel=2) + + if kwargs: + warn( + "A WSGI app does not take keyword arguments.", WSGIWarning, stacklevel=2 + ) + + environ: "WSGIEnvironment" = args[0] + start_response: "StartResponse" = args[1] + + self.check_environ(environ) + environ["wsgi.input"] = InputStream(environ["wsgi.input"]) + environ["wsgi.errors"] = ErrorStream(environ["wsgi.errors"]) + + # Hook our own file wrapper in so that applications will always + # iterate to the end and we can check the content length. + environ["wsgi.file_wrapper"] = FileWrapper + + headers_set: t.List[t.Any] = [] + chunks: t.List[int] = [] + + def checking_start_response( + *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[bytes], None]: + if len(args) not in {2, 3}: + warn( + f"Invalid number of arguments: {len(args)}, expected 2 or 3.", + WSGIWarning, + stacklevel=2, + ) + + if kwargs: + warn("'start_response' does not take keyword arguments.", WSGIWarning) + + status: str = args[0] + headers: t.List[t.Tuple[str, str]] = args[1] + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ] = (args[2] if len(args) == 3 else None) + + headers_set[:] = self.check_start_response(status, headers, exc_info) + return GuardedWrite(start_response(status, headers, exc_info), chunks) + + app_iter = self.app(environ, t.cast("StartResponse", checking_start_response)) + self.check_iterator(app_iter) + return GuardedIterator( + app_iter, t.cast(t.Tuple[int, Headers], headers_set), chunks + ) diff --git a/venv/lib/python3.9/site-packages/werkzeug/middleware/profiler.py b/venv/lib/python3.9/site-packages/werkzeug/middleware/profiler.py new file mode 100644 index 0000000..0992f8f --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/middleware/profiler.py @@ -0,0 +1,139 @@ +""" +Application Profiler +==================== + +This module provides a middleware that profiles each request with the +:mod:`cProfile` module. This can help identify bottlenecks in your code +that may be slowing down your application. + +.. autoclass:: ProfilerMiddleware + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import os.path +import sys +import time +import typing as t +from pstats import Stats + +try: + from cProfile import Profile +except ImportError: + from profile import Profile # type: ignore + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class ProfilerMiddleware: + """Wrap a WSGI application and profile the execution of each + request. Responses are buffered so that timings are more exact. + + If ``stream`` is given, :class:`pstats.Stats` are written to it + after each request. If ``profile_dir`` is given, :mod:`cProfile` + data files are saved to that directory, one file per request. + + The filename can be customized by passing ``filename_format``. If + it is a string, it will be formatted using :meth:`str.format` with + the following fields available: + + - ``{method}`` - The request method; GET, POST, etc. + - ``{path}`` - The request path or 'root' should one not exist. + - ``{elapsed}`` - The elapsed time of the request. + - ``{time}`` - The time of the request. + + If it is a callable, it will be called with the WSGI ``environ`` + dict and should return a filename. + + :param app: The WSGI application to wrap. + :param stream: Write stats to this stream. Disable with ``None``. + :param sort_by: A tuple of columns to sort stats by. See + :meth:`pstats.Stats.sort_stats`. + :param restrictions: A tuple of restrictions to filter stats by. See + :meth:`pstats.Stats.print_stats`. + :param profile_dir: Save profile data files to this directory. + :param filename_format: Format string for profile data file names, + or a callable returning a name. See explanation above. + + .. code-block:: python + + from werkzeug.middleware.profiler import ProfilerMiddleware + app = ProfilerMiddleware(app) + + .. versionchanged:: 0.15 + Stats are written even if ``profile_dir`` is given, and can be + disable by passing ``stream=None``. + + .. versionadded:: 0.15 + Added ``filename_format``. + + .. versionadded:: 0.9 + Added ``restrictions`` and ``profile_dir``. + """ + + def __init__( + self, + app: "WSGIApplication", + stream: t.TextIO = sys.stdout, + sort_by: t.Iterable[str] = ("time", "calls"), + restrictions: t.Iterable[t.Union[str, int, float]] = (), + profile_dir: t.Optional[str] = None, + filename_format: str = "{method}.{path}.{elapsed:.0f}ms.{time:.0f}.prof", + ) -> None: + self._app = app + self._stream = stream + self._sort_by = sort_by + self._restrictions = restrictions + self._profile_dir = profile_dir + self._filename_format = filename_format + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + response_body: t.List[bytes] = [] + + def catching_start_response(status, headers, exc_info=None): # type: ignore + start_response(status, headers, exc_info) + return response_body.append + + def runapp() -> None: + app_iter = self._app( + environ, t.cast("StartResponse", catching_start_response) + ) + response_body.extend(app_iter) + + if hasattr(app_iter, "close"): + app_iter.close() # type: ignore + + profile = Profile() + start = time.time() + profile.runcall(runapp) + body = b"".join(response_body) + elapsed = time.time() - start + + if self._profile_dir is not None: + if callable(self._filename_format): + filename = self._filename_format(environ) + else: + filename = self._filename_format.format( + method=environ["REQUEST_METHOD"], + path=environ["PATH_INFO"].strip("/").replace("/", ".") or "root", + elapsed=elapsed * 1000.0, + time=time.time(), + ) + filename = os.path.join(self._profile_dir, filename) + profile.dump_stats(filename) + + if self._stream is not None: + stats = Stats(profile, stream=self._stream) + stats.sort_stats(*self._sort_by) + print("-" * 80, file=self._stream) + path_info = environ.get("PATH_INFO", "") + print(f"PATH: {path_info!r}", file=self._stream) + stats.print_stats(*self._restrictions) + print(f"{'-' * 80}\n", file=self._stream) + + return [body] diff --git a/venv/lib/python3.9/site-packages/werkzeug/middleware/proxy_fix.py b/venv/lib/python3.9/site-packages/werkzeug/middleware/proxy_fix.py new file mode 100644 index 0000000..e90b1b3 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/middleware/proxy_fix.py @@ -0,0 +1,187 @@ +""" +X-Forwarded-For Proxy Fix +========================= + +This module provides a middleware that adjusts the WSGI environ based on +``X-Forwarded-`` headers that proxies in front of an application may +set. + +When an application is running behind a proxy server, WSGI may see the +request as coming from that server rather than the real client. Proxies +set various headers to track where the request actually came from. + +This middleware should only be used if the application is actually +behind such a proxy, and should be configured with the number of proxies +that are chained in front of it. Not all proxies set all the headers. +Since incoming headers can be faked, you must set how many proxies are +setting each header so the middleware knows what to trust. + +.. autoclass:: ProxyFix + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import typing as t + +from ..http import parse_list_header + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class ProxyFix: + """Adjust the WSGI environ based on ``X-Forwarded-`` that proxies in + front of the application may set. + + - ``X-Forwarded-For`` sets ``REMOTE_ADDR``. + - ``X-Forwarded-Proto`` sets ``wsgi.url_scheme``. + - ``X-Forwarded-Host`` sets ``HTTP_HOST``, ``SERVER_NAME``, and + ``SERVER_PORT``. + - ``X-Forwarded-Port`` sets ``HTTP_HOST`` and ``SERVER_PORT``. + - ``X-Forwarded-Prefix`` sets ``SCRIPT_NAME``. + + You must tell the middleware how many proxies set each header so it + knows what values to trust. It is a security issue to trust values + that came from the client rather than a proxy. + + The original values of the headers are stored in the WSGI + environ as ``werkzeug.proxy_fix.orig``, a dict. + + :param app: The WSGI application to wrap. + :param x_for: Number of values to trust for ``X-Forwarded-For``. + :param x_proto: Number of values to trust for ``X-Forwarded-Proto``. + :param x_host: Number of values to trust for ``X-Forwarded-Host``. + :param x_port: Number of values to trust for ``X-Forwarded-Port``. + :param x_prefix: Number of values to trust for + ``X-Forwarded-Prefix``. + + .. code-block:: python + + from werkzeug.middleware.proxy_fix import ProxyFix + # App is behind one proxy that sets the -For and -Host headers. + app = ProxyFix(app, x_for=1, x_host=1) + + .. versionchanged:: 1.0 + Deprecated code has been removed: + + * The ``num_proxies`` argument and attribute. + * The ``get_remote_addr`` method. + * The environ keys ``orig_remote_addr``, + ``orig_wsgi_url_scheme``, and ``orig_http_host``. + + .. versionchanged:: 0.15 + All headers support multiple values. The ``num_proxies`` + argument is deprecated. Each header is configured with a + separate number of trusted proxies. + + .. versionchanged:: 0.15 + Original WSGI environ values are stored in the + ``werkzeug.proxy_fix.orig`` dict. ``orig_remote_addr``, + ``orig_wsgi_url_scheme``, and ``orig_http_host`` are deprecated + and will be removed in 1.0. + + .. versionchanged:: 0.15 + Support ``X-Forwarded-Port`` and ``X-Forwarded-Prefix``. + + .. versionchanged:: 0.15 + ``X-Forwarded-Host`` and ``X-Forwarded-Port`` modify + ``SERVER_NAME`` and ``SERVER_PORT``. + """ + + def __init__( + self, + app: "WSGIApplication", + x_for: int = 1, + x_proto: int = 1, + x_host: int = 0, + x_port: int = 0, + x_prefix: int = 0, + ) -> None: + self.app = app + self.x_for = x_for + self.x_proto = x_proto + self.x_host = x_host + self.x_port = x_port + self.x_prefix = x_prefix + + def _get_real_value(self, trusted: int, value: t.Optional[str]) -> t.Optional[str]: + """Get the real value from a list header based on the configured + number of trusted proxies. + + :param trusted: Number of values to trust in the header. + :param value: Comma separated list header value to parse. + :return: The real value, or ``None`` if there are fewer values + than the number of trusted proxies. + + .. versionchanged:: 1.0 + Renamed from ``_get_trusted_comma``. + + .. versionadded:: 0.15 + """ + if not (trusted and value): + return None + values = parse_list_header(value) + if len(values) >= trusted: + return values[-trusted] + return None + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + """Modify the WSGI environ based on the various ``Forwarded`` + headers before calling the wrapped application. Store the + original environ values in ``werkzeug.proxy_fix.orig_{key}``. + """ + environ_get = environ.get + orig_remote_addr = environ_get("REMOTE_ADDR") + orig_wsgi_url_scheme = environ_get("wsgi.url_scheme") + orig_http_host = environ_get("HTTP_HOST") + environ.update( + { + "werkzeug.proxy_fix.orig": { + "REMOTE_ADDR": orig_remote_addr, + "wsgi.url_scheme": orig_wsgi_url_scheme, + "HTTP_HOST": orig_http_host, + "SERVER_NAME": environ_get("SERVER_NAME"), + "SERVER_PORT": environ_get("SERVER_PORT"), + "SCRIPT_NAME": environ_get("SCRIPT_NAME"), + } + } + ) + + x_for = self._get_real_value(self.x_for, environ_get("HTTP_X_FORWARDED_FOR")) + if x_for: + environ["REMOTE_ADDR"] = x_for + + x_proto = self._get_real_value( + self.x_proto, environ_get("HTTP_X_FORWARDED_PROTO") + ) + if x_proto: + environ["wsgi.url_scheme"] = x_proto + + x_host = self._get_real_value(self.x_host, environ_get("HTTP_X_FORWARDED_HOST")) + if x_host: + environ["HTTP_HOST"] = x_host + parts = x_host.split(":", 1) + environ["SERVER_NAME"] = parts[0] + if len(parts) == 2: + environ["SERVER_PORT"] = parts[1] + + x_port = self._get_real_value(self.x_port, environ_get("HTTP_X_FORWARDED_PORT")) + if x_port: + host = environ.get("HTTP_HOST") + if host: + parts = host.split(":", 1) + host = parts[0] if len(parts) == 2 else host + environ["HTTP_HOST"] = f"{host}:{x_port}" + environ["SERVER_PORT"] = x_port + + x_prefix = self._get_real_value( + self.x_prefix, environ_get("HTTP_X_FORWARDED_PREFIX") + ) + if x_prefix: + environ["SCRIPT_NAME"] = x_prefix + + return self.app(environ, start_response) diff --git a/venv/lib/python3.9/site-packages/werkzeug/middleware/shared_data.py b/venv/lib/python3.9/site-packages/werkzeug/middleware/shared_data.py new file mode 100644 index 0000000..f11b43a --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/middleware/shared_data.py @@ -0,0 +1,320 @@ +""" +Serve Shared Static Files +========================= + +.. autoclass:: SharedDataMiddleware + :members: is_allowed + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import mimetypes +import os +import pkgutil +import posixpath +import typing as t +from datetime import datetime +from datetime import timezone +from io import BytesIO +from time import time +from zlib import adler32 + +from ..filesystem import get_filesystem_encoding +from ..http import http_date +from ..http import is_resource_modified +from ..security import safe_join +from ..utils import get_content_type +from ..wsgi import get_path_info +from ..wsgi import wrap_file + +_TOpener = t.Callable[[], t.Tuple[t.BinaryIO, datetime, int]] +_TLoader = t.Callable[[t.Optional[str]], t.Tuple[t.Optional[str], t.Optional[_TOpener]]] + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class SharedDataMiddleware: + + """A WSGI middleware which provides static content for development + environments or simple server setups. Its usage is quite simple:: + + import os + from werkzeug.middleware.shared_data import SharedDataMiddleware + + app = SharedDataMiddleware(app, { + '/shared': os.path.join(os.path.dirname(__file__), 'shared') + }) + + The contents of the folder ``./shared`` will now be available on + ``http://example.com/shared/``. This is pretty useful during development + because a standalone media server is not required. Files can also be + mounted on the root folder and still continue to use the application because + the shared data middleware forwards all unhandled requests to the + application, even if the requests are below one of the shared folders. + + If `pkg_resources` is available you can also tell the middleware to serve + files from package data:: + + app = SharedDataMiddleware(app, { + '/static': ('myapplication', 'static') + }) + + This will then serve the ``static`` folder in the `myapplication` + Python package. + + The optional `disallow` parameter can be a list of :func:`~fnmatch.fnmatch` + rules for files that are not accessible from the web. If `cache` is set to + `False` no caching headers are sent. + + Currently the middleware does not support non-ASCII filenames. If the + encoding on the file system happens to match the encoding of the URI it may + work but this could also be by accident. We strongly suggest using ASCII + only file names for static files. + + The middleware will guess the mimetype using the Python `mimetype` + module. If it's unable to figure out the charset it will fall back + to `fallback_mimetype`. + + :param app: the application to wrap. If you don't want to wrap an + application you can pass it :exc:`NotFound`. + :param exports: a list or dict of exported files and folders. + :param disallow: a list of :func:`~fnmatch.fnmatch` rules. + :param cache: enable or disable caching headers. + :param cache_timeout: the cache timeout in seconds for the headers. + :param fallback_mimetype: The fallback mimetype for unknown files. + + .. versionchanged:: 1.0 + The default ``fallback_mimetype`` is + ``application/octet-stream``. If a filename looks like a text + mimetype, the ``utf-8`` charset is added to it. + + .. versionadded:: 0.6 + Added ``fallback_mimetype``. + + .. versionchanged:: 0.5 + Added ``cache_timeout``. + """ + + def __init__( + self, + app: "WSGIApplication", + exports: t.Union[ + t.Dict[str, t.Union[str, t.Tuple[str, str]]], + t.Iterable[t.Tuple[str, t.Union[str, t.Tuple[str, str]]]], + ], + disallow: None = None, + cache: bool = True, + cache_timeout: int = 60 * 60 * 12, + fallback_mimetype: str = "application/octet-stream", + ) -> None: + self.app = app + self.exports: t.List[t.Tuple[str, _TLoader]] = [] + self.cache = cache + self.cache_timeout = cache_timeout + + if isinstance(exports, dict): + exports = exports.items() + + for key, value in exports: + if isinstance(value, tuple): + loader = self.get_package_loader(*value) + elif isinstance(value, str): + if os.path.isfile(value): + loader = self.get_file_loader(value) + else: + loader = self.get_directory_loader(value) + else: + raise TypeError(f"unknown def {value!r}") + + self.exports.append((key, loader)) + + if disallow is not None: + from fnmatch import fnmatch + + self.is_allowed = lambda x: not fnmatch(x, disallow) + + self.fallback_mimetype = fallback_mimetype + + def is_allowed(self, filename: str) -> bool: + """Subclasses can override this method to disallow the access to + certain files. However by providing `disallow` in the constructor + this method is overwritten. + """ + return True + + def _opener(self, filename: str) -> _TOpener: + return lambda: ( + open(filename, "rb"), + datetime.fromtimestamp(os.path.getmtime(filename), tz=timezone.utc), + int(os.path.getsize(filename)), + ) + + def get_file_loader(self, filename: str) -> _TLoader: + return lambda x: (os.path.basename(filename), self._opener(filename)) + + def get_package_loader(self, package: str, package_path: str) -> _TLoader: + load_time = datetime.now(timezone.utc) + provider = pkgutil.get_loader(package) + + if hasattr(provider, "get_resource_reader"): + # Python 3 + reader = provider.get_resource_reader(package) # type: ignore + + def loader( + path: t.Optional[str], + ) -> t.Tuple[t.Optional[str], t.Optional[_TOpener]]: + if path is None: + return None, None + + path = safe_join(package_path, path) + + if path is None: + return None, None + + basename = posixpath.basename(path) + + try: + resource = reader.open_resource(path) + except OSError: + return None, None + + if isinstance(resource, BytesIO): + return ( + basename, + lambda: (resource, load_time, len(resource.getvalue())), + ) + + return ( + basename, + lambda: ( + resource, + datetime.fromtimestamp( + os.path.getmtime(resource.name), tz=timezone.utc + ), + os.path.getsize(resource.name), + ), + ) + + else: + # Python 3.6 + package_filename = provider.get_filename(package) # type: ignore + is_filesystem = os.path.exists(package_filename) + root = os.path.join(os.path.dirname(package_filename), package_path) + + def loader( + path: t.Optional[str], + ) -> t.Tuple[t.Optional[str], t.Optional[_TOpener]]: + if path is None: + return None, None + + path = safe_join(root, path) + + if path is None: + return None, None + + basename = posixpath.basename(path) + + if is_filesystem: + if not os.path.isfile(path): + return None, None + + return basename, self._opener(path) + + try: + data = provider.get_data(path) # type: ignore + except OSError: + return None, None + + return basename, lambda: (BytesIO(data), load_time, len(data)) + + return loader + + def get_directory_loader(self, directory: str) -> _TLoader: + def loader( + path: t.Optional[str], + ) -> t.Tuple[t.Optional[str], t.Optional[_TOpener]]: + if path is not None: + path = safe_join(directory, path) + + if path is None: + return None, None + else: + path = directory + + if os.path.isfile(path): + return os.path.basename(path), self._opener(path) + + return None, None + + return loader + + def generate_etag(self, mtime: datetime, file_size: int, real_filename: str) -> str: + if not isinstance(real_filename, bytes): + real_filename = real_filename.encode( # type: ignore + get_filesystem_encoding() + ) + + timestamp = mtime.timestamp() + checksum = adler32(real_filename) & 0xFFFFFFFF # type: ignore + return f"wzsdm-{timestamp}-{file_size}-{checksum}" + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + path = get_path_info(environ) + file_loader = None + + for search_path, loader in self.exports: + if search_path == path: + real_filename, file_loader = loader(None) + + if file_loader is not None: + break + + if not search_path.endswith("/"): + search_path += "/" + + if path.startswith(search_path): + real_filename, file_loader = loader(path[len(search_path) :]) + + if file_loader is not None: + break + + if file_loader is None or not self.is_allowed(real_filename): # type: ignore + return self.app(environ, start_response) + + guessed_type = mimetypes.guess_type(real_filename) # type: ignore + mime_type = get_content_type(guessed_type[0] or self.fallback_mimetype, "utf-8") + f, mtime, file_size = file_loader() + + headers = [("Date", http_date())] + + if self.cache: + timeout = self.cache_timeout + etag = self.generate_etag(mtime, file_size, real_filename) # type: ignore + headers += [ + ("Etag", f'"{etag}"'), + ("Cache-Control", f"max-age={timeout}, public"), + ] + + if not is_resource_modified(environ, etag, last_modified=mtime): + f.close() + start_response("304 Not Modified", headers) + return [] + + headers.append(("Expires", http_date(time() + timeout))) + else: + headers.append(("Cache-Control", "public")) + + headers.extend( + ( + ("Content-Type", mime_type), + ("Content-Length", str(file_size)), + ("Last-Modified", http_date(mtime)), + ) + ) + start_response("200 OK", headers) + return wrap_file(environ, f) diff --git a/venv/lib/python3.9/site-packages/werkzeug/py.typed b/venv/lib/python3.9/site-packages/werkzeug/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.9/site-packages/werkzeug/routing.py b/venv/lib/python3.9/site-packages/werkzeug/routing.py new file mode 100644 index 0000000..1043875 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/routing.py @@ -0,0 +1,2332 @@ +"""When it comes to combining multiple controller or view functions +(however you want to call them) you need a dispatcher. A simple way +would be applying regular expression tests on the ``PATH_INFO`` and +calling registered callback functions that return the value then. + +This module implements a much more powerful system than simple regular +expression matching because it can also convert values in the URLs and +build URLs. + +Here a simple example that creates a URL map for an application with +two subdomains (www and kb) and some URL rules: + +.. code-block:: python + + m = Map([ + # Static URLs + Rule('/', endpoint='static/index'), + Rule('/about', endpoint='static/about'), + Rule('/help', endpoint='static/help'), + # Knowledge Base + Subdomain('kb', [ + Rule('/', endpoint='kb/index'), + Rule('/browse/', endpoint='kb/browse'), + Rule('/browse//', endpoint='kb/browse'), + Rule('/browse//', endpoint='kb/browse') + ]) + ], default_subdomain='www') + +If the application doesn't use subdomains it's perfectly fine to not set +the default subdomain and not use the `Subdomain` rule factory. The +endpoint in the rules can be anything, for example import paths or +unique identifiers. The WSGI application can use those endpoints to get the +handler for that URL. It doesn't have to be a string at all but it's +recommended. + +Now it's possible to create a URL adapter for one of the subdomains and +build URLs: + +.. code-block:: python + + c = m.bind('example.com') + + c.build("kb/browse", dict(id=42)) + 'http://kb.example.com/browse/42/' + + c.build("kb/browse", dict()) + 'http://kb.example.com/browse/' + + c.build("kb/browse", dict(id=42, page=3)) + 'http://kb.example.com/browse/42/3' + + c.build("static/about") + '/about' + + c.build("static/index", force_external=True) + 'http://www.example.com/' + + c = m.bind('example.com', subdomain='kb') + + c.build("static/about") + 'http://www.example.com/about' + +The first argument to bind is the server name *without* the subdomain. +Per default it will assume that the script is mounted on the root, but +often that's not the case so you can provide the real mount point as +second argument: + +.. code-block:: python + + c = m.bind('example.com', '/applications/example') + +The third argument can be the subdomain, if not given the default +subdomain is used. For more details about binding have a look at the +documentation of the `MapAdapter`. + +And here is how you can match URLs: + +.. code-block:: python + + c = m.bind('example.com') + + c.match("/") + ('static/index', {}) + + c.match("/about") + ('static/about', {}) + + c = m.bind('example.com', '/', 'kb') + + c.match("/") + ('kb/index', {}) + + c.match("/browse/42/23") + ('kb/browse', {'id': 42, 'page': 23}) + +If matching fails you get a ``NotFound`` exception, if the rule thinks +it's a good idea to redirect (for example because the URL was defined +to have a slash at the end but the request was missing that slash) it +will raise a ``RequestRedirect`` exception. Both are subclasses of +``HTTPException`` so you can use those errors as responses in the +application. + +If matching succeeded but the URL rule was incompatible to the given +method (for example there were only rules for ``GET`` and ``HEAD`` but +routing tried to match a ``POST`` request) a ``MethodNotAllowed`` +exception is raised. +""" +import ast +import difflib +import posixpath +import re +import typing +import typing as t +import uuid +import warnings +from pprint import pformat +from string import Template +from threading import Lock +from types import CodeType + +from ._internal import _encode_idna +from ._internal import _get_environ +from ._internal import _to_bytes +from ._internal import _to_str +from ._internal import _wsgi_decoding_dance +from .datastructures import ImmutableDict +from .datastructures import MultiDict +from .exceptions import BadHost +from .exceptions import BadRequest +from .exceptions import HTTPException +from .exceptions import MethodNotAllowed +from .exceptions import NotFound +from .urls import _fast_url_quote +from .urls import url_encode +from .urls import url_join +from .urls import url_quote +from .utils import cached_property +from .utils import redirect +from .wsgi import get_host + +if t.TYPE_CHECKING: + import typing_extensions as te + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + from .wrappers.response import Response + +_rule_re = re.compile( + r""" + (?P[^<]*) # static rule data + < + (?: + (?P[a-zA-Z_][a-zA-Z0-9_]*) # converter name + (?:\((?P.*?)\))? # converter arguments + \: # variable delimiter + )? + (?P[a-zA-Z_][a-zA-Z0-9_]*) # variable name + > + """, + re.VERBOSE, +) +_simple_rule_re = re.compile(r"<([^>]+)>") +_converter_args_re = re.compile( + r""" + ((?P\w+)\s*=\s*)? + (?P + True|False| + \d+.\d+| + \d+.| + \d+| + [\w\d_.]+| + [urUR]?(?P"[^"]*?"|'[^']*') + )\s*, + """, + re.VERBOSE, +) + + +_PYTHON_CONSTANTS = {"None": None, "True": True, "False": False} + + +def _pythonize(value: str) -> t.Union[None, bool, int, float, str]: + if value in _PYTHON_CONSTANTS: + return _PYTHON_CONSTANTS[value] + for convert in int, float: + try: + return convert(value) # type: ignore + except ValueError: + pass + if value[:1] == value[-1:] and value[0] in "\"'": + value = value[1:-1] + return str(value) + + +def parse_converter_args(argstr: str) -> t.Tuple[t.Tuple, t.Dict[str, t.Any]]: + argstr += "," + args = [] + kwargs = {} + + for item in _converter_args_re.finditer(argstr): + value = item.group("stringval") + if value is None: + value = item.group("value") + value = _pythonize(value) + if not item.group("name"): + args.append(value) + else: + name = item.group("name") + kwargs[name] = value + + return tuple(args), kwargs + + +def parse_rule(rule: str) -> t.Iterator[t.Tuple[t.Optional[str], t.Optional[str], str]]: + """Parse a rule and return it as generator. Each iteration yields tuples + in the form ``(converter, arguments, variable)``. If the converter is + `None` it's a static url part, otherwise it's a dynamic one. + + :internal: + """ + pos = 0 + end = len(rule) + do_match = _rule_re.match + used_names = set() + while pos < end: + m = do_match(rule, pos) + if m is None: + break + data = m.groupdict() + if data["static"]: + yield None, None, data["static"] + variable = data["variable"] + converter = data["converter"] or "default" + if variable in used_names: + raise ValueError(f"variable name {variable!r} used twice.") + used_names.add(variable) + yield converter, data["args"] or None, variable + pos = m.end() + if pos < end: + remaining = rule[pos:] + if ">" in remaining or "<" in remaining: + raise ValueError(f"malformed url rule: {rule!r}") + yield None, None, remaining + + +class RoutingException(Exception): + """Special exceptions that require the application to redirect, notifying + about missing urls, etc. + + :internal: + """ + + +class RequestRedirect(HTTPException, RoutingException): + """Raise if the map requests a redirect. This is for example the case if + `strict_slashes` are activated and an url that requires a trailing slash. + + The attribute `new_url` contains the absolute destination url. + """ + + code = 308 + + def __init__(self, new_url: str) -> None: + super().__init__(new_url) + self.new_url = new_url + + def get_response( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> "Response": + return redirect(self.new_url, self.code) + + +class RequestPath(RoutingException): + """Internal exception.""" + + __slots__ = ("path_info",) + + def __init__(self, path_info: str) -> None: + super().__init__() + self.path_info = path_info + + +class RequestAliasRedirect(RoutingException): # noqa: B903 + """This rule is an alias and wants to redirect to the canonical URL.""" + + def __init__(self, matched_values: t.Mapping[str, t.Any]) -> None: + super().__init__() + self.matched_values = matched_values + + +class BuildError(RoutingException, LookupError): + """Raised if the build system cannot find a URL for an endpoint with the + values provided. + """ + + def __init__( + self, + endpoint: str, + values: t.Mapping[str, t.Any], + method: t.Optional[str], + adapter: t.Optional["MapAdapter"] = None, + ) -> None: + super().__init__(endpoint, values, method) + self.endpoint = endpoint + self.values = values + self.method = method + self.adapter = adapter + + @cached_property + def suggested(self) -> t.Optional["Rule"]: + return self.closest_rule(self.adapter) + + def closest_rule(self, adapter: t.Optional["MapAdapter"]) -> t.Optional["Rule"]: + def _score_rule(rule: "Rule") -> float: + return sum( + [ + 0.98 + * difflib.SequenceMatcher( + None, rule.endpoint, self.endpoint + ).ratio(), + 0.01 * bool(set(self.values or ()).issubset(rule.arguments)), + 0.01 * bool(rule.methods and self.method in rule.methods), + ] + ) + + if adapter and adapter.map._rules: + return max(adapter.map._rules, key=_score_rule) + + return None + + def __str__(self) -> str: + message = [f"Could not build url for endpoint {self.endpoint!r}"] + if self.method: + message.append(f" ({self.method!r})") + if self.values: + message.append(f" with values {sorted(self.values)!r}") + message.append(".") + if self.suggested: + if self.endpoint == self.suggested.endpoint: + if ( + self.method + and self.suggested.methods is not None + and self.method not in self.suggested.methods + ): + message.append( + " Did you mean to use methods" + f" {sorted(self.suggested.methods)!r}?" + ) + missing_values = self.suggested.arguments.union( + set(self.suggested.defaults or ()) + ) - set(self.values.keys()) + if missing_values: + message.append( + f" Did you forget to specify values {sorted(missing_values)!r}?" + ) + else: + message.append(f" Did you mean {self.suggested.endpoint!r} instead?") + return "".join(message) + + +class WebsocketMismatch(BadRequest): + """The only matched rule is either a WebSocket and the request is + HTTP, or the rule is HTTP and the request is a WebSocket. + """ + + +class ValidationError(ValueError): + """Validation error. If a rule converter raises this exception the rule + does not match the current URL and the next URL is tried. + """ + + +class RuleFactory: + """As soon as you have more complex URL setups it's a good idea to use rule + factories to avoid repetitive tasks. Some of them are builtin, others can + be added by subclassing `RuleFactory` and overriding `get_rules`. + """ + + def get_rules(self, map: "Map") -> t.Iterable["Rule"]: + """Subclasses of `RuleFactory` have to override this method and return + an iterable of rules.""" + raise NotImplementedError() + + +class Subdomain(RuleFactory): + """All URLs provided by this factory have the subdomain set to a + specific domain. For example if you want to use the subdomain for + the current language this can be a good setup:: + + url_map = Map([ + Rule('/', endpoint='#select_language'), + Subdomain('', [ + Rule('/', endpoint='index'), + Rule('/about', endpoint='about'), + Rule('/help', endpoint='help') + ]) + ]) + + All the rules except for the ``'#select_language'`` endpoint will now + listen on a two letter long subdomain that holds the language code + for the current request. + """ + + def __init__(self, subdomain: str, rules: t.Iterable["Rule"]) -> None: + self.subdomain = subdomain + self.rules = rules + + def get_rules(self, map: "Map") -> t.Iterator["Rule"]: + for rulefactory in self.rules: + for rule in rulefactory.get_rules(map): + rule = rule.empty() + rule.subdomain = self.subdomain + yield rule + + +class Submount(RuleFactory): + """Like `Subdomain` but prefixes the URL rule with a given string:: + + url_map = Map([ + Rule('/', endpoint='index'), + Submount('/blog', [ + Rule('/', endpoint='blog/index'), + Rule('/entry/', endpoint='blog/show') + ]) + ]) + + Now the rule ``'blog/show'`` matches ``/blog/entry/``. + """ + + def __init__(self, path: str, rules: t.Iterable["Rule"]) -> None: + self.path = path.rstrip("/") + self.rules = rules + + def get_rules(self, map: "Map") -> t.Iterator["Rule"]: + for rulefactory in self.rules: + for rule in rulefactory.get_rules(map): + rule = rule.empty() + rule.rule = self.path + rule.rule + yield rule + + +class EndpointPrefix(RuleFactory): + """Prefixes all endpoints (which must be strings for this factory) with + another string. This can be useful for sub applications:: + + url_map = Map([ + Rule('/', endpoint='index'), + EndpointPrefix('blog/', [Submount('/blog', [ + Rule('/', endpoint='index'), + Rule('/entry/', endpoint='show') + ])]) + ]) + """ + + def __init__(self, prefix: str, rules: t.Iterable["Rule"]) -> None: + self.prefix = prefix + self.rules = rules + + def get_rules(self, map: "Map") -> t.Iterator["Rule"]: + for rulefactory in self.rules: + for rule in rulefactory.get_rules(map): + rule = rule.empty() + rule.endpoint = self.prefix + rule.endpoint + yield rule + + +class RuleTemplate: + """Returns copies of the rules wrapped and expands string templates in + the endpoint, rule, defaults or subdomain sections. + + Here a small example for such a rule template:: + + from werkzeug.routing import Map, Rule, RuleTemplate + + resource = RuleTemplate([ + Rule('/$name/', endpoint='$name.list'), + Rule('/$name/', endpoint='$name.show') + ]) + + url_map = Map([resource(name='user'), resource(name='page')]) + + When a rule template is called the keyword arguments are used to + replace the placeholders in all the string parameters. + """ + + def __init__(self, rules: t.Iterable["Rule"]) -> None: + self.rules = list(rules) + + def __call__(self, *args: t.Any, **kwargs: t.Any) -> "RuleTemplateFactory": + return RuleTemplateFactory(self.rules, dict(*args, **kwargs)) + + +class RuleTemplateFactory(RuleFactory): + """A factory that fills in template variables into rules. Used by + `RuleTemplate` internally. + + :internal: + """ + + def __init__(self, rules: t.Iterable["Rule"], context: t.Dict[str, t.Any]) -> None: + self.rules = rules + self.context = context + + def get_rules(self, map: "Map") -> t.Iterator["Rule"]: + for rulefactory in self.rules: + for rule in rulefactory.get_rules(map): + new_defaults = subdomain = None + if rule.defaults: + new_defaults = {} + for key, value in rule.defaults.items(): + if isinstance(value, str): + value = Template(value).substitute(self.context) + new_defaults[key] = value + if rule.subdomain is not None: + subdomain = Template(rule.subdomain).substitute(self.context) + new_endpoint = rule.endpoint + if isinstance(new_endpoint, str): + new_endpoint = Template(new_endpoint).substitute(self.context) + yield Rule( + Template(rule.rule).substitute(self.context), + new_defaults, + subdomain, + rule.methods, + rule.build_only, + new_endpoint, + rule.strict_slashes, + ) + + +def _prefix_names(src: str) -> ast.stmt: + """ast parse and prefix names with `.` to avoid collision with user vars""" + tree = ast.parse(src).body[0] + if isinstance(tree, ast.Expr): + tree = tree.value # type: ignore + for node in ast.walk(tree): + if isinstance(node, ast.Name): + node.id = f".{node.id}" + return tree + + +_CALL_CONVERTER_CODE_FMT = "self._converters[{elem!r}].to_url()" +_IF_KWARGS_URL_ENCODE_CODE = """\ +if kwargs: + q = '?' + params = self._encode_query_vars(kwargs) +else: + q = params = '' +""" +_IF_KWARGS_URL_ENCODE_AST = _prefix_names(_IF_KWARGS_URL_ENCODE_CODE) +_URL_ENCODE_AST_NAMES = (_prefix_names("q"), _prefix_names("params")) + + +class Rule(RuleFactory): + """A Rule represents one URL pattern. There are some options for `Rule` + that change the way it behaves and are passed to the `Rule` constructor. + Note that besides the rule-string all arguments *must* be keyword arguments + in order to not break the application on Werkzeug upgrades. + + `string` + Rule strings basically are just normal URL paths with placeholders in + the format ```` where the converter and the + arguments are optional. If no converter is defined the `default` + converter is used which means `string` in the normal configuration. + + URL rules that end with a slash are branch URLs, others are leaves. + If you have `strict_slashes` enabled (which is the default), all + branch URLs that are matched without a trailing slash will trigger a + redirect to the same URL with the missing slash appended. + + The converters are defined on the `Map`. + + `endpoint` + The endpoint for this rule. This can be anything. A reference to a + function, a string, a number etc. The preferred way is using a string + because the endpoint is used for URL generation. + + `defaults` + An optional dict with defaults for other rules with the same endpoint. + This is a bit tricky but useful if you want to have unique URLs:: + + url_map = Map([ + Rule('/all/', defaults={'page': 1}, endpoint='all_entries'), + Rule('/all/page/', endpoint='all_entries') + ]) + + If a user now visits ``http://example.com/all/page/1`` he will be + redirected to ``http://example.com/all/``. If `redirect_defaults` is + disabled on the `Map` instance this will only affect the URL + generation. + + `subdomain` + The subdomain rule string for this rule. If not specified the rule + only matches for the `default_subdomain` of the map. If the map is + not bound to a subdomain this feature is disabled. + + Can be useful if you want to have user profiles on different subdomains + and all subdomains are forwarded to your application:: + + url_map = Map([ + Rule('/', subdomain='', endpoint='user/homepage'), + Rule('/stats', subdomain='', endpoint='user/stats') + ]) + + `methods` + A sequence of http methods this rule applies to. If not specified, all + methods are allowed. For example this can be useful if you want different + endpoints for `POST` and `GET`. If methods are defined and the path + matches but the method matched against is not in this list or in the + list of another rule for that path the error raised is of the type + `MethodNotAllowed` rather than `NotFound`. If `GET` is present in the + list of methods and `HEAD` is not, `HEAD` is added automatically. + + `strict_slashes` + Override the `Map` setting for `strict_slashes` only for this rule. If + not specified the `Map` setting is used. + + `merge_slashes` + Override :attr:`Map.merge_slashes` for this rule. + + `build_only` + Set this to True and the rule will never match but will create a URL + that can be build. This is useful if you have resources on a subdomain + or folder that are not handled by the WSGI application (like static data) + + `redirect_to` + If given this must be either a string or callable. In case of a + callable it's called with the url adapter that triggered the match and + the values of the URL as keyword arguments and has to return the target + for the redirect, otherwise it has to be a string with placeholders in + rule syntax:: + + def foo_with_slug(adapter, id): + # ask the database for the slug for the old id. this of + # course has nothing to do with werkzeug. + return f'foo/{Foo.get_slug_for_id(id)}' + + url_map = Map([ + Rule('/foo/', endpoint='foo'), + Rule('/some/old/url/', redirect_to='foo/'), + Rule('/other/old/url/', redirect_to=foo_with_slug) + ]) + + When the rule is matched the routing system will raise a + `RequestRedirect` exception with the target for the redirect. + + Keep in mind that the URL will be joined against the URL root of the + script so don't use a leading slash on the target URL unless you + really mean root of that domain. + + `alias` + If enabled this rule serves as an alias for another rule with the same + endpoint and arguments. + + `host` + If provided and the URL map has host matching enabled this can be + used to provide a match rule for the whole host. This also means + that the subdomain feature is disabled. + + `websocket` + If ``True``, this rule is only matches for WebSocket (``ws://``, + ``wss://``) requests. By default, rules will only match for HTTP + requests. + + .. versionadded:: 1.0 + Added ``websocket``. + + .. versionadded:: 1.0 + Added ``merge_slashes``. + + .. versionadded:: 0.7 + Added ``alias`` and ``host``. + + .. versionchanged:: 0.6.1 + ``HEAD`` is added to ``methods`` if ``GET`` is present. + """ + + def __init__( + self, + string: str, + defaults: t.Optional[t.Mapping[str, t.Any]] = None, + subdomain: t.Optional[str] = None, + methods: t.Optional[t.Iterable[str]] = None, + build_only: bool = False, + endpoint: t.Optional[str] = None, + strict_slashes: t.Optional[bool] = None, + merge_slashes: t.Optional[bool] = None, + redirect_to: t.Optional[t.Union[str, t.Callable[..., str]]] = None, + alias: bool = False, + host: t.Optional[str] = None, + websocket: bool = False, + ) -> None: + if not string.startswith("/"): + raise ValueError("urls must start with a leading slash") + self.rule = string + self.is_leaf = not string.endswith("/") + + self.map: "Map" = None # type: ignore + self.strict_slashes = strict_slashes + self.merge_slashes = merge_slashes + self.subdomain = subdomain + self.host = host + self.defaults = defaults + self.build_only = build_only + self.alias = alias + self.websocket = websocket + + if methods is not None: + if isinstance(methods, str): + raise TypeError("'methods' should be a list of strings.") + + methods = {x.upper() for x in methods} + + if "HEAD" not in methods and "GET" in methods: + methods.add("HEAD") + + if websocket and methods - {"GET", "HEAD", "OPTIONS"}: + raise ValueError( + "WebSocket rules can only use 'GET', 'HEAD', and 'OPTIONS' methods." + ) + + self.methods = methods + self.endpoint: str = endpoint # type: ignore + self.redirect_to = redirect_to + + if defaults: + self.arguments = set(map(str, defaults)) + else: + self.arguments = set() + + self._trace: t.List[t.Tuple[bool, str]] = [] + + def empty(self) -> "Rule": + """ + Return an unbound copy of this rule. + + This can be useful if want to reuse an already bound URL for another + map. See ``get_empty_kwargs`` to override what keyword arguments are + provided to the new copy. + """ + return type(self)(self.rule, **self.get_empty_kwargs()) + + def get_empty_kwargs(self) -> t.Mapping[str, t.Any]: + """ + Provides kwargs for instantiating empty copy with empty() + + Use this method to provide custom keyword arguments to the subclass of + ``Rule`` when calling ``some_rule.empty()``. Helpful when the subclass + has custom keyword arguments that are needed at instantiation. + + Must return a ``dict`` that will be provided as kwargs to the new + instance of ``Rule``, following the initial ``self.rule`` value which + is always provided as the first, required positional argument. + """ + defaults = None + if self.defaults: + defaults = dict(self.defaults) + return dict( + defaults=defaults, + subdomain=self.subdomain, + methods=self.methods, + build_only=self.build_only, + endpoint=self.endpoint, + strict_slashes=self.strict_slashes, + redirect_to=self.redirect_to, + alias=self.alias, + host=self.host, + ) + + def get_rules(self, map: "Map") -> t.Iterator["Rule"]: + yield self + + def refresh(self) -> None: + """Rebinds and refreshes the URL. Call this if you modified the + rule in place. + + :internal: + """ + self.bind(self.map, rebind=True) + + def bind(self, map: "Map", rebind: bool = False) -> None: + """Bind the url to a map and create a regular expression based on + the information from the rule itself and the defaults from the map. + + :internal: + """ + if self.map is not None and not rebind: + raise RuntimeError(f"url rule {self!r} already bound to map {self.map!r}") + self.map = map + if self.strict_slashes is None: + self.strict_slashes = map.strict_slashes + if self.merge_slashes is None: + self.merge_slashes = map.merge_slashes + if self.subdomain is None: + self.subdomain = map.default_subdomain + self.compile() + + def get_converter( + self, + variable_name: str, + converter_name: str, + args: t.Tuple, + kwargs: t.Mapping[str, t.Any], + ) -> "BaseConverter": + """Looks up the converter for the given parameter. + + .. versionadded:: 0.9 + """ + if converter_name not in self.map.converters: + raise LookupError(f"the converter {converter_name!r} does not exist") + return self.map.converters[converter_name](self.map, *args, **kwargs) + + def _encode_query_vars(self, query_vars: t.Mapping[str, t.Any]) -> str: + return url_encode( + query_vars, + charset=self.map.charset, + sort=self.map.sort_parameters, + key=self.map.sort_key, + ) + + def compile(self) -> None: + """Compiles the regular expression and stores it.""" + assert self.map is not None, "rule not bound" + + if self.map.host_matching: + domain_rule = self.host or "" + else: + domain_rule = self.subdomain or "" + + self._trace = [] + self._converters: t.Dict[str, "BaseConverter"] = {} + self._static_weights: t.List[t.Tuple[int, int]] = [] + self._argument_weights: t.List[int] = [] + regex_parts = [] + + def _build_regex(rule: str) -> None: + index = 0 + for converter, arguments, variable in parse_rule(rule): + if converter is None: + for match in re.finditer(r"/+|[^/]+", variable): + part = match.group(0) + if part.startswith("/"): + if self.merge_slashes: + regex_parts.append(r"/+?") + self._trace.append((False, "/")) + else: + regex_parts.append(part) + self._trace.append((False, part)) + continue + self._trace.append((False, part)) + regex_parts.append(re.escape(part)) + if part: + self._static_weights.append((index, -len(part))) + else: + if arguments: + c_args, c_kwargs = parse_converter_args(arguments) + else: + c_args = () + c_kwargs = {} + convobj = self.get_converter(variable, converter, c_args, c_kwargs) + regex_parts.append(f"(?P<{variable}>{convobj.regex})") + self._converters[variable] = convobj + self._trace.append((True, variable)) + self._argument_weights.append(convobj.weight) + self.arguments.add(str(variable)) + index = index + 1 + + _build_regex(domain_rule) + regex_parts.append("\\|") + self._trace.append((False, "|")) + _build_regex(self.rule if self.is_leaf else self.rule.rstrip("/")) + if not self.is_leaf: + self._trace.append((False, "/")) + + self._build: t.Callable[..., t.Tuple[str, str]] + self._build = self._compile_builder(False).__get__(self, None) # type: ignore + self._build_unknown: t.Callable[..., t.Tuple[str, str]] + self._build_unknown = self._compile_builder(True).__get__( # type: ignore + self, None + ) + + if self.build_only: + return + + if not (self.is_leaf and self.strict_slashes): + reps = "*" if self.merge_slashes else "?" + tail = f"(?/{reps})" + else: + tail = "" + + regex = f"^{''.join(regex_parts)}{tail}$" + self._regex = re.compile(regex) + + def match( + self, path: str, method: t.Optional[str] = None + ) -> t.Optional[t.MutableMapping[str, t.Any]]: + """Check if the rule matches a given path. Path is a string in the + form ``"subdomain|/path"`` and is assembled by the map. If + the map is doing host matching the subdomain part will be the host + instead. + + If the rule matches a dict with the converted values is returned, + otherwise the return value is `None`. + + :internal: + """ + if not self.build_only: + require_redirect = False + + m = self._regex.search(path) + if m is not None: + groups = m.groupdict() + # we have a folder like part of the url without a trailing + # slash and strict slashes enabled. raise an exception that + # tells the map to redirect to the same url but with a + # trailing slash + if ( + self.strict_slashes + and not self.is_leaf + and not groups.pop("__suffix__") + and ( + method is None or self.methods is None or method in self.methods + ) + ): + path += "/" + require_redirect = True + # if we are not in strict slashes mode we have to remove + # a __suffix__ + elif not self.strict_slashes: + del groups["__suffix__"] + + result = {} + for name, value in groups.items(): + try: + value = self._converters[name].to_python(value) + except ValidationError: + return None + result[str(name)] = value + if self.defaults: + result.update(self.defaults) + + if self.merge_slashes: + new_path = "|".join(self.build(result, False)) # type: ignore + if path.endswith("/") and not new_path.endswith("/"): + new_path += "/" + if new_path.count("/") < path.count("/"): + path = new_path + require_redirect = True + + if require_redirect: + path = path.split("|", 1)[1] + raise RequestPath(path) + + if self.alias and self.map.redirect_defaults: + raise RequestAliasRedirect(result) + + return result + + return None + + @staticmethod + def _get_func_code(code: CodeType, name: str) -> t.Callable[..., t.Tuple[str, str]]: + globs: t.Dict[str, t.Any] = {} + locs: t.Dict[str, t.Any] = {} + exec(code, globs, locs) + return locs[name] # type: ignore + + def _compile_builder( + self, append_unknown: bool = True + ) -> t.Callable[..., t.Tuple[str, str]]: + defaults = self.defaults or {} + dom_ops: t.List[t.Tuple[bool, str]] = [] + url_ops: t.List[t.Tuple[bool, str]] = [] + + opl = dom_ops + for is_dynamic, data in self._trace: + if data == "|" and opl is dom_ops: + opl = url_ops + continue + # this seems like a silly case to ever come up but: + # if a default is given for a value that appears in the rule, + # resolve it to a constant ahead of time + if is_dynamic and data in defaults: + data = self._converters[data].to_url(defaults[data]) + opl.append((False, data)) + elif not is_dynamic: + opl.append( + (False, url_quote(_to_bytes(data, self.map.charset), safe="/:|+")) + ) + else: + opl.append((True, data)) + + def _convert(elem: str) -> ast.stmt: + ret = _prefix_names(_CALL_CONVERTER_CODE_FMT.format(elem=elem)) + ret.args = [ast.Name(str(elem), ast.Load())] # type: ignore # str for py2 + return ret + + def _parts(ops: t.List[t.Tuple[bool, str]]) -> t.List[ast.AST]: + parts = [ + _convert(elem) if is_dynamic else ast.Str(s=elem) + for is_dynamic, elem in ops + ] + parts = parts or [ast.Str("")] + # constant fold + ret = [parts[0]] + for p in parts[1:]: + if isinstance(p, ast.Str) and isinstance(ret[-1], ast.Str): + ret[-1] = ast.Str(ret[-1].s + p.s) + else: + ret.append(p) + return ret + + dom_parts = _parts(dom_ops) + url_parts = _parts(url_ops) + if not append_unknown: + body = [] + else: + body = [_IF_KWARGS_URL_ENCODE_AST] + url_parts.extend(_URL_ENCODE_AST_NAMES) + + def _join(parts: t.List[ast.AST]) -> ast.AST: + if len(parts) == 1: # shortcut + return parts[0] + return ast.JoinedStr(parts) + + body.append( + ast.Return(ast.Tuple([_join(dom_parts), _join(url_parts)], ast.Load())) + ) + + pargs = [ + elem + for is_dynamic, elem in dom_ops + url_ops + if is_dynamic and elem not in defaults + ] + kargs = [str(k) for k in defaults] + + func_ast: ast.FunctionDef = _prefix_names("def _(): pass") # type: ignore + func_ast.name = f"" + func_ast.args.args.append(ast.arg(".self", None)) + for arg in pargs + kargs: + func_ast.args.args.append(ast.arg(arg, None)) + func_ast.args.kwarg = ast.arg(".kwargs", None) + for _ in kargs: + func_ast.args.defaults.append(ast.Str("")) + func_ast.body = body + + # use `ast.parse` instead of `ast.Module` for better portability + # Python 3.8 changes the signature of `ast.Module` + module = ast.parse("") + module.body = [func_ast] + + # mark everything as on line 1, offset 0 + # less error-prone than `ast.fix_missing_locations` + # bad line numbers cause an assert to fail in debug builds + for node in ast.walk(module): + if "lineno" in node._attributes: + node.lineno = 1 + if "col_offset" in node._attributes: + node.col_offset = 0 + + code = compile(module, "", "exec") + return self._get_func_code(code, func_ast.name) + + def build( + self, values: t.Mapping[str, t.Any], append_unknown: bool = True + ) -> t.Optional[t.Tuple[str, str]]: + """Assembles the relative url for that rule and the subdomain. + If building doesn't work for some reasons `None` is returned. + + :internal: + """ + try: + if append_unknown: + return self._build_unknown(**values) + else: + return self._build(**values) + except ValidationError: + return None + + def provides_defaults_for(self, rule: "Rule") -> bool: + """Check if this rule has defaults for a given rule. + + :internal: + """ + return bool( + not self.build_only + and self.defaults + and self.endpoint == rule.endpoint + and self != rule + and self.arguments == rule.arguments + ) + + def suitable_for( + self, values: t.Mapping[str, t.Any], method: t.Optional[str] = None + ) -> bool: + """Check if the dict of values has enough data for url generation. + + :internal: + """ + # if a method was given explicitly and that method is not supported + # by this rule, this rule is not suitable. + if ( + method is not None + and self.methods is not None + and method not in self.methods + ): + return False + + defaults = self.defaults or () + + # all arguments required must be either in the defaults dict or + # the value dictionary otherwise it's not suitable + for key in self.arguments: + if key not in defaults and key not in values: + return False + + # in case defaults are given we ensure that either the value was + # skipped or the value is the same as the default value. + if defaults: + for key, value in defaults.items(): + if key in values and value != values[key]: + return False + + return True + + def match_compare_key( + self, + ) -> t.Tuple[bool, int, t.Iterable[t.Tuple[int, int]], int, t.Iterable[int]]: + """The match compare key for sorting. + + Current implementation: + + 1. rules without any arguments come first for performance + reasons only as we expect them to match faster and some + common ones usually don't have any arguments (index pages etc.) + 2. rules with more static parts come first so the second argument + is the negative length of the number of the static weights. + 3. we order by static weights, which is a combination of index + and length + 4. The more complex rules come first so the next argument is the + negative length of the number of argument weights. + 5. lastly we order by the actual argument weights. + + :internal: + """ + return ( + bool(self.arguments), + -len(self._static_weights), + self._static_weights, + -len(self._argument_weights), + self._argument_weights, + ) + + def build_compare_key(self) -> t.Tuple[int, int, int]: + """The build compare key for sorting. + + :internal: + """ + return (1 if self.alias else 0, -len(self.arguments), -len(self.defaults or ())) + + def __eq__(self, other: object) -> bool: + return isinstance(other, type(self)) and self._trace == other._trace + + __hash__ = None # type: ignore + + def __str__(self) -> str: + return self.rule + + def __repr__(self) -> str: + if self.map is None: + return f"<{type(self).__name__} (unbound)>" + parts = [] + for is_dynamic, data in self._trace: + if is_dynamic: + parts.append(f"<{data}>") + else: + parts.append(data) + parts = "".join(parts).lstrip("|") + methods = f" ({', '.join(self.methods)})" if self.methods is not None else "" + return f"<{type(self).__name__} {parts!r}{methods} -> {self.endpoint}>" + + +class BaseConverter: + """Base class for all converters.""" + + regex = "[^/]+" + weight = 100 + + def __init__(self, map: "Map", *args: t.Any, **kwargs: t.Any) -> None: + self.map = map + + def to_python(self, value: str) -> t.Any: + return value + + def to_url(self, value: t.Any) -> str: + if isinstance(value, (bytes, bytearray)): + return _fast_url_quote(value) + return _fast_url_quote(str(value).encode(self.map.charset)) + + +class UnicodeConverter(BaseConverter): + """This converter is the default converter and accepts any string but + only one path segment. Thus the string can not include a slash. + + This is the default validator. + + Example:: + + Rule('/pages/'), + Rule('/') + + :param map: the :class:`Map`. + :param minlength: the minimum length of the string. Must be greater + or equal 1. + :param maxlength: the maximum length of the string. + :param length: the exact length of the string. + """ + + def __init__( + self, + map: "Map", + minlength: int = 1, + maxlength: t.Optional[int] = None, + length: t.Optional[int] = None, + ) -> None: + super().__init__(map) + if length is not None: + length_regex = f"{{{int(length)}}}" + else: + if maxlength is None: + maxlength_value = "" + else: + maxlength_value = str(int(maxlength)) + length_regex = f"{{{int(minlength)},{maxlength_value}}}" + self.regex = f"[^/]{length_regex}" + + +class AnyConverter(BaseConverter): + """Matches one of the items provided. Items can either be Python + identifiers or strings:: + + Rule('/') + + :param map: the :class:`Map`. + :param items: this function accepts the possible items as positional + arguments. + """ + + def __init__(self, map: "Map", *items: str) -> None: + super().__init__(map) + self.regex = f"(?:{'|'.join([re.escape(x) for x in items])})" + + +class PathConverter(BaseConverter): + """Like the default :class:`UnicodeConverter`, but it also matches + slashes. This is useful for wikis and similar applications:: + + Rule('/') + Rule('//edit') + + :param map: the :class:`Map`. + """ + + regex = "[^/].*?" + weight = 200 + + +class NumberConverter(BaseConverter): + """Baseclass for `IntegerConverter` and `FloatConverter`. + + :internal: + """ + + weight = 50 + num_convert: t.Callable = int + + def __init__( + self, + map: "Map", + fixed_digits: int = 0, + min: t.Optional[int] = None, + max: t.Optional[int] = None, + signed: bool = False, + ) -> None: + if signed: + self.regex = self.signed_regex + super().__init__(map) + self.fixed_digits = fixed_digits + self.min = min + self.max = max + self.signed = signed + + def to_python(self, value: str) -> t.Any: + if self.fixed_digits and len(value) != self.fixed_digits: + raise ValidationError() + value = self.num_convert(value) + if (self.min is not None and value < self.min) or ( + self.max is not None and value > self.max + ): + raise ValidationError() + return value + + def to_url(self, value: t.Any) -> str: + value = str(self.num_convert(value)) + if self.fixed_digits: + value = value.zfill(self.fixed_digits) + return value + + @property + def signed_regex(self) -> str: + return f"-?{self.regex}" + + +class IntegerConverter(NumberConverter): + """This converter only accepts integer values:: + + Rule("/page/") + + By default it only accepts unsigned, positive values. The ``signed`` + parameter will enable signed, negative values. :: + + Rule("/page/") + + :param map: The :class:`Map`. + :param fixed_digits: The number of fixed digits in the URL. If you + set this to ``4`` for example, the rule will only match if the + URL looks like ``/0001/``. The default is variable length. + :param min: The minimal value. + :param max: The maximal value. + :param signed: Allow signed (negative) values. + + .. versionadded:: 0.15 + The ``signed`` parameter. + """ + + regex = r"\d+" + + +class FloatConverter(NumberConverter): + """This converter only accepts floating point values:: + + Rule("/probability/") + + By default it only accepts unsigned, positive values. The ``signed`` + parameter will enable signed, negative values. :: + + Rule("/offset/") + + :param map: The :class:`Map`. + :param min: The minimal value. + :param max: The maximal value. + :param signed: Allow signed (negative) values. + + .. versionadded:: 0.15 + The ``signed`` parameter. + """ + + regex = r"\d+\.\d+" + num_convert = float + + def __init__( + self, + map: "Map", + min: t.Optional[float] = None, + max: t.Optional[float] = None, + signed: bool = False, + ) -> None: + super().__init__(map, min=min, max=max, signed=signed) # type: ignore + + +class UUIDConverter(BaseConverter): + """This converter only accepts UUID strings:: + + Rule('/object/') + + .. versionadded:: 0.10 + + :param map: the :class:`Map`. + """ + + regex = ( + r"[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-" + r"[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}" + ) + + def to_python(self, value: str) -> uuid.UUID: + return uuid.UUID(value) + + def to_url(self, value: uuid.UUID) -> str: + return str(value) + + +#: the default converter mapping for the map. +DEFAULT_CONVERTERS: t.Mapping[str, t.Type[BaseConverter]] = { + "default": UnicodeConverter, + "string": UnicodeConverter, + "any": AnyConverter, + "path": PathConverter, + "int": IntegerConverter, + "float": FloatConverter, + "uuid": UUIDConverter, +} + + +class Map: + """The map class stores all the URL rules and some configuration + parameters. Some of the configuration values are only stored on the + `Map` instance since those affect all rules, others are just defaults + and can be overridden for each rule. Note that you have to specify all + arguments besides the `rules` as keyword arguments! + + :param rules: sequence of url rules for this map. + :param default_subdomain: The default subdomain for rules without a + subdomain defined. + :param charset: charset of the url. defaults to ``"utf-8"`` + :param strict_slashes: If a rule ends with a slash but the matched + URL does not, redirect to the URL with a trailing slash. + :param merge_slashes: Merge consecutive slashes when matching or + building URLs. Matches will redirect to the normalized URL. + Slashes in variable parts are not merged. + :param redirect_defaults: This will redirect to the default rule if it + wasn't visited that way. This helps creating + unique URLs. + :param converters: A dict of converters that adds additional converters + to the list of converters. If you redefine one + converter this will override the original one. + :param sort_parameters: If set to `True` the url parameters are sorted. + See `url_encode` for more details. + :param sort_key: The sort key function for `url_encode`. + :param encoding_errors: the error method to use for decoding + :param host_matching: if set to `True` it enables the host matching + feature and disables the subdomain one. If + enabled the `host` parameter to rules is used + instead of the `subdomain` one. + + .. versionchanged:: 1.0 + If ``url_scheme`` is ``ws`` or ``wss``, only WebSocket rules + will match. + + .. versionchanged:: 1.0 + Added ``merge_slashes``. + + .. versionchanged:: 0.7 + Added ``encoding_errors`` and ``host_matching``. + + .. versionchanged:: 0.5 + Added ``sort_parameters`` and ``sort_key``. + """ + + #: A dict of default converters to be used. + default_converters = ImmutableDict(DEFAULT_CONVERTERS) + + #: The type of lock to use when updating. + #: + #: .. versionadded:: 1.0 + lock_class = Lock + + def __init__( + self, + rules: t.Optional[t.Iterable[RuleFactory]] = None, + default_subdomain: str = "", + charset: str = "utf-8", + strict_slashes: bool = True, + merge_slashes: bool = True, + redirect_defaults: bool = True, + converters: t.Optional[t.Mapping[str, t.Type[BaseConverter]]] = None, + sort_parameters: bool = False, + sort_key: t.Optional[t.Callable[[t.Any], t.Any]] = None, + encoding_errors: str = "replace", + host_matching: bool = False, + ) -> None: + self._rules: t.List[Rule] = [] + self._rules_by_endpoint: t.Dict[str, t.List[Rule]] = {} + self._remap = True + self._remap_lock = self.lock_class() + + self.default_subdomain = default_subdomain + self.charset = charset + self.encoding_errors = encoding_errors + self.strict_slashes = strict_slashes + self.merge_slashes = merge_slashes + self.redirect_defaults = redirect_defaults + self.host_matching = host_matching + + self.converters = self.default_converters.copy() + if converters: + self.converters.update(converters) + + self.sort_parameters = sort_parameters + self.sort_key = sort_key + + for rulefactory in rules or (): + self.add(rulefactory) + + def is_endpoint_expecting(self, endpoint: str, *arguments: str) -> bool: + """Iterate over all rules and check if the endpoint expects + the arguments provided. This is for example useful if you have + some URLs that expect a language code and others that do not and + you want to wrap the builder a bit so that the current language + code is automatically added if not provided but endpoints expect + it. + + :param endpoint: the endpoint to check. + :param arguments: this function accepts one or more arguments + as positional arguments. Each one of them is + checked. + """ + self.update() + arguments = set(arguments) + for rule in self._rules_by_endpoint[endpoint]: + if arguments.issubset(rule.arguments): + return True + return False + + def iter_rules(self, endpoint: t.Optional[str] = None) -> t.Iterator[Rule]: + """Iterate over all rules or the rules of an endpoint. + + :param endpoint: if provided only the rules for that endpoint + are returned. + :return: an iterator + """ + self.update() + if endpoint is not None: + return iter(self._rules_by_endpoint[endpoint]) + return iter(self._rules) + + def add(self, rulefactory: RuleFactory) -> None: + """Add a new rule or factory to the map and bind it. Requires that the + rule is not bound to another map. + + :param rulefactory: a :class:`Rule` or :class:`RuleFactory` + """ + for rule in rulefactory.get_rules(self): + rule.bind(self) + self._rules.append(rule) + self._rules_by_endpoint.setdefault(rule.endpoint, []).append(rule) + self._remap = True + + def bind( + self, + server_name: str, + script_name: t.Optional[str] = None, + subdomain: t.Optional[str] = None, + url_scheme: str = "http", + default_method: str = "GET", + path_info: t.Optional[str] = None, + query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None, + ) -> "MapAdapter": + """Return a new :class:`MapAdapter` with the details specified to the + call. Note that `script_name` will default to ``'/'`` if not further + specified or `None`. The `server_name` at least is a requirement + because the HTTP RFC requires absolute URLs for redirects and so all + redirect exceptions raised by Werkzeug will contain the full canonical + URL. + + If no path_info is passed to :meth:`match` it will use the default path + info passed to bind. While this doesn't really make sense for + manual bind calls, it's useful if you bind a map to a WSGI + environment which already contains the path info. + + `subdomain` will default to the `default_subdomain` for this map if + no defined. If there is no `default_subdomain` you cannot use the + subdomain feature. + + .. versionchanged:: 1.0 + If ``url_scheme`` is ``ws`` or ``wss``, only WebSocket rules + will match. + + .. versionchanged:: 0.15 + ``path_info`` defaults to ``'/'`` if ``None``. + + .. versionchanged:: 0.8 + ``query_args`` can be a string. + + .. versionchanged:: 0.7 + Added ``query_args``. + """ + server_name = server_name.lower() + if self.host_matching: + if subdomain is not None: + raise RuntimeError("host matching enabled and a subdomain was provided") + elif subdomain is None: + subdomain = self.default_subdomain + if script_name is None: + script_name = "/" + if path_info is None: + path_info = "/" + try: + server_name = _encode_idna(server_name) # type: ignore + except UnicodeError: + raise BadHost() + return MapAdapter( + self, + server_name, + script_name, + subdomain, + url_scheme, + path_info, + default_method, + query_args, + ) + + def bind_to_environ( + self, + environ: "WSGIEnvironment", + server_name: t.Optional[str] = None, + subdomain: t.Optional[str] = None, + ) -> "MapAdapter": + """Like :meth:`bind` but you can pass it an WSGI environment and it + will fetch the information from that dictionary. Note that because of + limitations in the protocol there is no way to get the current + subdomain and real `server_name` from the environment. If you don't + provide it, Werkzeug will use `SERVER_NAME` and `SERVER_PORT` (or + `HTTP_HOST` if provided) as used `server_name` with disabled subdomain + feature. + + If `subdomain` is `None` but an environment and a server name is + provided it will calculate the current subdomain automatically. + Example: `server_name` is ``'example.com'`` and the `SERVER_NAME` + in the wsgi `environ` is ``'staging.dev.example.com'`` the calculated + subdomain will be ``'staging.dev'``. + + If the object passed as environ has an environ attribute, the value of + this attribute is used instead. This allows you to pass request + objects. Additionally `PATH_INFO` added as a default of the + :class:`MapAdapter` so that you don't have to pass the path info to + the match method. + + .. versionchanged:: 1.0.0 + If the passed server name specifies port 443, it will match + if the incoming scheme is ``https`` without a port. + + .. versionchanged:: 1.0.0 + A warning is shown when the passed server name does not + match the incoming WSGI server name. + + .. versionchanged:: 0.8 + This will no longer raise a ValueError when an unexpected server + name was passed. + + .. versionchanged:: 0.5 + previously this method accepted a bogus `calculate_subdomain` + parameter that did not have any effect. It was removed because + of that. + + :param environ: a WSGI environment. + :param server_name: an optional server name hint (see above). + :param subdomain: optionally the current subdomain (see above). + """ + environ = _get_environ(environ) + wsgi_server_name = get_host(environ).lower() + scheme = environ["wsgi.url_scheme"] + + if ( + environ.get("HTTP_CONNECTION", "").lower() == "upgrade" + and environ.get("HTTP_UPGRADE", "").lower() == "websocket" + ): + scheme = "wss" if scheme == "https" else "ws" + + if server_name is None: + server_name = wsgi_server_name + else: + server_name = server_name.lower() + + # strip standard port to match get_host() + if scheme in {"http", "ws"} and server_name.endswith(":80"): + server_name = server_name[:-3] + elif scheme in {"https", "wss"} and server_name.endswith(":443"): + server_name = server_name[:-4] + + if subdomain is None and not self.host_matching: + cur_server_name = wsgi_server_name.split(".") + real_server_name = server_name.split(".") + offset = -len(real_server_name) + + if cur_server_name[offset:] != real_server_name: + # This can happen even with valid configs if the server was + # accessed directly by IP address under some situations. + # Instead of raising an exception like in Werkzeug 0.7 or + # earlier we go by an invalid subdomain which will result + # in a 404 error on matching. + warnings.warn( + f"Current server name {wsgi_server_name!r} doesn't match configured" + f" server name {server_name!r}", + stacklevel=2, + ) + subdomain = "" + else: + subdomain = ".".join(filter(None, cur_server_name[:offset])) + + def _get_wsgi_string(name: str) -> t.Optional[str]: + val = environ.get(name) + if val is not None: + return _wsgi_decoding_dance(val, self.charset) + return None + + script_name = _get_wsgi_string("SCRIPT_NAME") + path_info = _get_wsgi_string("PATH_INFO") + query_args = _get_wsgi_string("QUERY_STRING") + return Map.bind( + self, + server_name, + script_name, + subdomain, + scheme, + environ["REQUEST_METHOD"], + path_info, + query_args=query_args, + ) + + def update(self) -> None: + """Called before matching and building to keep the compiled rules + in the correct order after things changed. + """ + if not self._remap: + return + + with self._remap_lock: + if not self._remap: + return + + self._rules.sort(key=lambda x: x.match_compare_key()) + for rules in self._rules_by_endpoint.values(): + rules.sort(key=lambda x: x.build_compare_key()) + self._remap = False + + def __repr__(self) -> str: + rules = self.iter_rules() + return f"{type(self).__name__}({pformat(list(rules))})" + + +class MapAdapter: + + """Returned by :meth:`Map.bind` or :meth:`Map.bind_to_environ` and does + the URL matching and building based on runtime information. + """ + + def __init__( + self, + map: Map, + server_name: str, + script_name: str, + subdomain: t.Optional[str], + url_scheme: str, + path_info: str, + default_method: str, + query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None, + ): + self.map = map + self.server_name = _to_str(server_name) + script_name = _to_str(script_name) + if not script_name.endswith("/"): + script_name += "/" + self.script_name = script_name + self.subdomain = _to_str(subdomain) + self.url_scheme = _to_str(url_scheme) + self.path_info = _to_str(path_info) + self.default_method = _to_str(default_method) + self.query_args = query_args + self.websocket = self.url_scheme in {"ws", "wss"} + + def dispatch( + self, + view_func: t.Callable[[str, t.Mapping[str, t.Any]], "WSGIApplication"], + path_info: t.Optional[str] = None, + method: t.Optional[str] = None, + catch_http_exceptions: bool = False, + ) -> "WSGIApplication": + """Does the complete dispatching process. `view_func` is called with + the endpoint and a dict with the values for the view. It should + look up the view function, call it, and return a response object + or WSGI application. http exceptions are not caught by default + so that applications can display nicer error messages by just + catching them by hand. If you want to stick with the default + error messages you can pass it ``catch_http_exceptions=True`` and + it will catch the http exceptions. + + Here a small example for the dispatch usage:: + + from werkzeug.wrappers import Request, Response + from werkzeug.wsgi import responder + from werkzeug.routing import Map, Rule + + def on_index(request): + return Response('Hello from the index') + + url_map = Map([Rule('/', endpoint='index')]) + views = {'index': on_index} + + @responder + def application(environ, start_response): + request = Request(environ) + urls = url_map.bind_to_environ(environ) + return urls.dispatch(lambda e, v: views[e](request, **v), + catch_http_exceptions=True) + + Keep in mind that this method might return exception objects, too, so + use :class:`Response.force_type` to get a response object. + + :param view_func: a function that is called with the endpoint as + first argument and the value dict as second. Has + to dispatch to the actual view function with this + information. (see above) + :param path_info: the path info to use for matching. Overrides the + path info specified on binding. + :param method: the HTTP method used for matching. Overrides the + method specified on binding. + :param catch_http_exceptions: set to `True` to catch any of the + werkzeug :class:`HTTPException`\\s. + """ + try: + try: + endpoint, args = self.match(path_info, method) + except RequestRedirect as e: + return e + return view_func(endpoint, args) + except HTTPException as e: + if catch_http_exceptions: + return e + raise + + @typing.overload + def match( # type: ignore + self, + path_info: t.Optional[str] = None, + method: t.Optional[str] = None, + return_rule: "te.Literal[False]" = False, + query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None, + websocket: t.Optional[bool] = None, + ) -> t.Tuple[str, t.Mapping[str, t.Any]]: + ... + + @typing.overload + def match( + self, + path_info: t.Optional[str] = None, + method: t.Optional[str] = None, + return_rule: "te.Literal[True]" = True, + query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None, + websocket: t.Optional[bool] = None, + ) -> t.Tuple[Rule, t.Mapping[str, t.Any]]: + ... + + def match( + self, + path_info: t.Optional[str] = None, + method: t.Optional[str] = None, + return_rule: bool = False, + query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None, + websocket: t.Optional[bool] = None, + ) -> t.Tuple[t.Union[str, Rule], t.Mapping[str, t.Any]]: + """The usage is simple: you just pass the match method the current + path info as well as the method (which defaults to `GET`). The + following things can then happen: + + - you receive a `NotFound` exception that indicates that no URL is + matching. A `NotFound` exception is also a WSGI application you + can call to get a default page not found page (happens to be the + same object as `werkzeug.exceptions.NotFound`) + + - you receive a `MethodNotAllowed` exception that indicates that there + is a match for this URL but not for the current request method. + This is useful for RESTful applications. + + - you receive a `RequestRedirect` exception with a `new_url` + attribute. This exception is used to notify you about a request + Werkzeug requests from your WSGI application. This is for example the + case if you request ``/foo`` although the correct URL is ``/foo/`` + You can use the `RequestRedirect` instance as response-like object + similar to all other subclasses of `HTTPException`. + + - you receive a ``WebsocketMismatch`` exception if the only + match is a WebSocket rule but the bind is an HTTP request, or + if the match is an HTTP rule but the bind is a WebSocket + request. + + - you get a tuple in the form ``(endpoint, arguments)`` if there is + a match (unless `return_rule` is True, in which case you get a tuple + in the form ``(rule, arguments)``) + + If the path info is not passed to the match method the default path + info of the map is used (defaults to the root URL if not defined + explicitly). + + All of the exceptions raised are subclasses of `HTTPException` so they + can be used as WSGI responses. They will all render generic error or + redirect pages. + + Here is a small example for matching: + + >>> m = Map([ + ... Rule('/', endpoint='index'), + ... Rule('/downloads/', endpoint='downloads/index'), + ... Rule('/downloads/', endpoint='downloads/show') + ... ]) + >>> urls = m.bind("example.com", "/") + >>> urls.match("/", "GET") + ('index', {}) + >>> urls.match("/downloads/42") + ('downloads/show', {'id': 42}) + + And here is what happens on redirect and missing URLs: + + >>> urls.match("/downloads") + Traceback (most recent call last): + ... + RequestRedirect: http://example.com/downloads/ + >>> urls.match("/missing") + Traceback (most recent call last): + ... + NotFound: 404 Not Found + + :param path_info: the path info to use for matching. Overrides the + path info specified on binding. + :param method: the HTTP method used for matching. Overrides the + method specified on binding. + :param return_rule: return the rule that matched instead of just the + endpoint (defaults to `False`). + :param query_args: optional query arguments that are used for + automatic redirects as string or dictionary. It's + currently not possible to use the query arguments + for URL matching. + :param websocket: Match WebSocket instead of HTTP requests. A + websocket request has a ``ws`` or ``wss`` + :attr:`url_scheme`. This overrides that detection. + + .. versionadded:: 1.0 + Added ``websocket``. + + .. versionchanged:: 0.8 + ``query_args`` can be a string. + + .. versionadded:: 0.7 + Added ``query_args``. + + .. versionadded:: 0.6 + Added ``return_rule``. + """ + self.map.update() + if path_info is None: + path_info = self.path_info + else: + path_info = _to_str(path_info, self.map.charset) + if query_args is None: + query_args = self.query_args or {} + method = (method or self.default_method).upper() + + if websocket is None: + websocket = self.websocket + + require_redirect = False + + domain_part = self.server_name if self.map.host_matching else self.subdomain + path_part = f"/{path_info.lstrip('/')}" if path_info else "" + path = f"{domain_part}|{path_part}" + + have_match_for = set() + websocket_mismatch = False + + for rule in self.map._rules: + try: + rv = rule.match(path, method) + except RequestPath as e: + raise RequestRedirect( + self.make_redirect_url( + url_quote(e.path_info, self.map.charset, safe="/:|+"), + query_args, + ) + ) + except RequestAliasRedirect as e: + raise RequestRedirect( + self.make_alias_redirect_url( + path, rule.endpoint, e.matched_values, method, query_args + ) + ) + if rv is None: + continue + if rule.methods is not None and method not in rule.methods: + have_match_for.update(rule.methods) + continue + + if rule.websocket != websocket: + websocket_mismatch = True + continue + + if self.map.redirect_defaults: + redirect_url = self.get_default_redirect(rule, method, rv, query_args) + if redirect_url is not None: + raise RequestRedirect(redirect_url) + + if rule.redirect_to is not None: + if isinstance(rule.redirect_to, str): + + def _handle_match(match: t.Match[str]) -> str: + value = rv[match.group(1)] # type: ignore + return rule._converters[match.group(1)].to_url(value) + + redirect_url = _simple_rule_re.sub(_handle_match, rule.redirect_to) + else: + redirect_url = rule.redirect_to(self, **rv) + + if self.subdomain: + netloc = f"{self.subdomain}.{self.server_name}" + else: + netloc = self.server_name + + raise RequestRedirect( + url_join( + f"{self.url_scheme or 'http'}://{netloc}{self.script_name}", + redirect_url, + ) + ) + + if require_redirect: + raise RequestRedirect( + self.make_redirect_url( + url_quote(path_info, self.map.charset, safe="/:|+"), query_args + ) + ) + + if return_rule: + return rule, rv + else: + return rule.endpoint, rv + + if have_match_for: + raise MethodNotAllowed(valid_methods=list(have_match_for)) + + if websocket_mismatch: + raise WebsocketMismatch() + + raise NotFound() + + def test( + self, path_info: t.Optional[str] = None, method: t.Optional[str] = None + ) -> bool: + """Test if a rule would match. Works like `match` but returns `True` + if the URL matches, or `False` if it does not exist. + + :param path_info: the path info to use for matching. Overrides the + path info specified on binding. + :param method: the HTTP method used for matching. Overrides the + method specified on binding. + """ + try: + self.match(path_info, method) + except RequestRedirect: + pass + except HTTPException: + return False + return True + + def allowed_methods(self, path_info: t.Optional[str] = None) -> t.Iterable[str]: + """Returns the valid methods that match for a given path. + + .. versionadded:: 0.7 + """ + try: + self.match(path_info, method="--") + except MethodNotAllowed as e: + return e.valid_methods # type: ignore + except HTTPException: + pass + return [] + + def get_host(self, domain_part: t.Optional[str]) -> str: + """Figures out the full host name for the given domain part. The + domain part is a subdomain in case host matching is disabled or + a full host name. + """ + if self.map.host_matching: + if domain_part is None: + return self.server_name + return _to_str(domain_part, "ascii") + subdomain = domain_part + if subdomain is None: + subdomain = self.subdomain + else: + subdomain = _to_str(subdomain, "ascii") + + if subdomain: + return f"{subdomain}.{self.server_name}" + else: + return self.server_name + + def get_default_redirect( + self, + rule: Rule, + method: str, + values: t.MutableMapping[str, t.Any], + query_args: t.Union[t.Mapping[str, t.Any], str], + ) -> t.Optional[str]: + """A helper that returns the URL to redirect to if it finds one. + This is used for default redirecting only. + + :internal: + """ + assert self.map.redirect_defaults + for r in self.map._rules_by_endpoint[rule.endpoint]: + # every rule that comes after this one, including ourself + # has a lower priority for the defaults. We order the ones + # with the highest priority up for building. + if r is rule: + break + if r.provides_defaults_for(rule) and r.suitable_for(values, method): + values.update(r.defaults) # type: ignore + domain_part, path = r.build(values) # type: ignore + return self.make_redirect_url(path, query_args, domain_part=domain_part) + return None + + def encode_query_args(self, query_args: t.Union[t.Mapping[str, t.Any], str]) -> str: + if not isinstance(query_args, str): + return url_encode(query_args, self.map.charset) + return query_args + + def make_redirect_url( + self, + path_info: str, + query_args: t.Optional[t.Union[t.Mapping[str, t.Any], str]] = None, + domain_part: t.Optional[str] = None, + ) -> str: + """Creates a redirect URL. + + :internal: + """ + if query_args: + suffix = f"?{self.encode_query_args(query_args)}" + else: + suffix = "" + + scheme = self.url_scheme or "http" + host = self.get_host(domain_part) + path = posixpath.join(self.script_name.strip("/"), path_info.lstrip("/")) + return f"{scheme}://{host}/{path}{suffix}" + + def make_alias_redirect_url( + self, + path: str, + endpoint: str, + values: t.Mapping[str, t.Any], + method: str, + query_args: t.Union[t.Mapping[str, t.Any], str], + ) -> str: + """Internally called to make an alias redirect URL.""" + url = self.build( + endpoint, values, method, append_unknown=False, force_external=True + ) + if query_args: + url += f"?{self.encode_query_args(query_args)}" + assert url != path, "detected invalid alias setting. No canonical URL found" + return url + + def _partial_build( + self, + endpoint: str, + values: t.Mapping[str, t.Any], + method: t.Optional[str], + append_unknown: bool, + ) -> t.Optional[t.Tuple[str, str, bool]]: + """Helper for :meth:`build`. Returns subdomain and path for the + rule that accepts this endpoint, values and method. + + :internal: + """ + # in case the method is none, try with the default method first + if method is None: + rv = self._partial_build( + endpoint, values, self.default_method, append_unknown + ) + if rv is not None: + return rv + + # Default method did not match or a specific method is passed. + # Check all for first match with matching host. If no matching + # host is found, go with first result. + first_match = None + + for rule in self.map._rules_by_endpoint.get(endpoint, ()): + if rule.suitable_for(values, method): + build_rv = rule.build(values, append_unknown) + + if build_rv is not None: + rv = (build_rv[0], build_rv[1], rule.websocket) + if self.map.host_matching: + if rv[0] == self.server_name: + return rv + elif first_match is None: + first_match = rv + else: + return rv + + return first_match + + def build( + self, + endpoint: str, + values: t.Optional[t.Mapping[str, t.Any]] = None, + method: t.Optional[str] = None, + force_external: bool = False, + append_unknown: bool = True, + url_scheme: t.Optional[str] = None, + ) -> str: + """Building URLs works pretty much the other way round. Instead of + `match` you call `build` and pass it the endpoint and a dict of + arguments for the placeholders. + + The `build` function also accepts an argument called `force_external` + which, if you set it to `True` will force external URLs. Per default + external URLs (include the server name) will only be used if the + target URL is on a different subdomain. + + >>> m = Map([ + ... Rule('/', endpoint='index'), + ... Rule('/downloads/', endpoint='downloads/index'), + ... Rule('/downloads/', endpoint='downloads/show') + ... ]) + >>> urls = m.bind("example.com", "/") + >>> urls.build("index", {}) + '/' + >>> urls.build("downloads/show", {'id': 42}) + '/downloads/42' + >>> urls.build("downloads/show", {'id': 42}, force_external=True) + 'http://example.com/downloads/42' + + Because URLs cannot contain non ASCII data you will always get + bytes back. Non ASCII characters are urlencoded with the + charset defined on the map instance. + + Additional values are converted to strings and appended to the URL as + URL querystring parameters: + + >>> urls.build("index", {'q': 'My Searchstring'}) + '/?q=My+Searchstring' + + When processing those additional values, lists are furthermore + interpreted as multiple values (as per + :py:class:`werkzeug.datastructures.MultiDict`): + + >>> urls.build("index", {'q': ['a', 'b', 'c']}) + '/?q=a&q=b&q=c' + + Passing a ``MultiDict`` will also add multiple values: + + >>> urls.build("index", MultiDict((('p', 'z'), ('q', 'a'), ('q', 'b')))) + '/?p=z&q=a&q=b' + + If a rule does not exist when building a `BuildError` exception is + raised. + + The build method accepts an argument called `method` which allows you + to specify the method you want to have an URL built for if you have + different methods for the same endpoint specified. + + :param endpoint: the endpoint of the URL to build. + :param values: the values for the URL to build. Unhandled values are + appended to the URL as query parameters. + :param method: the HTTP method for the rule if there are different + URLs for different methods on the same endpoint. + :param force_external: enforce full canonical external URLs. If the URL + scheme is not provided, this will generate + a protocol-relative URL. + :param append_unknown: unknown parameters are appended to the generated + URL as query string argument. Disable this + if you want the builder to ignore those. + :param url_scheme: Scheme to use in place of the bound + :attr:`url_scheme`. + + .. versionchanged:: 2.0 + Added the ``url_scheme`` parameter. + + .. versionadded:: 0.6 + Added the ``append_unknown`` parameter. + """ + self.map.update() + + if values: + temp_values: t.Dict[str, t.Union[t.List[t.Any], t.Any]] = {} + always_list = isinstance(values, MultiDict) + key: str + value: t.Optional[t.Union[t.List[t.Any], t.Any]] + + # For MultiDict, dict.items(values) is like values.lists() + # without the call or list coercion overhead. + for key, value in dict.items(values): # type: ignore + if value is None: + continue + + if always_list or isinstance(value, (list, tuple)): + value = [v for v in value if v is not None] + + if not value: + continue + + if len(value) == 1: + value = value[0] + + temp_values[key] = value + + values = temp_values + else: + values = {} + + rv = self._partial_build(endpoint, values, method, append_unknown) + if rv is None: + raise BuildError(endpoint, values, method, self) + + domain_part, path, websocket = rv + host = self.get_host(domain_part) + + if url_scheme is None: + url_scheme = self.url_scheme + + # Always build WebSocket routes with the scheme (browsers + # require full URLs). If bound to a WebSocket, ensure that HTTP + # routes are built with an HTTP scheme. + secure = url_scheme in {"https", "wss"} + + if websocket: + force_external = True + url_scheme = "wss" if secure else "ws" + elif url_scheme: + url_scheme = "https" if secure else "http" + + # shortcut this. + if not force_external and ( + (self.map.host_matching and host == self.server_name) + or (not self.map.host_matching and domain_part == self.subdomain) + ): + return f"{self.script_name.rstrip('/')}/{path.lstrip('/')}" + + scheme = f"{url_scheme}:" if url_scheme else "" + return f"{scheme}//{host}{self.script_name[:-1]}/{path.lstrip('/')}" diff --git a/venv/lib/python3.9/site-packages/werkzeug/sansio/__init__.py b/venv/lib/python3.9/site-packages/werkzeug/sansio/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ffd06327e2197a80867e273b29f9c66c349afca GIT binary patch literal 198 zcmYe~<>g`kf;S}}5`Gi!~qNj8`9C3BN)kC_ zlddkxBcX*Lmh%<^^BxC~9{rrRJm*Iw{Td{I7yGb4fW^XC$NQaXQlu{9T@qD&>eQ*~ zQ|DeCmdl=j-+!q8{Q1&l!}v1|CVx2$ZlcAz%rLmYS;uJ5)9kRW*)SQwR>$hv4O_!D z;9Mi8;atb*<{NnpJAmDWtKmH0LZhHz7qHjx02jE|DRxVZl7@?b%Z;*zOPxx0sxhVE za%Z}GqH#jQmCj7}WaA_=-ZuCYpZ>()(>rEkR+#(*pZSyldy>xrJ1b^)tR2=kH8FFF z&tYb6I5RgfGtU<=voM^QpO`t#&tT@vaAsj*<}5#lnRCOL(|GfFegT*ZglU`+XLgLn zSzs@6A6Q@HfIY`AHO>oT_X58xjP}Jnv*FW70H;Tn^xPG3e$E(TE@OwQ{2F$+hI3xQ z=q3I#MlWM@m9zJZ>MLK6?&?*R7I>(_W+#ke4D4{Adi1PCgDyRrVXWwRzonnAmA%U9V^ogOfj)Rc2r%0K#Z6ZZu4N7&Fb)HbkWApIfOL1X0)(L6CYu z(CzU-hu~5Wd^iX@+05sLoW&Np`?9mN-s_4b)#~=t`ewhy!+2e6EZr6HQ`PG)z1>pl zgO#O6J*ifEomOuN@7Y-Dv{sh-n`*rmefRp0mg1HYi~X?qG+Yz$(nmr*-4cVfr8taY zEa(n8s)Ylp>-|kRh4-F7i%DuO)8l1Gz*&{OEfF0#vjwu7L_ddabmk|9u!POo>u@fp z5@&uSMc7^Gh}0%!)<4fldWoE&?j*W2r!|vK1wj}^Jr$A?;~*HzA%jlQf_ZcVXdXRN zk6+B#1yCMkOyt0z2?i}NXs5ZiTB5^Ko8+J7GyTT(&z-|;TCf>;mY5(NAIsf2Oq@ZB zZFHUq84~8j{Jn(PWB4Nhf`rS{)(JV@c|+0wjJVovO$_Y&QwC`}BFQh(Tgld8M>Ib2&Tn#Rw=M)HG1TQW)*ky3 zI@Wj4Mh->e7r*3Nm>n5|un=l(-RE@g=svG|cNACNgRh8swQ$H%rG=f~caLkg9^AfP zOYKLu9xtc%-CN7IQn&W#-u;JfKdGheorez|-LEazj%EE7Z1E$snDVO2oZ(**UgKW* z@r|;VcuBb$SAf$)Aj;*$^Qzk1uEjs~3m+Ug?|v#?$Fk9RIcr#aTG%jo=QJV*w?4DD z&2yjR8hPPx=QGCh-2KFExa1U?qVSo?JzfN^AUsV`;$@7A*rmj2w!)_{F6%gSBAtFP zigkBIvxlg^^}7s+{m|c!gML@UF+!yu#=Z_qek)Qv|B;TTzMw!JU-vv8zvXq|Q|R=` z`2AMwOQ8lb5}ekC8)2&xBI@~A9d_; zPha(0t3DTTOA3BnQ`ae?uJi^G59MY$+YO%ut3BBbvUNe++7hXgG14S682t#&quoJ^ z+vt?BV!sy$~Yw_VyJ`m(05zJa2` z4GOXKx8iGf<+b?7i;LIdR~8q4`m^`ndp~+#e(){elF3muzN#tzZ^G(SS|AODQihwU zvocs+6*6_3y)F{J67t*FN1Lmx0!ni+Ig4B(*pvwLM2IMwdiU?uYr$`^)!eA}#iZ=_|mZ;z;rsKoNE}}&fLotT3eJg6IAb5;Xd>NgQ%UlV4 z(Pk!_{@OI{ubjdd-a38QOs|i2sWSPG*rG{MY4jttx@cOhs{pp96QgbHLalpjoBgX1 zowE&PZobM4`YVfOcQEsBMr3|_Ol^YN+^23FqBb*XWy3Jc9i7(ee6t+ls1|d;>&{JgPYrM4chfloRnsi>;Iqh>tq0NDQzf zrc%Kmaj_EG@M&(HKO(Bhl~q&cfJ|l-dLq7u#S=Eylv$&;y@^<`wi?_tx-BIq4jHnI!|_VrAO zh=Vl}MaJJDqbW(z6s?UcrT!9BF{Kv+iQ6?@n9JPXP1`;0?33#b*a%fCl>YU3*KvAf zY{S9ZI91zvYRUw#jZ+wHhpZqm_1T{#=5C&>XxHVi4tW#Q1vov6TtFT{sz__N0m{;z z@hkH*Sr%DXhAR{94MSBDi(8+<=AN_Y516I*dQZ*gOny&I9e(d~Q{GIBU9#c>JA*TO zA2-~Y+ljrwD*kwjFg+%_h$7DUNgPnA>>`=dqKUxO7Hv za8Au7Zek}$E}vT4(5RZ%qr#`=Hu1SY=LFxRX*~wtrgVst-P4?`GwyBMv2;@pulGWq+1(gi2GN9CKzb-REkPQ2|A7vuf4o{a6{z7`6HG~ki+ z6YDvP|2ru@H{+Y?d}1XshqR zt;yb?pL$3vQpF$PE+$_ka;oEW<*Rd!RH+4**B6zveEa^b`n!S7IFD;-CCKiU!#jt( zO)IIIl2jx~A6;s#38hPReU*^^Ksb99aW>04H6nbSx+~P_$V0WPq~bR9T97IDi<&}G z@mVeDz?0^5A(Q61p~7iMD_VYOaY7{^dZuJJmU^Q|k_!;e*VKBWz(oh?4dGsrj1LEK zFT(0TzvkDNjwL#S*=C7V5Xz<*-9_f`te6!9b&oBuX}X=5CUd@aEzIL@X8*5TM?-&i z>=LLKawX>A>9HBTi;KR5l{44}yPLEtjc2jr*4ZN|V$4?)p>Y340dhY`{v3lfW7||Z zks`dqVG_1$?iqKD58gzGvv#dLRH;ubxqzgI1VQ8797oN%XCnC6+c`L`lh}k$a@4OP zh%)2D1(in%CFjUxDb)WP@$eYBX>ZWt=)Nb9aJr3?XtS{fIKe@Gh?_oWFu~_k7 z1;*Czv=k-An5;{-`m%^+fC-;EVZTqtMj;=0Xq;roJ5rn0X?>vuHctny1jkn6`)ykoZ2tKt0yw}84US9;M{!A^@)ACI~Qk(AE1kr~F z*`SUX*KAC%rkSM5Kwd}pE}H(};4-^ld}WfwF!O&(S1P61V&#FRX@cg!&%)>?T1*Z) zx^oDNGj8IZ0IlJkKz9#|=P-779%Dz}vfPP#LoL$xhB{&km669+7GzX9(^Ao*3u!~K zHkHekt`Hz5J6k@EEfi`-HG$swkX}e!e?`+*WCQ1&s1k=vjjKdc{sg2)nWK=he*^d- z;<5sJ3W-r(Mc_7-)wWR#T*Z^_04R9c&U+aRZUU<)`(!$zBO0{Ay0u}*lptC`LoS!_v zxr-7HRP!k1)GRL~NM{_SPTNFU!<#-vSqRT9*0mza-r}N8ZDlW}E5&7_ayynyQ znl~RuLCcU*BbJ z_|;SL2`F`LIh?O_7SfTOK0##}gpx;QdmcgbDJe^&I^F0Pk;6?@$Sj%c=MkNlP~_`) zqOD7Btk( zPHlm&&H9syB(Om8q2e2!} zxYQHRnj-t8oLvp#Q~Q- literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/request.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/request.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f30fdf0a0d958f54351279b0515a3fd5224cc27 GIT binary patch literal 17194 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/utils.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/utils.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2def1df83e72347a2ed0eeba879dcb236cf39d44 GIT binary patch literal 3902 zcmcInO>Y~=8Q$4lQY1~uiefZ&+6GfMiOp0cjW~ydNSy?B+Xx8Qz_L+PKufMTLvgL; zEPhDbXXXgEwnfK$F zm(lWa!^86r^UuMpRnPl74NgBb3_ixI|B6Og*4OzeB$#Y`qNg!&X{wUmPid9QlwiI@68C)y#ne&&tk$=g9 zgqye07}Z7NNkyC!%}153Rq+bAN%x5cT7$-~Sl;C)Rk0$@gLh4^O|P}~45#pV&wR8k zRyO-G9cDuIW06J}FK^0Wu3|I$xl)EF*YBU?dP8)w?2(L|O_ zqjGJe=qIr@WmQR&t8_?9ES@EF>UeMB)qg`%c)CU#GG4(9JM`7Xg6*&a^o=k4Cor!F zAB6}0ezWik?~ok?zxL7#p=W~Gr_7_@Z{Uhe?;7N9dB05$!Xi8hMdc||X%UL5So#Bu zcMyu&K_v|ZJE&MqAv9H?>3dewpBI|oET^kl1iQZa3ggWDGuu%y29dphHcK2nz)6r3ilXh|wC%QeIm5qLysR_)xFE3(cT}9)u8e8@Ee@uSv z$GSiFO8dhk8%Bw~(LRwWSzDchMDNbO=v3`iwQR&1wlz^Ylx3ieDl6MFBX!xlo5qxX zHr>jGa}{~2tjSbp>a~`fxe15Vc{E!qi^S_YC4rKot)|XLqxfOphQU@HQ;uqF=b9A= zm*-zP0C`cj(RlTcg?@uo{ne_^n)ucH8f)NN^+VsyG%!>3*FaI1AknInRgHiJ1e~*K z$1)O9VNxnYPr1AZT_S21Fcct*r-BZRZ{pQop+TO81p*~!YOO#&Z5KcTj6TMfLMOyG zyadR#bKzr8RNTyC@5=yGPgD_b17LwCmXNXN0iJ6P3(_}0uY>-Dr8huF5A<`6UIbR} z5yCSpf)0gIYN_}CZAUj~Ql_n1e}u0(GlI&WK$;|8fqr{kkc*}+bXxZ^g%r9lSG zbNnswq#ZR!mM&ai_4hqhcx(YDxO zH()b5OOqKNW~o6c+ZCor2LdRhe5|b!5syYvK{4o&W1_$mkrLc;FHSO5naPG(GC#qu zriRcUNoMN=4e@A33P{V`0@%_5?Q%r>j$N%g%F|)j9rGk>1{@1=6~$We$nnXCVEbZ` zl5Gs7T~N2rTuC_j{4ivrvw-SC(ZT6r^LBem-p?g0PZnDTe(p*>7+fA3Gu4-2b+>^N zQ0}`hc8UgrPvKrz+)Z+zZZ6M=IG+HSg@DJjMSa-BO}DYqRr1feHEwG#Sm&9tD-t$? zIE~DBo%ga-f@s4iPveJNXTx1-5I)2aG2Q(1aFi|ZB*6_r^xs3<5yGJWYk(ECC6{cF$u z{o=(7M+hEhT~@4P_QURb?_GcPEol1{+CAT2rKqROSS->C)N9aZu}Be+v?}U#n)p67 zKcMD^Xs{mSUk1Y3jx>EDybl)r1{&}6knjyaU-O%64LG;L)>zY`;Ht0Q21l#v7I+K& zvaYhs^vQo^Xxk>jOwIaO3*qnJjv#LF&^1D@g}Wnk07ndEPjEmW=I5Szr>Fq9f~Sn( zjuhdMU!b6&o08^DQ1~cuKs{u{al&hX%TvGmuQF7?oXCXgPgV|kod#&N<VdN=_Jlk)9NJBjA)Pn&9^-K6jQ*(qx&-t3lTmT+9C>p`okUZYeOX8;!WUdAm6m9N1N=W79 zk1jhT0Z?>0C>A@467@OzXusKg`>mh-A7Z@bt9L None: + self.buffer = bytearray() + self.complete = False + self.max_form_memory_size = max_form_memory_size + self.state = State.PREAMBLE + self.boundary = boundary + + # Note in the below \h i.e. horizontal whitespace is used + # as [^\S\n\r] as \h isn't supported in python. + + # The preamble must end with a boundary where the boundary is + # prefixed by a line break, RFC2046. Except that many + # implementations including Werkzeug's tests omit the line + # break prefix. In addition the first boundary could be the + # epilogue boundary (for empty form-data) hence the matching + # group to understand if it is an epilogue boundary. + self.preamble_re = re.compile( + br"%s?--%s(--[^\S\n\r]*%s?|[^\S\n\r]*%s)" + % (LINE_BREAK, re.escape(boundary), LINE_BREAK, LINE_BREAK), + re.MULTILINE, + ) + # A boundary must include a line break prefix and suffix, and + # may include trailing whitespace. In addition the boundary + # could be the epilogue boundary hence the matching group to + # understand if it is an epilogue boundary. + self.boundary_re = re.compile( + br"%s--%s(--[^\S\n\r]*%s?|[^\S\n\r]*%s)" + % (LINE_BREAK, re.escape(boundary), LINE_BREAK, LINE_BREAK), + re.MULTILINE, + ) + + def last_newline(self) -> int: + try: + last_nl = self.buffer.rindex(b"\n") + except ValueError: + last_nl = len(self.buffer) + try: + last_cr = self.buffer.rindex(b"\r") + except ValueError: + last_cr = len(self.buffer) + + return min(last_nl, last_cr) + + def receive_data(self, data: Optional[bytes]) -> None: + if data is None: + self.complete = True + elif ( + self.max_form_memory_size is not None + and len(self.buffer) + len(data) > self.max_form_memory_size + ): + raise RequestEntityTooLarge() + else: + self.buffer.extend(data) + + def next_event(self) -> Event: + event: Event = NEED_DATA + + if self.state == State.PREAMBLE: + match = self.preamble_re.search(self.buffer) + if match is not None: + if match.group(1).startswith(b"--"): + self.state = State.EPILOGUE + else: + self.state = State.PART + data = bytes(self.buffer[: match.start()]) + del self.buffer[: match.end()] + event = Preamble(data=data) + + elif self.state == State.PART: + match = BLANK_LINE_RE.search(self.buffer) + if match is not None: + headers = self._parse_headers(self.buffer[: match.start()]) + del self.buffer[: match.end()] + + if "content-disposition" not in headers: + raise ValueError("Missing Content-Disposition header") + + disposition, extra = parse_options_header( + headers["content-disposition"] + ) + name = cast(str, extra.get("name")) + filename = extra.get("filename") + if filename is not None: + event = File( + filename=filename, + headers=headers, + name=name, + ) + else: + event = Field( + headers=headers, + name=name, + ) + self.state = State.DATA + + elif self.state == State.DATA: + if self.buffer.find(b"--" + self.boundary) == -1: + # No complete boundary in the buffer, but there may be + # a partial boundary at the end. As the boundary + # starts with either a nl or cr find the earliest and + # return up to that as data. + data_length = del_index = self.last_newline() + more_data = True + else: + match = self.boundary_re.search(self.buffer) + if match is not None: + if match.group(1).startswith(b"--"): + self.state = State.EPILOGUE + else: + self.state = State.PART + data_length = match.start() + del_index = match.end() + else: + data_length = del_index = self.last_newline() + more_data = match is None + + data = bytes(self.buffer[:data_length]) + del self.buffer[:del_index] + if data or not more_data: + event = Data(data=data, more_data=more_data) + + elif self.state == State.EPILOGUE and self.complete: + event = Epilogue(data=bytes(self.buffer)) + del self.buffer[:] + self.state = State.COMPLETE + + if self.complete and isinstance(event, NeedData): + raise ValueError(f"Invalid form-data cannot parse beyond {self.state}") + + return event + + def _parse_headers(self, data: bytes) -> Headers: + headers: List[Tuple[str, str]] = [] + # Merge the continued headers into one line + data = HEADER_CONTINUATION_RE.sub(b" ", data) + # Now there is one header per line + for line in data.splitlines(): + if line.strip() != b"": + name, value = _to_str(line).strip().split(":", 1) + headers.append((name.strip(), value.strip())) + return Headers(headers) + + +class MultipartEncoder: + def __init__(self, boundary: bytes) -> None: + self.boundary = boundary + self.state = State.PREAMBLE + + def send_event(self, event: Event) -> bytes: + if isinstance(event, Preamble) and self.state == State.PREAMBLE: + self.state = State.PART + return event.data + elif isinstance(event, (Field, File)) and self.state in { + State.PREAMBLE, + State.PART, + State.DATA, + }: + self.state = State.DATA + data = b"\r\n--" + self.boundary + b"\r\n" + data += b'Content-Disposition: form-data; name="%s"' % _to_bytes(event.name) + if isinstance(event, File): + data += b'; filename="%s"' % _to_bytes(event.filename) + data += b"\r\n" + for name, value in cast(Field, event).headers: + if name.lower() != "content-disposition": + data += _to_bytes(f"{name}: {value}\r\n") + data += b"\r\n" + return data + elif isinstance(event, Data) and self.state == State.DATA: + return event.data + elif isinstance(event, Epilogue): + self.state = State.COMPLETE + return b"\r\n--" + self.boundary + b"--\r\n" + event.data + else: + raise ValueError(f"Cannot generate {event} in state: {self.state}") diff --git a/venv/lib/python3.9/site-packages/werkzeug/sansio/request.py b/venv/lib/python3.9/site-packages/werkzeug/sansio/request.py new file mode 100644 index 0000000..2c21a21 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/sansio/request.py @@ -0,0 +1,548 @@ +import typing as t +from datetime import datetime + +from .._internal import _to_str +from ..datastructures import Accept +from ..datastructures import Authorization +from ..datastructures import CharsetAccept +from ..datastructures import ETags +from ..datastructures import Headers +from ..datastructures import HeaderSet +from ..datastructures import IfRange +from ..datastructures import ImmutableList +from ..datastructures import ImmutableMultiDict +from ..datastructures import LanguageAccept +from ..datastructures import MIMEAccept +from ..datastructures import MultiDict +from ..datastructures import Range +from ..datastructures import RequestCacheControl +from ..http import parse_accept_header +from ..http import parse_authorization_header +from ..http import parse_cache_control_header +from ..http import parse_cookie +from ..http import parse_date +from ..http import parse_etags +from ..http import parse_if_range_header +from ..http import parse_list_header +from ..http import parse_options_header +from ..http import parse_range_header +from ..http import parse_set_header +from ..urls import url_decode +from ..user_agent import UserAgent +from ..useragents import _UserAgent as _DeprecatedUserAgent +from ..utils import cached_property +from ..utils import header_property +from .utils import get_current_url +from .utils import get_host + + +class Request: + """Represents the non-IO parts of a HTTP request, including the + method, URL info, and headers. + + This class is not meant for general use. It should only be used when + implementing WSGI, ASGI, or another HTTP application spec. Werkzeug + provides a WSGI implementation at :cls:`werkzeug.wrappers.Request`. + + :param method: The method the request was made with, such as + ``GET``. + :param scheme: The URL scheme of the protocol the request used, such + as ``https`` or ``wss``. + :param server: The address of the server. ``(host, port)``, + ``(path, None)`` for unix sockets, or ``None`` if not known. + :param root_path: The prefix that the application is mounted under. + This is prepended to generated URLs, but is not part of route + matching. + :param path: The path part of the URL after ``root_path``. + :param query_string: The part of the URL after the "?". + :param headers: The headers received with the request. + :param remote_addr: The address of the client sending the request. + + .. versionadded:: 2.0 + """ + + #: The charset used to decode most data in the request. + charset = "utf-8" + + #: the error handling procedure for errors, defaults to 'replace' + encoding_errors = "replace" + + #: the class to use for `args` and `form`. The default is an + #: :class:`~werkzeug.datastructures.ImmutableMultiDict` which supports + #: multiple values per key. alternatively it makes sense to use an + #: :class:`~werkzeug.datastructures.ImmutableOrderedMultiDict` which + #: preserves order or a :class:`~werkzeug.datastructures.ImmutableDict` + #: which is the fastest but only remembers the last key. It is also + #: possible to use mutable structures, but this is not recommended. + #: + #: .. versionadded:: 0.6 + parameter_storage_class: t.Type[MultiDict] = ImmutableMultiDict + + #: The type to be used for dict values from the incoming WSGI + #: environment. (For example for :attr:`cookies`.) By default an + #: :class:`~werkzeug.datastructures.ImmutableMultiDict` is used. + #: + #: .. versionchanged:: 1.0.0 + #: Changed to ``ImmutableMultiDict`` to support multiple values. + #: + #: .. versionadded:: 0.6 + dict_storage_class: t.Type[MultiDict] = ImmutableMultiDict + + #: the type to be used for list values from the incoming WSGI environment. + #: By default an :class:`~werkzeug.datastructures.ImmutableList` is used + #: (for example for :attr:`access_list`). + #: + #: .. versionadded:: 0.6 + list_storage_class: t.Type[t.List] = ImmutableList + + user_agent_class = _DeprecatedUserAgent + """The class used and returned by the :attr:`user_agent` property to + parse the header. Defaults to + :class:`~werkzeug.user_agent.UserAgent`, which does no parsing. An + extension can provide a subclass that uses a parser to provide other + data. + + .. versionadded:: 2.0 + """ + + #: Valid host names when handling requests. By default all hosts are + #: trusted, which means that whatever the client says the host is + #: will be accepted. + #: + #: Because ``Host`` and ``X-Forwarded-Host`` headers can be set to + #: any value by a malicious client, it is recommended to either set + #: this property or implement similar validation in the proxy (if + #: the application is being run behind one). + #: + #: .. versionadded:: 0.9 + trusted_hosts: t.Optional[t.List[str]] = None + + def __init__( + self, + method: str, + scheme: str, + server: t.Optional[t.Tuple[str, t.Optional[int]]], + root_path: str, + path: str, + query_string: bytes, + headers: Headers, + remote_addr: t.Optional[str], + ) -> None: + #: The method the request was made with, such as ``GET``. + self.method = method.upper() + #: The URL scheme of the protocol the request used, such as + #: ``https`` or ``wss``. + self.scheme = scheme + #: The address of the server. ``(host, port)``, ``(path, None)`` + #: for unix sockets, or ``None`` if not known. + self.server = server + #: The prefix that the application is mounted under, without a + #: trailing slash. :attr:`path` comes after this. + self.root_path = root_path.rstrip("/") + #: The path part of the URL after :attr:`root_path`. This is the + #: path used for routing within the application. + self.path = "/" + path.lstrip("/") + #: The part of the URL after the "?". This is the raw value, use + #: :attr:`args` for the parsed values. + self.query_string = query_string + #: The headers received with the request. + self.headers = headers + #: The address of the client sending the request. + self.remote_addr = remote_addr + + def __repr__(self) -> str: + try: + url = self.url + except Exception as e: + url = f"(invalid URL: {e})" + + return f"<{type(self).__name__} {url!r} [{self.method}]>" + + @property + def url_charset(self) -> str: + """The charset that is assumed for URLs. Defaults to the value + of :attr:`charset`. + + .. versionadded:: 0.6 + """ + return self.charset + + @cached_property + def args(self) -> "MultiDict[str, str]": + """The parsed URL parameters (the part in the URL after the question + mark). + + By default an + :class:`~werkzeug.datastructures.ImmutableMultiDict` + is returned from this function. This can be changed by setting + :attr:`parameter_storage_class` to a different type. This might + be necessary if the order of the form data is important. + """ + return url_decode( + self.query_string, + self.url_charset, + errors=self.encoding_errors, + cls=self.parameter_storage_class, + ) + + @cached_property + def access_route(self) -> t.List[str]: + """If a forwarded header exists this is a list of all ip addresses + from the client ip to the last proxy server. + """ + if "X-Forwarded-For" in self.headers: + return self.list_storage_class( + parse_list_header(self.headers["X-Forwarded-For"]) + ) + elif self.remote_addr is not None: + return self.list_storage_class([self.remote_addr]) + return self.list_storage_class() + + @cached_property + def full_path(self) -> str: + """Requested path, including the query string.""" + return f"{self.path}?{_to_str(self.query_string, self.url_charset)}" + + @property + def is_secure(self) -> bool: + """``True`` if the request was made with a secure protocol + (HTTPS or WSS). + """ + return self.scheme in {"https", "wss"} + + @cached_property + def url(self) -> str: + """The full request URL with the scheme, host, root path, path, + and query string.""" + return get_current_url( + self.scheme, self.host, self.root_path, self.path, self.query_string + ) + + @cached_property + def base_url(self) -> str: + """Like :attr:`url` but without the query string.""" + return get_current_url(self.scheme, self.host, self.root_path, self.path) + + @cached_property + def root_url(self) -> str: + """The request URL scheme, host, and root path. This is the root + that the application is accessed from. + """ + return get_current_url(self.scheme, self.host, self.root_path) + + @cached_property + def host_url(self) -> str: + """The request URL scheme and host only.""" + return get_current_url(self.scheme, self.host) + + @cached_property + def host(self) -> str: + """The host name the request was made to, including the port if + it's non-standard. Validated with :attr:`trusted_hosts`. + """ + return get_host( + self.scheme, self.headers.get("host"), self.server, self.trusted_hosts + ) + + @cached_property + def cookies(self) -> "ImmutableMultiDict[str, str]": + """A :class:`dict` with the contents of all cookies transmitted with + the request.""" + wsgi_combined_cookie = ";".join(self.headers.getlist("Cookie")) + return parse_cookie( # type: ignore + wsgi_combined_cookie, + self.charset, + self.encoding_errors, + cls=self.dict_storage_class, + ) + + # Common Descriptors + + content_type = header_property[str]( + "Content-Type", + doc="""The Content-Type entity-header field indicates the media + type of the entity-body sent to the recipient or, in the case of + the HEAD method, the media type that would have been sent had + the request been a GET.""", + read_only=True, + ) + + @cached_property + def content_length(self) -> t.Optional[int]: + """The Content-Length entity-header field indicates the size of the + entity-body in bytes or, in the case of the HEAD method, the size of + the entity-body that would have been sent had the request been a + GET. + """ + if self.headers.get("Transfer-Encoding", "") == "chunked": + return None + + content_length = self.headers.get("Content-Length") + if content_length is not None: + try: + return max(0, int(content_length)) + except (ValueError, TypeError): + pass + + return None + + content_encoding = header_property[str]( + "Content-Encoding", + doc="""The Content-Encoding entity-header field is used as a + modifier to the media-type. When present, its value indicates + what additional content codings have been applied to the + entity-body, and thus what decoding mechanisms must be applied + in order to obtain the media-type referenced by the Content-Type + header field. + + .. versionadded:: 0.9""", + read_only=True, + ) + content_md5 = header_property[str]( + "Content-MD5", + doc="""The Content-MD5 entity-header field, as defined in + RFC 1864, is an MD5 digest of the entity-body for the purpose of + providing an end-to-end message integrity check (MIC) of the + entity-body. (Note: a MIC is good for detecting accidental + modification of the entity-body in transit, but is not proof + against malicious attacks.) + + .. versionadded:: 0.9""", + read_only=True, + ) + referrer = header_property[str]( + "Referer", + doc="""The Referer[sic] request-header field allows the client + to specify, for the server's benefit, the address (URI) of the + resource from which the Request-URI was obtained (the + "referrer", although the header field is misspelled).""", + read_only=True, + ) + date = header_property( + "Date", + None, + parse_date, + doc="""The Date general-header field represents the date and + time at which the message was originated, having the same + semantics as orig-date in RFC 822. + + .. versionchanged:: 2.0 + The datetime object is timezone-aware. + """, + read_only=True, + ) + max_forwards = header_property( + "Max-Forwards", + None, + int, + doc="""The Max-Forwards request-header field provides a + mechanism with the TRACE and OPTIONS methods to limit the number + of proxies or gateways that can forward the request to the next + inbound server.""", + read_only=True, + ) + + def _parse_content_type(self) -> None: + if not hasattr(self, "_parsed_content_type"): + self._parsed_content_type = parse_options_header( + self.headers.get("Content-Type", "") + ) + + @property + def mimetype(self) -> str: + """Like :attr:`content_type`, but without parameters (eg, without + charset, type etc.) and always lowercase. For example if the content + type is ``text/HTML; charset=utf-8`` the mimetype would be + ``'text/html'``. + """ + self._parse_content_type() + return self._parsed_content_type[0].lower() + + @property + def mimetype_params(self) -> t.Dict[str, str]: + """The mimetype parameters as dict. For example if the content + type is ``text/html; charset=utf-8`` the params would be + ``{'charset': 'utf-8'}``. + """ + self._parse_content_type() + return self._parsed_content_type[1] + + @cached_property + def pragma(self) -> HeaderSet: + """The Pragma general-header field is used to include + implementation-specific directives that might apply to any recipient + along the request/response chain. All pragma directives specify + optional behavior from the viewpoint of the protocol; however, some + systems MAY require that behavior be consistent with the directives. + """ + return parse_set_header(self.headers.get("Pragma", "")) + + # Accept + + @cached_property + def accept_mimetypes(self) -> MIMEAccept: + """List of mimetypes this client supports as + :class:`~werkzeug.datastructures.MIMEAccept` object. + """ + return parse_accept_header(self.headers.get("Accept"), MIMEAccept) + + @cached_property + def accept_charsets(self) -> CharsetAccept: + """List of charsets this client supports as + :class:`~werkzeug.datastructures.CharsetAccept` object. + """ + return parse_accept_header(self.headers.get("Accept-Charset"), CharsetAccept) + + @cached_property + def accept_encodings(self) -> Accept: + """List of encodings this client accepts. Encodings in a HTTP term + are compression encodings such as gzip. For charsets have a look at + :attr:`accept_charset`. + """ + return parse_accept_header(self.headers.get("Accept-Encoding")) + + @cached_property + def accept_languages(self) -> LanguageAccept: + """List of languages this client accepts as + :class:`~werkzeug.datastructures.LanguageAccept` object. + + .. versionchanged 0.5 + In previous versions this was a regular + :class:`~werkzeug.datastructures.Accept` object. + """ + return parse_accept_header(self.headers.get("Accept-Language"), LanguageAccept) + + # ETag + + @cached_property + def cache_control(self) -> RequestCacheControl: + """A :class:`~werkzeug.datastructures.RequestCacheControl` object + for the incoming cache control headers. + """ + cache_control = self.headers.get("Cache-Control") + return parse_cache_control_header(cache_control, None, RequestCacheControl) + + @cached_property + def if_match(self) -> ETags: + """An object containing all the etags in the `If-Match` header. + + :rtype: :class:`~werkzeug.datastructures.ETags` + """ + return parse_etags(self.headers.get("If-Match")) + + @cached_property + def if_none_match(self) -> ETags: + """An object containing all the etags in the `If-None-Match` header. + + :rtype: :class:`~werkzeug.datastructures.ETags` + """ + return parse_etags(self.headers.get("If-None-Match")) + + @cached_property + def if_modified_since(self) -> t.Optional[datetime]: + """The parsed `If-Modified-Since` header as a datetime object. + + .. versionchanged:: 2.0 + The datetime object is timezone-aware. + """ + return parse_date(self.headers.get("If-Modified-Since")) + + @cached_property + def if_unmodified_since(self) -> t.Optional[datetime]: + """The parsed `If-Unmodified-Since` header as a datetime object. + + .. versionchanged:: 2.0 + The datetime object is timezone-aware. + """ + return parse_date(self.headers.get("If-Unmodified-Since")) + + @cached_property + def if_range(self) -> IfRange: + """The parsed ``If-Range`` header. + + .. versionchanged:: 2.0 + ``IfRange.date`` is timezone-aware. + + .. versionadded:: 0.7 + """ + return parse_if_range_header(self.headers.get("If-Range")) + + @cached_property + def range(self) -> t.Optional[Range]: + """The parsed `Range` header. + + .. versionadded:: 0.7 + + :rtype: :class:`~werkzeug.datastructures.Range` + """ + return parse_range_header(self.headers.get("Range")) + + # User Agent + + @cached_property + def user_agent(self) -> UserAgent: + """The user agent. Use ``user_agent.string`` to get the header + value. Set :attr:`user_agent_class` to a subclass of + :class:`~werkzeug.user_agent.UserAgent` to provide parsing for + the other properties or other extended data. + + .. versionchanged:: 2.0 + The built in parser is deprecated and will be removed in + Werkzeug 2.1. A ``UserAgent`` subclass must be set to parse + data from the string. + """ + return self.user_agent_class(self.headers.get("User-Agent", "")) + + # Authorization + + @cached_property + def authorization(self) -> t.Optional[Authorization]: + """The `Authorization` object in parsed form.""" + return parse_authorization_header(self.headers.get("Authorization")) + + # CORS + + origin = header_property[str]( + "Origin", + doc=( + "The host that the request originated from. Set" + " :attr:`~CORSResponseMixin.access_control_allow_origin` on" + " the response to indicate which origins are allowed." + ), + read_only=True, + ) + + access_control_request_headers = header_property( + "Access-Control-Request-Headers", + load_func=parse_set_header, + doc=( + "Sent with a preflight request to indicate which headers" + " will be sent with the cross origin request. Set" + " :attr:`~CORSResponseMixin.access_control_allow_headers`" + " on the response to indicate which headers are allowed." + ), + read_only=True, + ) + + access_control_request_method = header_property[str]( + "Access-Control-Request-Method", + doc=( + "Sent with a preflight request to indicate which method" + " will be used for the cross origin request. Set" + " :attr:`~CORSResponseMixin.access_control_allow_methods`" + " on the response to indicate which methods are allowed." + ), + read_only=True, + ) + + @property + def is_json(self) -> bool: + """Check if the mimetype indicates JSON data, either + :mimetype:`application/json` or :mimetype:`application/*+json`. + """ + mt = self.mimetype + return ( + mt == "application/json" + or mt.startswith("application/") + and mt.endswith("+json") + ) diff --git a/venv/lib/python3.9/site-packages/werkzeug/sansio/response.py b/venv/lib/python3.9/site-packages/werkzeug/sansio/response.py new file mode 100644 index 0000000..aedfcb0 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/sansio/response.py @@ -0,0 +1,656 @@ +import typing +import typing as t +from datetime import datetime +from datetime import timedelta +from datetime import timezone +from http import HTTPStatus + +from .._internal import _to_str +from ..datastructures import Headers +from ..datastructures import HeaderSet +from ..http import dump_cookie +from ..http import HTTP_STATUS_CODES +from ..utils import get_content_type +from werkzeug.datastructures import CallbackDict +from werkzeug.datastructures import ContentRange +from werkzeug.datastructures import ResponseCacheControl +from werkzeug.datastructures import WWWAuthenticate +from werkzeug.http import COEP +from werkzeug.http import COOP +from werkzeug.http import dump_age +from werkzeug.http import dump_csp_header +from werkzeug.http import dump_header +from werkzeug.http import dump_options_header +from werkzeug.http import http_date +from werkzeug.http import parse_age +from werkzeug.http import parse_cache_control_header +from werkzeug.http import parse_content_range_header +from werkzeug.http import parse_csp_header +from werkzeug.http import parse_date +from werkzeug.http import parse_options_header +from werkzeug.http import parse_set_header +from werkzeug.http import parse_www_authenticate_header +from werkzeug.http import quote_etag +from werkzeug.http import unquote_etag +from werkzeug.utils import header_property + + +def _set_property(name: str, doc: t.Optional[str] = None) -> property: + def fget(self: "Response") -> HeaderSet: + def on_update(header_set: HeaderSet) -> None: + if not header_set and name in self.headers: + del self.headers[name] + elif header_set: + self.headers[name] = header_set.to_header() + + return parse_set_header(self.headers.get(name), on_update) + + def fset( + self: "Response", + value: t.Optional[ + t.Union[str, t.Dict[str, t.Union[str, int]], t.Iterable[str]] + ], + ) -> None: + if not value: + del self.headers[name] + elif isinstance(value, str): + self.headers[name] = value + else: + self.headers[name] = dump_header(value) + + return property(fget, fset, doc=doc) + + +class Response: + """Represents the non-IO parts of an HTTP response, specifically the + status and headers but not the body. + + This class is not meant for general use. It should only be used when + implementing WSGI, ASGI, or another HTTP application spec. Werkzeug + provides a WSGI implementation at :cls:`werkzeug.wrappers.Response`. + + :param status: The status code for the response. Either an int, in + which case the default status message is added, or a string in + the form ``{code} {message}``, like ``404 Not Found``. Defaults + to 200. + :param headers: A :class:`~werkzeug.datastructures.Headers` object, + or a list of ``(key, value)`` tuples that will be converted to a + ``Headers`` object. + :param mimetype: The mime type (content type without charset or + other parameters) of the response. If the value starts with + ``text/`` (or matches some other special cases), the charset + will be added to create the ``content_type``. + :param content_type: The full content type of the response. + Overrides building the value from ``mimetype``. + + .. versionadded:: 2.0 + """ + + #: the charset of the response. + charset = "utf-8" + + #: the default status if none is provided. + default_status = 200 + + #: the default mimetype if none is provided. + default_mimetype = "text/plain" + + #: Warn if a cookie header exceeds this size. The default, 4093, should be + #: safely `supported by most browsers `_. A cookie larger than + #: this size will still be sent, but it may be ignored or handled + #: incorrectly by some browsers. Set to 0 to disable this check. + #: + #: .. versionadded:: 0.13 + #: + #: .. _`cookie`: http://browsercookielimits.squawky.net/ + max_cookie_size = 4093 + + # A :class:`Headers` object representing the response headers. + headers: Headers + + def __init__( + self, + status: t.Optional[t.Union[int, str, HTTPStatus]] = None, + headers: t.Optional[ + t.Union[ + t.Mapping[str, t.Union[str, int, t.Iterable[t.Union[str, int]]]], + t.Iterable[t.Tuple[str, t.Union[str, int]]], + ] + ] = None, + mimetype: t.Optional[str] = None, + content_type: t.Optional[str] = None, + ) -> None: + if isinstance(headers, Headers): + self.headers = headers + elif not headers: + self.headers = Headers() + else: + self.headers = Headers(headers) + + if content_type is None: + if mimetype is None and "content-type" not in self.headers: + mimetype = self.default_mimetype + if mimetype is not None: + mimetype = get_content_type(mimetype, self.charset) + content_type = mimetype + if content_type is not None: + self.headers["Content-Type"] = content_type + if status is None: + status = self.default_status + self.status = status # type: ignore + + def __repr__(self) -> str: + return f"<{type(self).__name__} [{self.status}]>" + + @property + def status_code(self) -> int: + """The HTTP status code as a number.""" + return self._status_code + + @status_code.setter + def status_code(self, code: int) -> None: + self.status = code # type: ignore + + @property + def status(self) -> str: + """The HTTP status code as a string.""" + return self._status + + @status.setter + def status(self, value: t.Union[str, int, HTTPStatus]) -> None: + if not isinstance(value, (str, bytes, int, HTTPStatus)): + raise TypeError("Invalid status argument") + + self._status, self._status_code = self._clean_status(value) + + def _clean_status(self, value: t.Union[str, int, HTTPStatus]) -> t.Tuple[str, int]: + if isinstance(value, HTTPStatus): + value = int(value) + status = _to_str(value, self.charset) + split_status = status.split(None, 1) + + if len(split_status) == 0: + raise ValueError("Empty status argument") + + if len(split_status) > 1: + if split_status[0].isdigit(): + # code and message + return status, int(split_status[0]) + + # multi-word message + return f"0 {status}", 0 + + if split_status[0].isdigit(): + # code only + status_code = int(split_status[0]) + + try: + status = f"{status_code} {HTTP_STATUS_CODES[status_code].upper()}" + except KeyError: + status = f"{status_code} UNKNOWN" + + return status, status_code + + # one-word message + return f"0 {status}", 0 + + def set_cookie( + self, + key: str, + value: str = "", + max_age: t.Optional[t.Union[timedelta, int]] = None, + expires: t.Optional[t.Union[str, datetime, int, float]] = None, + path: t.Optional[str] = "/", + domain: t.Optional[str] = None, + secure: bool = False, + httponly: bool = False, + samesite: t.Optional[str] = None, + ) -> None: + """Sets a cookie. + + A warning is raised if the size of the cookie header exceeds + :attr:`max_cookie_size`, but the header will still be set. + + :param key: the key (name) of the cookie to be set. + :param value: the value of the cookie. + :param max_age: should be a number of seconds, or `None` (default) if + the cookie should last only as long as the client's + browser session. + :param expires: should be a `datetime` object or UNIX timestamp. + :param path: limits the cookie to a given path, per default it will + span the whole domain. + :param domain: if you want to set a cross-domain cookie. For example, + ``domain=".example.com"`` will set a cookie that is + readable by the domain ``www.example.com``, + ``foo.example.com`` etc. Otherwise, a cookie will only + be readable by the domain that set it. + :param secure: If ``True``, the cookie will only be available + via HTTPS. + :param httponly: Disallow JavaScript access to the cookie. + :param samesite: Limit the scope of the cookie to only be + attached to requests that are "same-site". + """ + self.headers.add( + "Set-Cookie", + dump_cookie( + key, + value=value, + max_age=max_age, + expires=expires, + path=path, + domain=domain, + secure=secure, + httponly=httponly, + charset=self.charset, + max_size=self.max_cookie_size, + samesite=samesite, + ), + ) + + def delete_cookie( + self, + key: str, + path: str = "/", + domain: t.Optional[str] = None, + secure: bool = False, + httponly: bool = False, + samesite: t.Optional[str] = None, + ) -> None: + """Delete a cookie. Fails silently if key doesn't exist. + + :param key: the key (name) of the cookie to be deleted. + :param path: if the cookie that should be deleted was limited to a + path, the path has to be defined here. + :param domain: if the cookie that should be deleted was limited to a + domain, that domain has to be defined here. + :param secure: If ``True``, the cookie will only be available + via HTTPS. + :param httponly: Disallow JavaScript access to the cookie. + :param samesite: Limit the scope of the cookie to only be + attached to requests that are "same-site". + """ + self.set_cookie( + key, + expires=0, + max_age=0, + path=path, + domain=domain, + secure=secure, + httponly=httponly, + samesite=samesite, + ) + + @property + def is_json(self) -> bool: + """Check if the mimetype indicates JSON data, either + :mimetype:`application/json` or :mimetype:`application/*+json`. + """ + mt = self.mimetype + return mt is not None and ( + mt == "application/json" + or mt.startswith("application/") + and mt.endswith("+json") + ) + + # Common Descriptors + + @property + def mimetype(self) -> t.Optional[str]: + """The mimetype (content type without charset etc.)""" + ct = self.headers.get("content-type") + + if ct: + return ct.split(";")[0].strip() + else: + return None + + @mimetype.setter + def mimetype(self, value: str) -> None: + self.headers["Content-Type"] = get_content_type(value, self.charset) + + @property + def mimetype_params(self) -> t.Dict[str, str]: + """The mimetype parameters as dict. For example if the + content type is ``text/html; charset=utf-8`` the params would be + ``{'charset': 'utf-8'}``. + + .. versionadded:: 0.5 + """ + + def on_update(d: t.Dict[str, str]) -> None: + self.headers["Content-Type"] = dump_options_header(self.mimetype, d) + + d = parse_options_header(self.headers.get("content-type", ""))[1] + return CallbackDict(d, on_update) + + location = header_property[str]( + "Location", + doc="""The Location response-header field is used to redirect + the recipient to a location other than the Request-URI for + completion of the request or identification of a new + resource.""", + ) + age = header_property( + "Age", + None, + parse_age, + dump_age, # type: ignore + doc="""The Age response-header field conveys the sender's + estimate of the amount of time since the response (or its + revalidation) was generated at the origin server. + + Age values are non-negative decimal integers, representing time + in seconds.""", + ) + content_type = header_property[str]( + "Content-Type", + doc="""The Content-Type entity-header field indicates the media + type of the entity-body sent to the recipient or, in the case of + the HEAD method, the media type that would have been sent had + the request been a GET.""", + ) + content_length = header_property( + "Content-Length", + None, + int, + str, + doc="""The Content-Length entity-header field indicates the size + of the entity-body, in decimal number of OCTETs, sent to the + recipient or, in the case of the HEAD method, the size of the + entity-body that would have been sent had the request been a + GET.""", + ) + content_location = header_property[str]( + "Content-Location", + doc="""The Content-Location entity-header field MAY be used to + supply the resource location for the entity enclosed in the + message when that entity is accessible from a location separate + from the requested resource's URI.""", + ) + content_encoding = header_property[str]( + "Content-Encoding", + doc="""The Content-Encoding entity-header field is used as a + modifier to the media-type. When present, its value indicates + what additional content codings have been applied to the + entity-body, and thus what decoding mechanisms must be applied + in order to obtain the media-type referenced by the Content-Type + header field.""", + ) + content_md5 = header_property[str]( + "Content-MD5", + doc="""The Content-MD5 entity-header field, as defined in + RFC 1864, is an MD5 digest of the entity-body for the purpose of + providing an end-to-end message integrity check (MIC) of the + entity-body. (Note: a MIC is good for detecting accidental + modification of the entity-body in transit, but is not proof + against malicious attacks.)""", + ) + date = header_property( + "Date", + None, + parse_date, + http_date, + doc="""The Date general-header field represents the date and + time at which the message was originated, having the same + semantics as orig-date in RFC 822. + + .. versionchanged:: 2.0 + The datetime object is timezone-aware. + """, + ) + expires = header_property( + "Expires", + None, + parse_date, + http_date, + doc="""The Expires entity-header field gives the date/time after + which the response is considered stale. A stale cache entry may + not normally be returned by a cache. + + .. versionchanged:: 2.0 + The datetime object is timezone-aware. + """, + ) + last_modified = header_property( + "Last-Modified", + None, + parse_date, + http_date, + doc="""The Last-Modified entity-header field indicates the date + and time at which the origin server believes the variant was + last modified. + + .. versionchanged:: 2.0 + The datetime object is timezone-aware. + """, + ) + + @property + def retry_after(self) -> t.Optional[datetime]: + """The Retry-After response-header field can be used with a + 503 (Service Unavailable) response to indicate how long the + service is expected to be unavailable to the requesting client. + + Time in seconds until expiration or date. + + .. versionchanged:: 2.0 + The datetime object is timezone-aware. + """ + value = self.headers.get("retry-after") + if value is None: + return None + elif value.isdigit(): + return datetime.now(timezone.utc) + timedelta(seconds=int(value)) + return parse_date(value) + + @retry_after.setter + def retry_after(self, value: t.Optional[t.Union[datetime, int, str]]) -> None: + if value is None: + if "retry-after" in self.headers: + del self.headers["retry-after"] + return + elif isinstance(value, datetime): + value = http_date(value) + else: + value = str(value) + self.headers["Retry-After"] = value + + vary = _set_property( + "Vary", + doc="""The Vary field value indicates the set of request-header + fields that fully determines, while the response is fresh, + whether a cache is permitted to use the response to reply to a + subsequent request without revalidation.""", + ) + content_language = _set_property( + "Content-Language", + doc="""The Content-Language entity-header field describes the + natural language(s) of the intended audience for the enclosed + entity. Note that this might not be equivalent to all the + languages used within the entity-body.""", + ) + allow = _set_property( + "Allow", + doc="""The Allow entity-header field lists the set of methods + supported by the resource identified by the Request-URI. The + purpose of this field is strictly to inform the recipient of + valid methods associated with the resource. An Allow header + field MUST be present in a 405 (Method Not Allowed) + response.""", + ) + + # ETag + + @property + def cache_control(self) -> ResponseCacheControl: + """The Cache-Control general-header field is used to specify + directives that MUST be obeyed by all caching mechanisms along the + request/response chain. + """ + + def on_update(cache_control: ResponseCacheControl) -> None: + if not cache_control and "cache-control" in self.headers: + del self.headers["cache-control"] + elif cache_control: + self.headers["Cache-Control"] = cache_control.to_header() + + return parse_cache_control_header( + self.headers.get("cache-control"), on_update, ResponseCacheControl + ) + + def set_etag(self, etag: str, weak: bool = False) -> None: + """Set the etag, and override the old one if there was one.""" + self.headers["ETag"] = quote_etag(etag, weak) + + def get_etag(self) -> t.Union[t.Tuple[str, bool], t.Tuple[None, None]]: + """Return a tuple in the form ``(etag, is_weak)``. If there is no + ETag the return value is ``(None, None)``. + """ + return unquote_etag(self.headers.get("ETag")) + + accept_ranges = header_property[str]( + "Accept-Ranges", + doc="""The `Accept-Ranges` header. Even though the name would + indicate that multiple values are supported, it must be one + string token only. + + The values ``'bytes'`` and ``'none'`` are common. + + .. versionadded:: 0.7""", + ) + + @property + def content_range(self) -> ContentRange: + """The ``Content-Range`` header as a + :class:`~werkzeug.datastructures.ContentRange` object. Available + even if the header is not set. + + .. versionadded:: 0.7 + """ + + def on_update(rng: ContentRange) -> None: + if not rng: + del self.headers["content-range"] + else: + self.headers["Content-Range"] = rng.to_header() + + rv = parse_content_range_header(self.headers.get("content-range"), on_update) + # always provide a content range object to make the descriptor + # more user friendly. It provides an unset() method that can be + # used to remove the header quickly. + if rv is None: + rv = ContentRange(None, None, None, on_update=on_update) + return rv + + @content_range.setter + def content_range(self, value: t.Optional[t.Union[ContentRange, str]]) -> None: + if not value: + del self.headers["content-range"] + elif isinstance(value, str): + self.headers["Content-Range"] = value + else: + self.headers["Content-Range"] = value.to_header() + + # Authorization + + @property + def www_authenticate(self) -> WWWAuthenticate: + """The ``WWW-Authenticate`` header in a parsed form.""" + + def on_update(www_auth: WWWAuthenticate) -> None: + if not www_auth and "www-authenticate" in self.headers: + del self.headers["www-authenticate"] + elif www_auth: + self.headers["WWW-Authenticate"] = www_auth.to_header() + + header = self.headers.get("www-authenticate") + return parse_www_authenticate_header(header, on_update) + + # CSP + + content_security_policy = header_property( + "Content-Security-Policy", + None, + parse_csp_header, # type: ignore + dump_csp_header, + doc="""The Content-Security-Policy header adds an additional layer of + security to help detect and mitigate certain types of attacks.""", + ) + content_security_policy_report_only = header_property( + "Content-Security-Policy-Report-Only", + None, + parse_csp_header, # type: ignore + dump_csp_header, + doc="""The Content-Security-Policy-Report-Only header adds a csp policy + that is not enforced but is reported thereby helping detect + certain types of attacks.""", + ) + + # CORS + + @property + def access_control_allow_credentials(self) -> bool: + """Whether credentials can be shared by the browser to + JavaScript code. As part of the preflight request it indicates + whether credentials can be used on the cross origin request. + """ + return "Access-Control-Allow-Credentials" in self.headers + + @access_control_allow_credentials.setter + def access_control_allow_credentials(self, value: t.Optional[bool]) -> None: + if value is True: + self.headers["Access-Control-Allow-Credentials"] = "true" + else: + self.headers.pop("Access-Control-Allow-Credentials", None) + + access_control_allow_headers = header_property( + "Access-Control-Allow-Headers", + load_func=parse_set_header, + dump_func=dump_header, + doc="Which headers can be sent with the cross origin request.", + ) + + access_control_allow_methods = header_property( + "Access-Control-Allow-Methods", + load_func=parse_set_header, + dump_func=dump_header, + doc="Which methods can be used for the cross origin request.", + ) + + access_control_allow_origin = header_property[str]( + "Access-Control-Allow-Origin", + doc="The origin or '*' for any origin that may make cross origin requests.", + ) + + access_control_expose_headers = header_property( + "Access-Control-Expose-Headers", + load_func=parse_set_header, + dump_func=dump_header, + doc="Which headers can be shared by the browser to JavaScript code.", + ) + + access_control_max_age = header_property( + "Access-Control-Max-Age", + load_func=int, + dump_func=str, + doc="The maximum age in seconds the access control settings can be cached for.", + ) + + cross_origin_opener_policy = header_property[COOP]( + "Cross-Origin-Opener-Policy", + load_func=lambda value: COOP(value), + dump_func=lambda value: value.value, + default=COOP.UNSAFE_NONE, + doc="""Allows control over sharing of browsing context group with cross-origin + documents. Values must be a member of the :class:`werkzeug.http.COOP` enum.""", + ) + + cross_origin_embedder_policy = header_property[COEP]( + "Cross-Origin-Embedder-Policy", + load_func=lambda value: COEP(value), + dump_func=lambda value: value.value, + default=COEP.UNSAFE_NONE, + doc="""Prevents a document from loading any cross-origin resources that do not + explicitly grant the document permission. Values must be a member of the + :class:`werkzeug.http.COEP` enum.""", + ) diff --git a/venv/lib/python3.9/site-packages/werkzeug/sansio/utils.py b/venv/lib/python3.9/site-packages/werkzeug/sansio/utils.py new file mode 100644 index 0000000..1b4d892 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/sansio/utils.py @@ -0,0 +1,142 @@ +import typing as t + +from .._internal import _encode_idna +from ..exceptions import SecurityError +from ..urls import uri_to_iri +from ..urls import url_quote + + +def host_is_trusted(hostname: str, trusted_list: t.Iterable[str]) -> bool: + """Check if a host matches a list of trusted names. + + :param hostname: The name to check. + :param trusted_list: A list of valid names to match. If a name + starts with a dot it will match all subdomains. + + .. versionadded:: 0.9 + """ + if not hostname: + return False + + if isinstance(trusted_list, str): + trusted_list = [trusted_list] + + def _normalize(hostname: str) -> bytes: + if ":" in hostname: + hostname = hostname.rsplit(":", 1)[0] + + return _encode_idna(hostname) + + try: + hostname_bytes = _normalize(hostname) + except UnicodeError: + return False + + for ref in trusted_list: + if ref.startswith("."): + ref = ref[1:] + suffix_match = True + else: + suffix_match = False + + try: + ref_bytes = _normalize(ref) + except UnicodeError: + return False + + if ref_bytes == hostname_bytes: + return True + + if suffix_match and hostname_bytes.endswith(b"." + ref_bytes): + return True + + return False + + +def get_host( + scheme: str, + host_header: t.Optional[str], + server: t.Optional[t.Tuple[str, t.Optional[int]]] = None, + trusted_hosts: t.Optional[t.Iterable[str]] = None, +) -> str: + """Return the host for the given parameters. + + This first checks the ``host_header``. If it's not present, then + ``server`` is used. The host will only contain the port if it is + different than the standard port for the protocol. + + Optionally, verify that the host is trusted using + :func:`host_is_trusted` and raise a + :exc:`~werkzeug.exceptions.SecurityError` if it is not. + + :param scheme: The protocol the request used, like ``"https"``. + :param host_header: The ``Host`` header value. + :param server: Address of the server. ``(host, port)``, or + ``(path, None)`` for unix sockets. + :param trusted_hosts: A list of trusted host names. + + :return: Host, with port if necessary. + :raise ~werkzeug.exceptions.SecurityError: If the host is not + trusted. + """ + host = "" + + if host_header is not None: + host = host_header + elif server is not None: + host = server[0] + + if server[1] is not None: + host = f"{host}:{server[1]}" + + if scheme in {"http", "ws"} and host.endswith(":80"): + host = host[:-3] + elif scheme in {"https", "wss"} and host.endswith(":443"): + host = host[:-4] + + if trusted_hosts is not None: + if not host_is_trusted(host, trusted_hosts): + raise SecurityError(f"Host {host!r} is not trusted.") + + return host + + +def get_current_url( + scheme: str, + host: str, + root_path: t.Optional[str] = None, + path: t.Optional[str] = None, + query_string: t.Optional[bytes] = None, +) -> str: + """Recreate the URL for a request. If an optional part isn't + provided, it and subsequent parts are not included in the URL. + + The URL is an IRI, not a URI, so it may contain Unicode characters. + Use :func:`~werkzeug.urls.iri_to_uri` to convert it to ASCII. + + :param scheme: The protocol the request used, like ``"https"``. + :param host: The host the request was made to. See :func:`get_host`. + :param root_path: Prefix that the application is mounted under. This + is prepended to ``path``. + :param path: The path part of the URL after ``root_path``. + :param query_string: The portion of the URL after the "?". + """ + url = [scheme, "://", host] + + if root_path is None: + url.append("/") + return uri_to_iri("".join(url)) + + url.append(url_quote(root_path.rstrip("/"))) + url.append("/") + + if path is None: + return uri_to_iri("".join(url)) + + url.append(url_quote(path.lstrip("/"))) + + if query_string: + url.append("?") + url.append(url_quote(query_string, safe=":&%=+$!*'(),")) + + return uri_to_iri("".join(url)) diff --git a/venv/lib/python3.9/site-packages/werkzeug/security.py b/venv/lib/python3.9/site-packages/werkzeug/security.py new file mode 100644 index 0000000..e23040a --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/security.py @@ -0,0 +1,247 @@ +import hashlib +import hmac +import os +import posixpath +import secrets +import typing as t +import warnings + +if t.TYPE_CHECKING: + pass + +SALT_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" +DEFAULT_PBKDF2_ITERATIONS = 260000 + +_os_alt_seps: t.List[str] = list( + sep for sep in [os.path.sep, os.path.altsep] if sep is not None and sep != "/" +) + + +def pbkdf2_hex( + data: t.Union[str, bytes], + salt: t.Union[str, bytes], + iterations: int = DEFAULT_PBKDF2_ITERATIONS, + keylen: t.Optional[int] = None, + hashfunc: t.Optional[t.Union[str, t.Callable]] = None, +) -> str: + """Like :func:`pbkdf2_bin`, but returns a hex-encoded string. + + :param data: the data to derive. + :param salt: the salt for the derivation. + :param iterations: the number of iterations. + :param keylen: the length of the resulting key. If not provided, + the digest size will be used. + :param hashfunc: the hash function to use. This can either be the + string name of a known hash function, or a function + from the hashlib module. Defaults to sha256. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Use :func:`hashlib.pbkdf2_hmac` + instead. + + .. versionadded:: 0.9 + """ + warnings.warn( + "'pbkdf2_hex' is deprecated and will be removed in Werkzeug" + " 2.1. Use 'hashlib.pbkdf2_hmac().hex()' instead.", + DeprecationWarning, + stacklevel=2, + ) + return pbkdf2_bin(data, salt, iterations, keylen, hashfunc).hex() + + +def pbkdf2_bin( + data: t.Union[str, bytes], + salt: t.Union[str, bytes], + iterations: int = DEFAULT_PBKDF2_ITERATIONS, + keylen: t.Optional[int] = None, + hashfunc: t.Optional[t.Union[str, t.Callable]] = None, +) -> bytes: + """Returns a binary digest for the PBKDF2 hash algorithm of `data` + with the given `salt`. It iterates `iterations` times and produces a + key of `keylen` bytes. By default, SHA-256 is used as hash function; + a different hashlib `hashfunc` can be provided. + + :param data: the data to derive. + :param salt: the salt for the derivation. + :param iterations: the number of iterations. + :param keylen: the length of the resulting key. If not provided + the digest size will be used. + :param hashfunc: the hash function to use. This can either be the + string name of a known hash function or a function + from the hashlib module. Defaults to sha256. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Use :func:`hashlib.pbkdf2_hmac` + instead. + + .. versionadded:: 0.9 + """ + warnings.warn( + "'pbkdf2_bin' is deprecated and will be removed in Werkzeug" + " 2.1. Use 'hashlib.pbkdf2_hmac()' instead.", + DeprecationWarning, + stacklevel=2, + ) + + if isinstance(data, str): + data = data.encode("utf8") + + if isinstance(salt, str): + salt = salt.encode("utf8") + + if not hashfunc: + hash_name = "sha256" + elif callable(hashfunc): + hash_name = hashfunc().name + else: + hash_name = hashfunc + + return hashlib.pbkdf2_hmac(hash_name, data, salt, iterations, keylen) + + +def safe_str_cmp(a: str, b: str) -> bool: + """This function compares strings in somewhat constant time. This + requires that the length of at least one string is known in advance. + + Returns `True` if the two strings are equal, or `False` if they are not. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Use + :func:`hmac.compare_digest` instead. + + .. versionadded:: 0.7 + """ + warnings.warn( + "'safe_str_cmp' is deprecated and will be removed in Werkzeug" + " 2.1. Use 'hmac.compare_digest' instead.", + DeprecationWarning, + stacklevel=2, + ) + + if isinstance(a, str): + a = a.encode("utf-8") # type: ignore + + if isinstance(b, str): + b = b.encode("utf-8") # type: ignore + + return hmac.compare_digest(a, b) + + +def gen_salt(length: int) -> str: + """Generate a random string of SALT_CHARS with specified ``length``.""" + if length <= 0: + raise ValueError("Salt length must be positive") + + return "".join(secrets.choice(SALT_CHARS) for _ in range(length)) + + +def _hash_internal(method: str, salt: str, password: str) -> t.Tuple[str, str]: + """Internal password hash helper. Supports plaintext without salt, + unsalted and salted passwords. In case salted passwords are used + hmac is used. + """ + if method == "plain": + return password, method + + salt = salt.encode("utf-8") + password = password.encode("utf-8") + + if method.startswith("pbkdf2:"): + if not salt: + raise ValueError("Salt is required for PBKDF2") + + args = method[7:].split(":") + + if len(args) not in (1, 2): + raise ValueError("Invalid number of arguments for PBKDF2") + + method = args.pop(0) + iterations = int(args[0] or 0) if args else DEFAULT_PBKDF2_ITERATIONS + return ( + hashlib.pbkdf2_hmac(method, password, salt, iterations).hex(), + f"pbkdf2:{method}:{iterations}", + ) + + if salt: + return hmac.new(salt, password, method).hexdigest(), method + + return hashlib.new(method, password).hexdigest(), method + + +def generate_password_hash( + password: str, method: str = "pbkdf2:sha256", salt_length: int = 16 +) -> str: + """Hash a password with the given method and salt with a string of + the given length. The format of the string returned includes the method + that was used so that :func:`check_password_hash` can check the hash. + + The format for the hashed string looks like this:: + + method$salt$hash + + This method can **not** generate unsalted passwords but it is possible + to set param method='plain' in order to enforce plaintext passwords. + If a salt is used, hmac is used internally to salt the password. + + If PBKDF2 is wanted it can be enabled by setting the method to + ``pbkdf2:method:iterations`` where iterations is optional:: + + pbkdf2:sha256:80000$salt$hash + pbkdf2:sha256$salt$hash + + :param password: the password to hash. + :param method: the hash method to use (one that hashlib supports). Can + optionally be in the format ``pbkdf2:method:iterations`` + to enable PBKDF2. + :param salt_length: the length of the salt in letters. + """ + salt = gen_salt(salt_length) if method != "plain" else "" + h, actual_method = _hash_internal(method, salt, password) + return f"{actual_method}${salt}${h}" + + +def check_password_hash(pwhash: str, password: str) -> bool: + """Check a password against a given salted and hashed password value. + In order to support unsalted legacy passwords this method supports + plain text passwords, md5 and sha1 hashes (both salted and unsalted). + + Returns `True` if the password matched, `False` otherwise. + + :param pwhash: a hashed string like returned by + :func:`generate_password_hash`. + :param password: the plaintext password to compare against the hash. + """ + if pwhash.count("$") < 2: + return False + + method, salt, hashval = pwhash.split("$", 2) + return hmac.compare_digest(_hash_internal(method, salt, password)[0], hashval) + + +def safe_join(directory: str, *pathnames: str) -> t.Optional[str]: + """Safely join zero or more untrusted path components to a base + directory to avoid escaping the base directory. + + :param directory: The trusted base directory. + :param pathnames: The untrusted path components relative to the + base directory. + :return: A safe path, otherwise ``None``. + """ + parts = [directory] + + for filename in pathnames: + if filename != "": + filename = posixpath.normpath(filename) + + if ( + any(sep in filename for sep in _os_alt_seps) + or os.path.isabs(filename) + or filename == ".." + or filename.startswith("../") + ): + return None + + parts.append(filename) + + return posixpath.join(*parts) diff --git a/venv/lib/python3.9/site-packages/werkzeug/serving.py b/venv/lib/python3.9/site-packages/werkzeug/serving.py new file mode 100644 index 0000000..1be9949 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/serving.py @@ -0,0 +1,1079 @@ +"""A WSGI and HTTP server for use **during development only**. This +server is convenient to use, but is not designed to be particularly +stable, secure, or efficient. Use a dedicate WSGI server and HTTP +server when deploying to production. + +It provides features like interactive debugging and code reloading. Use +``run_simple`` to start the server. Put this in a ``run.py`` script: + +.. code-block:: python + + from myapp import create_app + from werkzeug import run_simple +""" +import io +import os +import platform +import signal +import socket +import socketserver +import sys +import typing as t +import warnings +from datetime import datetime as dt +from datetime import timedelta +from datetime import timezone +from http.server import BaseHTTPRequestHandler +from http.server import HTTPServer + +from ._internal import _log +from ._internal import _wsgi_encoding_dance +from .exceptions import InternalServerError +from .urls import uri_to_iri +from .urls import url_parse +from .urls import url_unquote + +try: + import ssl +except ImportError: + + class _SslDummy: + def __getattr__(self, name: str) -> t.Any: + raise RuntimeError("SSL support unavailable") + + ssl = _SslDummy() # type: ignore + +_log_add_style = True + +if os.name == "nt": + try: + __import__("colorama") + except ImportError: + _log_add_style = False + +can_fork = hasattr(os, "fork") + +if can_fork: + ForkingMixIn = socketserver.ForkingMixIn +else: + + class ForkingMixIn: # type: ignore + pass + + +try: + af_unix = socket.AF_UNIX +except AttributeError: + af_unix = None # type: ignore + +LISTEN_QUEUE = 128 +can_open_by_fd = not platform.system() == "Windows" and hasattr(socket, "fromfd") + +_TSSLContextArg = t.Optional[ + t.Union["ssl.SSLContext", t.Tuple[str, t.Optional[str]], "te.Literal['adhoc']"] +] + +if t.TYPE_CHECKING: + import typing_extensions as te # noqa: F401 + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + from cryptography.hazmat.primitives.asymmetric.rsa import ( + RSAPrivateKeyWithSerialization, + ) + from cryptography.x509 import Certificate + + +class DechunkedInput(io.RawIOBase): + """An input stream that handles Transfer-Encoding 'chunked'""" + + def __init__(self, rfile: t.BinaryIO) -> None: + self._rfile = rfile + self._done = False + self._len = 0 + + def readable(self) -> bool: + return True + + def read_chunk_len(self) -> int: + try: + line = self._rfile.readline().decode("latin1") + _len = int(line.strip(), 16) + except ValueError: + raise OSError("Invalid chunk header") + if _len < 0: + raise OSError("Negative chunk length not allowed") + return _len + + def readinto(self, buf: bytearray) -> int: # type: ignore + read = 0 + while not self._done and read < len(buf): + if self._len == 0: + # This is the first chunk or we fully consumed the previous + # one. Read the next length of the next chunk + self._len = self.read_chunk_len() + + if self._len == 0: + # Found the final chunk of size 0. The stream is now exhausted, + # but there is still a final newline that should be consumed + self._done = True + + if self._len > 0: + # There is data (left) in this chunk, so append it to the + # buffer. If this operation fully consumes the chunk, this will + # reset self._len to 0. + n = min(len(buf), self._len) + + # If (read + chunk size) becomes more than len(buf), buf will + # grow beyond the original size and read more data than + # required. So only read as much data as can fit in buf. + if read + n > len(buf): + buf[read:] = self._rfile.read(len(buf) - read) + self._len -= len(buf) - read + read = len(buf) + else: + buf[read : read + n] = self._rfile.read(n) + self._len -= n + read += n + + if self._len == 0: + # Skip the terminating newline of a chunk that has been fully + # consumed. This also applies to the 0-sized final chunk + terminator = self._rfile.readline() + if terminator not in (b"\n", b"\r\n", b"\r"): + raise OSError("Missing chunk terminating newline") + + return read + + +class WSGIRequestHandler(BaseHTTPRequestHandler): + """A request handler that implements WSGI dispatching.""" + + server: "BaseWSGIServer" + + @property + def server_version(self) -> str: # type: ignore + from . import __version__ + + return f"Werkzeug/{__version__}" + + def make_environ(self) -> "WSGIEnvironment": + request_url = url_parse(self.path) + + def shutdown_server() -> None: + warnings.warn( + "The 'environ['werkzeug.server.shutdown']' function is" + " deprecated and will be removed in Werkzeug 2.1.", + stacklevel=2, + ) + self.server.shutdown_signal = True + + url_scheme = "http" if self.server.ssl_context is None else "https" + + if not self.client_address: + self.client_address = ("", 0) + elif isinstance(self.client_address, str): + self.client_address = (self.client_address, 0) + + # If there was no scheme but the path started with two slashes, + # the first segment may have been incorrectly parsed as the + # netloc, prepend it to the path again. + if not request_url.scheme and request_url.netloc: + path_info = f"/{request_url.netloc}{request_url.path}" + else: + path_info = request_url.path + + path_info = url_unquote(path_info) + + environ: "WSGIEnvironment" = { + "wsgi.version": (1, 0), + "wsgi.url_scheme": url_scheme, + "wsgi.input": self.rfile, + "wsgi.errors": sys.stderr, + "wsgi.multithread": self.server.multithread, + "wsgi.multiprocess": self.server.multiprocess, + "wsgi.run_once": False, + "werkzeug.server.shutdown": shutdown_server, + "werkzeug.socket": self.connection, + "SERVER_SOFTWARE": self.server_version, + "REQUEST_METHOD": self.command, + "SCRIPT_NAME": "", + "PATH_INFO": _wsgi_encoding_dance(path_info), + "QUERY_STRING": _wsgi_encoding_dance(request_url.query), + # Non-standard, added by mod_wsgi, uWSGI + "REQUEST_URI": _wsgi_encoding_dance(self.path), + # Non-standard, added by gunicorn + "RAW_URI": _wsgi_encoding_dance(self.path), + "REMOTE_ADDR": self.address_string(), + "REMOTE_PORT": self.port_integer(), + "SERVER_NAME": self.server.server_address[0], + "SERVER_PORT": str(self.server.server_address[1]), + "SERVER_PROTOCOL": self.request_version, + } + + for key, value in self.headers.items(): + key = key.upper().replace("-", "_") + value = value.replace("\r\n", "") + if key not in ("CONTENT_TYPE", "CONTENT_LENGTH"): + key = f"HTTP_{key}" + if key in environ: + value = f"{environ[key]},{value}" + environ[key] = value + + if environ.get("HTTP_TRANSFER_ENCODING", "").strip().lower() == "chunked": + environ["wsgi.input_terminated"] = True + environ["wsgi.input"] = DechunkedInput(environ["wsgi.input"]) + + # Per RFC 2616, if the URL is absolute, use that as the host. + # We're using "has a scheme" to indicate an absolute URL. + if request_url.scheme and request_url.netloc: + environ["HTTP_HOST"] = request_url.netloc + + try: + # binary_form=False gives nicer information, but wouldn't be compatible with + # what Nginx or Apache could return. + peer_cert = self.connection.getpeercert(binary_form=True) + if peer_cert is not None: + # Nginx and Apache use PEM format. + environ["SSL_CLIENT_CERT"] = ssl.DER_cert_to_PEM_cert(peer_cert) + except ValueError: + # SSL handshake hasn't finished. + self.server.log("error", "Cannot fetch SSL peer certificate info") + except AttributeError: + # Not using TLS, the socket will not have getpeercert(). + pass + + return environ + + def run_wsgi(self) -> None: + if self.headers.get("Expect", "").lower().strip() == "100-continue": + self.wfile.write(b"HTTP/1.1 100 Continue\r\n\r\n") + + self.environ = environ = self.make_environ() + status_set: t.Optional[str] = None + headers_set: t.Optional[t.List[t.Tuple[str, str]]] = None + status_sent: t.Optional[str] = None + headers_sent: t.Optional[t.List[t.Tuple[str, str]]] = None + + def write(data: bytes) -> None: + nonlocal status_sent, headers_sent + assert status_set is not None, "write() before start_response" + assert headers_set is not None, "write() before start_response" + if status_sent is None: + status_sent = status_set + headers_sent = headers_set + try: + code_str, msg = status_sent.split(None, 1) + except ValueError: + code_str, msg = status_sent, "" + code = int(code_str) + self.send_response(code, msg) + header_keys = set() + for key, value in headers_sent: + self.send_header(key, value) + key = key.lower() + header_keys.add(key) + if not ( + "content-length" in header_keys + or environ["REQUEST_METHOD"] == "HEAD" + or code < 200 + or code in (204, 304) + ): + self.close_connection = True + self.send_header("Connection", "close") + if "server" not in header_keys: + self.send_header("Server", self.version_string()) + if "date" not in header_keys: + self.send_header("Date", self.date_time_string()) + self.end_headers() + + assert isinstance(data, bytes), "applications must write bytes" + self.wfile.write(data) + self.wfile.flush() + + def start_response(status, headers, exc_info=None): # type: ignore + nonlocal status_set, headers_set + if exc_info: + try: + if headers_sent: + raise exc_info[1].with_traceback(exc_info[2]) + finally: + exc_info = None + elif headers_set: + raise AssertionError("Headers already set") + status_set = status + headers_set = headers + return write + + def execute(app: "WSGIApplication") -> None: + application_iter = app(environ, start_response) + try: + for data in application_iter: + write(data) + if not headers_sent: + write(b"") + finally: + if hasattr(application_iter, "close"): + application_iter.close() # type: ignore + + try: + execute(self.server.app) + except (ConnectionError, socket.timeout) as e: + self.connection_dropped(e, environ) + except Exception: + if self.server.passthrough_errors: + raise + from .debug.tbtools import get_current_traceback + + traceback = get_current_traceback(ignore_system_exceptions=True) + try: + # if we haven't yet sent the headers but they are set + # we roll back to be able to set them again. + if status_sent is None: + status_set = None + headers_set = None + execute(InternalServerError()) + except Exception: + pass + self.server.log("error", "Error on request:\n%s", traceback.plaintext) + + def handle(self) -> None: + """Handles a request ignoring dropped connections.""" + try: + BaseHTTPRequestHandler.handle(self) + except (ConnectionError, socket.timeout) as e: + self.connection_dropped(e) + except Exception as e: + if self.server.ssl_context is not None and is_ssl_error(e): + self.log_error("SSL error occurred: %s", e) + else: + raise + if self.server.shutdown_signal: + self.initiate_shutdown() + + def initiate_shutdown(self) -> None: + if is_running_from_reloader(): + # Windows does not provide SIGKILL, go with SIGTERM then. + sig = getattr(signal, "SIGKILL", signal.SIGTERM) + os.kill(os.getpid(), sig) + + self.server._BaseServer__shutdown_request = True # type: ignore + + def connection_dropped( + self, error: BaseException, environ: t.Optional["WSGIEnvironment"] = None + ) -> None: + """Called if the connection was closed by the client. By default + nothing happens. + """ + + def handle_one_request(self) -> None: + """Handle a single HTTP request.""" + self.raw_requestline = self.rfile.readline() + if not self.raw_requestline: + self.close_connection = True + elif self.parse_request(): + self.run_wsgi() + + def send_response(self, code: int, message: t.Optional[str] = None) -> None: + """Send the response header and log the response code.""" + self.log_request(code) + if message is None: + message = self.responses[code][0] if code in self.responses else "" + if self.request_version != "HTTP/0.9": + hdr = f"{self.protocol_version} {code} {message}\r\n" + self.wfile.write(hdr.encode("ascii")) + + def version_string(self) -> str: + return super().version_string().strip() + + def address_string(self) -> str: + if getattr(self, "environ", None): + return self.environ["REMOTE_ADDR"] # type: ignore + + if not self.client_address: + return "" + + return self.client_address[0] + + def port_integer(self) -> int: + return self.client_address[1] + + def log_request( + self, code: t.Union[int, str] = "-", size: t.Union[int, str] = "-" + ) -> None: + try: + path = uri_to_iri(self.path) + msg = f"{self.command} {path} {self.request_version}" + except AttributeError: + # path isn't set if the requestline was bad + msg = self.requestline + + code = str(code) + + if _log_add_style: + if code[0] == "1": # 1xx - Informational + msg = _ansi_style(msg, "bold") + elif code == "200": # 2xx - Success + pass + elif code == "304": # 304 - Resource Not Modified + msg = _ansi_style(msg, "cyan") + elif code[0] == "3": # 3xx - Redirection + msg = _ansi_style(msg, "green") + elif code == "404": # 404 - Resource Not Found + msg = _ansi_style(msg, "yellow") + elif code[0] == "4": # 4xx - Client Error + msg = _ansi_style(msg, "bold", "red") + else: # 5xx, or any other response + msg = _ansi_style(msg, "bold", "magenta") + + self.log("info", '"%s" %s %s', msg, code, size) + + def log_error(self, format: str, *args: t.Any) -> None: + self.log("error", format, *args) + + def log_message(self, format: str, *args: t.Any) -> None: + self.log("info", format, *args) + + def log(self, type: str, message: str, *args: t.Any) -> None: + _log( + type, + f"{self.address_string()} - - [{self.log_date_time_string()}] {message}\n", + *args, + ) + + +def _ansi_style(value: str, *styles: str) -> str: + codes = { + "bold": 1, + "red": 31, + "green": 32, + "yellow": 33, + "magenta": 35, + "cyan": 36, + } + + for style in styles: + value = f"\x1b[{codes[style]}m{value}" + + return f"{value}\x1b[0m" + + +def generate_adhoc_ssl_pair( + cn: t.Optional[str] = None, +) -> t.Tuple["Certificate", "RSAPrivateKeyWithSerialization"]: + try: + from cryptography import x509 + from cryptography.x509.oid import NameOID + from cryptography.hazmat.backends import default_backend + from cryptography.hazmat.primitives import hashes + from cryptography.hazmat.primitives.asymmetric import rsa + except ImportError: + raise TypeError("Using ad-hoc certificates requires the cryptography library.") + + backend = default_backend() + pkey = rsa.generate_private_key( + public_exponent=65537, key_size=2048, backend=backend + ) + + # pretty damn sure that this is not actually accepted by anyone + if cn is None: + cn = "*" + + subject = x509.Name( + [ + x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Dummy Certificate"), + x509.NameAttribute(NameOID.COMMON_NAME, cn), + ] + ) + + backend = default_backend() + cert = ( + x509.CertificateBuilder() + .subject_name(subject) + .issuer_name(subject) + .public_key(pkey.public_key()) + .serial_number(x509.random_serial_number()) + .not_valid_before(dt.now(timezone.utc)) + .not_valid_after(dt.now(timezone.utc) + timedelta(days=365)) + .add_extension(x509.ExtendedKeyUsage([x509.OID_SERVER_AUTH]), critical=False) + .add_extension(x509.SubjectAlternativeName([x509.DNSName("*")]), critical=False) + .sign(pkey, hashes.SHA256(), backend) + ) + return cert, pkey + + +def make_ssl_devcert( + base_path: str, host: t.Optional[str] = None, cn: t.Optional[str] = None +) -> t.Tuple[str, str]: + """Creates an SSL key for development. This should be used instead of + the ``'adhoc'`` key which generates a new cert on each server start. + It accepts a path for where it should store the key and cert and + either a host or CN. If a host is given it will use the CN + ``*.host/CN=host``. + + For more information see :func:`run_simple`. + + .. versionadded:: 0.9 + + :param base_path: the path to the certificate and key. The extension + ``.crt`` is added for the certificate, ``.key`` is + added for the key. + :param host: the name of the host. This can be used as an alternative + for the `cn`. + :param cn: the `CN` to use. + """ + + if host is not None: + cn = f"*.{host}/CN={host}" + cert, pkey = generate_adhoc_ssl_pair(cn=cn) + + from cryptography.hazmat.primitives import serialization + + cert_file = f"{base_path}.crt" + pkey_file = f"{base_path}.key" + + with open(cert_file, "wb") as f: + f.write(cert.public_bytes(serialization.Encoding.PEM)) + with open(pkey_file, "wb") as f: + f.write( + pkey.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=serialization.NoEncryption(), + ) + ) + + return cert_file, pkey_file + + +def generate_adhoc_ssl_context() -> "ssl.SSLContext": + """Generates an adhoc SSL context for the development server.""" + import tempfile + import atexit + + cert, pkey = generate_adhoc_ssl_pair() + + from cryptography.hazmat.primitives import serialization + + cert_handle, cert_file = tempfile.mkstemp() + pkey_handle, pkey_file = tempfile.mkstemp() + atexit.register(os.remove, pkey_file) + atexit.register(os.remove, cert_file) + + os.write(cert_handle, cert.public_bytes(serialization.Encoding.PEM)) + os.write( + pkey_handle, + pkey.private_bytes( + encoding=serialization.Encoding.PEM, + format=serialization.PrivateFormat.TraditionalOpenSSL, + encryption_algorithm=serialization.NoEncryption(), + ), + ) + + os.close(cert_handle) + os.close(pkey_handle) + ctx = load_ssl_context(cert_file, pkey_file) + return ctx + + +def load_ssl_context( + cert_file: str, pkey_file: t.Optional[str] = None, protocol: t.Optional[int] = None +) -> "ssl.SSLContext": + """Loads SSL context from cert/private key files and optional protocol. + Many parameters are directly taken from the API of + :py:class:`ssl.SSLContext`. + + :param cert_file: Path of the certificate to use. + :param pkey_file: Path of the private key to use. If not given, the key + will be obtained from the certificate file. + :param protocol: A ``PROTOCOL`` constant from the :mod:`ssl` module. + Defaults to :data:`ssl.PROTOCOL_TLS_SERVER`. + """ + if protocol is None: + protocol = ssl.PROTOCOL_TLS_SERVER + + ctx = ssl.SSLContext(protocol) + ctx.load_cert_chain(cert_file, pkey_file) + return ctx + + +def is_ssl_error(error: t.Optional[Exception] = None) -> bool: + """Checks if the given error (or the current one) is an SSL error.""" + if error is None: + error = t.cast(Exception, sys.exc_info()[1]) + return isinstance(error, ssl.SSLError) + + +def select_address_family(host: str, port: int) -> socket.AddressFamily: + """Return ``AF_INET4``, ``AF_INET6``, or ``AF_UNIX`` depending on + the host and port.""" + if host.startswith("unix://"): + return socket.AF_UNIX + elif ":" in host and hasattr(socket, "AF_INET6"): + return socket.AF_INET6 + return socket.AF_INET + + +def get_sockaddr( + host: str, port: int, family: socket.AddressFamily +) -> t.Union[t.Tuple[str, int], str]: + """Return a fully qualified socket address that can be passed to + :func:`socket.bind`.""" + if family == af_unix: + return host.split("://", 1)[1] + try: + res = socket.getaddrinfo( + host, port, family, socket.SOCK_STREAM, socket.IPPROTO_TCP + ) + except socket.gaierror: + return host, port + return res[0][4] # type: ignore + + +def get_interface_ip(family: socket.AddressFamily) -> str: + """Get the IP address of an external interface. Used when binding to + 0.0.0.0 or ::1 to show a more useful URL. + + :meta private: + """ + # arbitrary private address + host = "fd31:f903:5ab5:1::1" if family == socket.AF_INET6 else "10.253.155.219" + + with socket.socket(family, socket.SOCK_DGRAM) as s: + try: + s.connect((host, 58162)) + except OSError: + return "::1" if family == socket.AF_INET6 else "127.0.0.1" + + return s.getsockname()[0] # type: ignore + + +class BaseWSGIServer(HTTPServer): + + """Simple single-threaded, single-process WSGI server.""" + + multithread = False + multiprocess = False + request_queue_size = LISTEN_QUEUE + + def __init__( + self, + host: str, + port: int, + app: "WSGIApplication", + handler: t.Optional[t.Type[WSGIRequestHandler]] = None, + passthrough_errors: bool = False, + ssl_context: t.Optional[_TSSLContextArg] = None, + fd: t.Optional[int] = None, + ) -> None: + if handler is None: + handler = WSGIRequestHandler + + self.address_family = select_address_family(host, port) + + if fd is not None: + real_sock = socket.fromfd(fd, self.address_family, socket.SOCK_STREAM) + port = 0 + + server_address = get_sockaddr(host, int(port), self.address_family) + + # remove socket file if it already exists + if self.address_family == af_unix: + server_address = t.cast(str, server_address) + + if os.path.exists(server_address): + os.unlink(server_address) + + super().__init__(server_address, handler) # type: ignore + + self.app = app + self.passthrough_errors = passthrough_errors + self.shutdown_signal = False + self.host = host + self.port = self.socket.getsockname()[1] + + # Patch in the original socket. + if fd is not None: + self.socket.close() + self.socket = real_sock + self.server_address = self.socket.getsockname() + + if ssl_context is not None: + if isinstance(ssl_context, tuple): + ssl_context = load_ssl_context(*ssl_context) + if ssl_context == "adhoc": + ssl_context = generate_adhoc_ssl_context() + + self.socket = ssl_context.wrap_socket(self.socket, server_side=True) + self.ssl_context: t.Optional["ssl.SSLContext"] = ssl_context + else: + self.ssl_context = None + + def log(self, type: str, message: str, *args: t.Any) -> None: + _log(type, message, *args) + + def serve_forever(self, poll_interval: float = 0.5) -> None: + self.shutdown_signal = False + try: + super().serve_forever(poll_interval=poll_interval) + except KeyboardInterrupt: + pass + finally: + self.server_close() + + def handle_error(self, request: t.Any, client_address: t.Tuple[str, int]) -> None: + if self.passthrough_errors: + raise + + return super().handle_error(request, client_address) + + +class ThreadedWSGIServer(socketserver.ThreadingMixIn, BaseWSGIServer): + + """A WSGI server that does threading.""" + + multithread = True + daemon_threads = True + + +class ForkingWSGIServer(ForkingMixIn, BaseWSGIServer): + + """A WSGI server that does forking.""" + + multiprocess = True + + def __init__( + self, + host: str, + port: int, + app: "WSGIApplication", + processes: int = 40, + handler: t.Optional[t.Type[WSGIRequestHandler]] = None, + passthrough_errors: bool = False, + ssl_context: t.Optional[_TSSLContextArg] = None, + fd: t.Optional[int] = None, + ) -> None: + if not can_fork: + raise ValueError("Your platform does not support forking.") + BaseWSGIServer.__init__( + self, host, port, app, handler, passthrough_errors, ssl_context, fd + ) + self.max_children = processes + + +def make_server( + host: str, + port: int, + app: "WSGIApplication", + threaded: bool = False, + processes: int = 1, + request_handler: t.Optional[t.Type[WSGIRequestHandler]] = None, + passthrough_errors: bool = False, + ssl_context: t.Optional[_TSSLContextArg] = None, + fd: t.Optional[int] = None, +) -> BaseWSGIServer: + """Create a new server instance that is either threaded, or forks + or just processes one request after another. + """ + if threaded and processes > 1: + raise ValueError("cannot have a multithreaded and multi process server.") + elif threaded: + return ThreadedWSGIServer( + host, port, app, request_handler, passthrough_errors, ssl_context, fd=fd + ) + elif processes > 1: + return ForkingWSGIServer( + host, + port, + app, + processes, + request_handler, + passthrough_errors, + ssl_context, + fd=fd, + ) + else: + return BaseWSGIServer( + host, port, app, request_handler, passthrough_errors, ssl_context, fd=fd + ) + + +def is_running_from_reloader() -> bool: + """Checks if the application is running from within the Werkzeug + reloader subprocess. + + .. versionadded:: 0.10 + """ + return os.environ.get("WERKZEUG_RUN_MAIN") == "true" + + +def run_simple( + hostname: str, + port: int, + application: "WSGIApplication", + use_reloader: bool = False, + use_debugger: bool = False, + use_evalex: bool = True, + extra_files: t.Optional[t.Iterable[str]] = None, + exclude_patterns: t.Optional[t.Iterable[str]] = None, + reloader_interval: int = 1, + reloader_type: str = "auto", + threaded: bool = False, + processes: int = 1, + request_handler: t.Optional[t.Type[WSGIRequestHandler]] = None, + static_files: t.Optional[t.Dict[str, t.Union[str, t.Tuple[str, str]]]] = None, + passthrough_errors: bool = False, + ssl_context: t.Optional[_TSSLContextArg] = None, +) -> None: + """Start a WSGI application. Optional features include a reloader, + multithreading and fork support. + + This function has a command-line interface too:: + + python -m werkzeug.serving --help + + .. versionchanged:: 2.0 + Added ``exclude_patterns`` parameter. + + .. versionadded:: 0.5 + `static_files` was added to simplify serving of static files as well + as `passthrough_errors`. + + .. versionadded:: 0.6 + support for SSL was added. + + .. versionadded:: 0.8 + Added support for automatically loading a SSL context from certificate + file and private key. + + .. versionadded:: 0.9 + Added command-line interface. + + .. versionadded:: 0.10 + Improved the reloader and added support for changing the backend + through the `reloader_type` parameter. See :ref:`reloader` + for more information. + + .. versionchanged:: 0.15 + Bind to a Unix socket by passing a path that starts with + ``unix://`` as the ``hostname``. + + :param hostname: The host to bind to, for example ``'localhost'``. + If the value is a path that starts with ``unix://`` it will bind + to a Unix socket instead of a TCP socket.. + :param port: The port for the server. eg: ``8080`` + :param application: the WSGI application to execute + :param use_reloader: should the server automatically restart the python + process if modules were changed? + :param use_debugger: should the werkzeug debugging system be used? + :param use_evalex: should the exception evaluation feature be enabled? + :param extra_files: a list of files the reloader should watch + additionally to the modules. For example configuration + files. + :param exclude_patterns: List of :mod:`fnmatch` patterns to ignore + when running the reloader. For example, ignore cache files that + shouldn't reload when updated. + :param reloader_interval: the interval for the reloader in seconds. + :param reloader_type: the type of reloader to use. The default is + auto detection. Valid values are ``'stat'`` and + ``'watchdog'``. See :ref:`reloader` for more + information. + :param threaded: should the process handle each request in a separate + thread? + :param processes: if greater than 1 then handle each request in a new process + up to this maximum number of concurrent processes. + :param request_handler: optional parameter that can be used to replace + the default one. You can use this to replace it + with a different + :class:`~BaseHTTPServer.BaseHTTPRequestHandler` + subclass. + :param static_files: a list or dict of paths for static files. This works + exactly like :class:`SharedDataMiddleware`, it's actually + just wrapping the application in that middleware before + serving. + :param passthrough_errors: set this to `True` to disable the error catching. + This means that the server will die on errors but + it can be useful to hook debuggers in (pdb etc.) + :param ssl_context: an SSL context for the connection. Either an + :class:`ssl.SSLContext`, a tuple in the form + ``(cert_file, pkey_file)``, the string ``'adhoc'`` if + the server should automatically create one, or ``None`` + to disable SSL (which is the default). + """ + if not isinstance(port, int): + raise TypeError("port must be an integer") + if use_debugger: + from .debug import DebuggedApplication + + application = DebuggedApplication(application, use_evalex) + if static_files: + from .middleware.shared_data import SharedDataMiddleware + + application = SharedDataMiddleware(application, static_files) + + def log_startup(sock: socket.socket) -> None: + all_addresses_message = ( + " * Running on all addresses.\n" + " WARNING: This is a development server. Do not use it in" + " a production deployment." + ) + + if sock.family == af_unix: + _log("info", " * Running on %s (Press CTRL+C to quit)", hostname) + else: + if hostname == "0.0.0.0": + _log("warning", all_addresses_message) + display_hostname = get_interface_ip(socket.AF_INET) + elif hostname == "::": + _log("warning", all_addresses_message) + display_hostname = get_interface_ip(socket.AF_INET6) + else: + display_hostname = hostname + + if ":" in display_hostname: + display_hostname = f"[{display_hostname}]" + + _log( + "info", + " * Running on %s://%s:%d/ (Press CTRL+C to quit)", + "http" if ssl_context is None else "https", + display_hostname, + sock.getsockname()[1], + ) + + def inner() -> None: + try: + fd: t.Optional[int] = int(os.environ["WERKZEUG_SERVER_FD"]) + except (LookupError, ValueError): + fd = None + srv = make_server( + hostname, + port, + application, + threaded, + processes, + request_handler, + passthrough_errors, + ssl_context, + fd=fd, + ) + if fd is None: + log_startup(srv.socket) + srv.serve_forever() + + if use_reloader: + # If we're not running already in the subprocess that is the + # reloader we want to open up a socket early to make sure the + # port is actually available. + if not is_running_from_reloader(): + if port == 0 and not can_open_by_fd: + raise ValueError( + "Cannot bind to a random port with enabled " + "reloader if the Python interpreter does " + "not support socket opening by fd." + ) + + # Create and destroy a socket so that any exceptions are + # raised before we spawn a separate Python interpreter and + # lose this ability. + address_family = select_address_family(hostname, port) + server_address = get_sockaddr(hostname, port, address_family) + s = socket.socket(address_family, socket.SOCK_STREAM) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + s.bind(server_address) + s.set_inheritable(True) + + # If we can open the socket by file descriptor, then we can just + # reuse this one and our socket will survive the restarts. + if can_open_by_fd: + os.environ["WERKZEUG_SERVER_FD"] = str(s.fileno()) + s.listen(LISTEN_QUEUE) + log_startup(s) + else: + s.close() + if address_family == af_unix: + server_address = t.cast(str, server_address) + _log("info", "Unlinking %s", server_address) + os.unlink(server_address) + + from ._reloader import run_with_reloader as _rwr + + _rwr( + inner, + extra_files=extra_files, + exclude_patterns=exclude_patterns, + interval=reloader_interval, + reloader_type=reloader_type, + ) + else: + inner() + + +def run_with_reloader(*args: t.Any, **kwargs: t.Any) -> None: + """Run a process with the reloader. This is not a public API, do + not use this function. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. + """ + from ._reloader import run_with_reloader as _rwr + + warnings.warn( + ( + "'run_with_reloader' is a private API, it will no longer be" + " accessible in Werkzeug 2.1. Use 'run_simple' instead." + ), + DeprecationWarning, + stacklevel=2, + ) + _rwr(*args, **kwargs) + + +def main() -> None: + """A simple command-line interface for :py:func:`run_simple`.""" + import argparse + from .utils import import_string + + _log("warning", "This CLI is deprecated and will be removed in version 2.1.") + + parser = argparse.ArgumentParser( + description="Run the given WSGI application with the development server.", + allow_abbrev=False, + ) + parser.add_argument( + "-b", + "--bind", + dest="address", + help="The hostname:port the app should listen on.", + ) + parser.add_argument( + "-d", + "--debug", + action="store_true", + help="Show the interactive debugger for unhandled exceptions.", + ) + parser.add_argument( + "-r", + "--reload", + action="store_true", + help="Reload the process if modules change.", + ) + parser.add_argument( + "application", help="Application to import and serve, in the form module:app." + ) + args = parser.parse_args() + hostname, port = None, None + + if args.address: + hostname, _, port = args.address.partition(":") + + run_simple( + hostname=hostname or "127.0.0.1", + port=int(port or 5000), + application=import_string(args.application), + use_reloader=args.reload, + use_debugger=args.debug, + ) + + +if __name__ == "__main__": + main() diff --git a/venv/lib/python3.9/site-packages/werkzeug/test.py b/venv/lib/python3.9/site-packages/werkzeug/test.py new file mode 100644 index 0000000..9301c02 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/test.py @@ -0,0 +1,1324 @@ +import mimetypes +import sys +import typing as t +import warnings +from collections import defaultdict +from datetime import datetime +from datetime import timedelta +from http.cookiejar import CookieJar +from io import BytesIO +from itertools import chain +from random import random +from tempfile import TemporaryFile +from time import time +from urllib.request import Request as _UrllibRequest + +from ._internal import _get_environ +from ._internal import _make_encode_wrapper +from ._internal import _wsgi_decoding_dance +from ._internal import _wsgi_encoding_dance +from .datastructures import Authorization +from .datastructures import CallbackDict +from .datastructures import CombinedMultiDict +from .datastructures import EnvironHeaders +from .datastructures import FileMultiDict +from .datastructures import Headers +from .datastructures import MultiDict +from .http import dump_cookie +from .http import dump_options_header +from .http import parse_options_header +from .sansio.multipart import Data +from .sansio.multipart import Epilogue +from .sansio.multipart import Field +from .sansio.multipart import File +from .sansio.multipart import MultipartEncoder +from .sansio.multipart import Preamble +from .urls import iri_to_uri +from .urls import url_encode +from .urls import url_fix +from .urls import url_parse +from .urls import url_unparse +from .urls import url_unquote +from .utils import get_content_type +from .wrappers.request import Request +from .wrappers.response import Response +from .wsgi import ClosingIterator +from .wsgi import get_current_url + +if t.TYPE_CHECKING: + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +def stream_encode_multipart( + data: t.Mapping[str, t.Any], + use_tempfile: bool = True, + threshold: int = 1024 * 500, + boundary: t.Optional[str] = None, + charset: str = "utf-8", +) -> t.Tuple[t.BinaryIO, int, str]: + """Encode a dict of values (either strings or file descriptors or + :class:`FileStorage` objects.) into a multipart encoded string stored + in a file descriptor. + """ + if boundary is None: + boundary = f"---------------WerkzeugFormPart_{time()}{random()}" + + stream: t.BinaryIO = BytesIO() + total_length = 0 + on_disk = False + + if use_tempfile: + + def write_binary(s: bytes) -> int: + nonlocal stream, total_length, on_disk + + if on_disk: + return stream.write(s) + else: + length = len(s) + + if length + total_length <= threshold: + stream.write(s) + else: + new_stream = t.cast(t.BinaryIO, TemporaryFile("wb+")) + new_stream.write(stream.getvalue()) # type: ignore + new_stream.write(s) + stream = new_stream + on_disk = True + + total_length += length + return length + + else: + write_binary = stream.write + + encoder = MultipartEncoder(boundary.encode()) + write_binary(encoder.send_event(Preamble(data=b""))) + for key, value in _iter_data(data): + reader = getattr(value, "read", None) + if reader is not None: + filename = getattr(value, "filename", getattr(value, "name", None)) + content_type = getattr(value, "content_type", None) + if content_type is None: + content_type = ( + filename + and mimetypes.guess_type(filename)[0] + or "application/octet-stream" + ) + headers = Headers([("Content-Type", content_type)]) + if filename is None: + write_binary(encoder.send_event(Field(name=key, headers=headers))) + else: + write_binary( + encoder.send_event( + File(name=key, filename=filename, headers=headers) + ) + ) + while True: + chunk = reader(16384) + + if not chunk: + break + + write_binary(encoder.send_event(Data(data=chunk, more_data=True))) + else: + if not isinstance(value, str): + value = str(value) + write_binary(encoder.send_event(Field(name=key, headers=Headers()))) + write_binary( + encoder.send_event(Data(data=value.encode(charset), more_data=False)) + ) + + write_binary(encoder.send_event(Epilogue(data=b""))) + + length = stream.tell() + stream.seek(0) + return stream, length, boundary + + +def encode_multipart( + values: t.Mapping[str, t.Any], + boundary: t.Optional[str] = None, + charset: str = "utf-8", +) -> t.Tuple[str, bytes]: + """Like `stream_encode_multipart` but returns a tuple in the form + (``boundary``, ``data``) where data is bytes. + """ + stream, length, boundary = stream_encode_multipart( + values, use_tempfile=False, boundary=boundary, charset=charset + ) + return boundary, stream.read() + + +class _TestCookieHeaders: + """A headers adapter for cookielib""" + + def __init__(self, headers: t.Union[Headers, t.List[t.Tuple[str, str]]]) -> None: + self.headers = headers + + def getheaders(self, name: str) -> t.Iterable[str]: + headers = [] + name = name.lower() + for k, v in self.headers: + if k.lower() == name: + headers.append(v) + return headers + + def get_all( + self, name: str, default: t.Optional[t.Iterable[str]] = None + ) -> t.Iterable[str]: + headers = self.getheaders(name) + + if not headers: + return default # type: ignore + + return headers + + +class _TestCookieResponse: + """Something that looks like a httplib.HTTPResponse, but is actually just an + adapter for our test responses to make them available for cookielib. + """ + + def __init__(self, headers: t.Union[Headers, t.List[t.Tuple[str, str]]]) -> None: + self.headers = _TestCookieHeaders(headers) + + def info(self) -> _TestCookieHeaders: + return self.headers + + +class _TestCookieJar(CookieJar): + """A cookielib.CookieJar modified to inject and read cookie headers from + and to wsgi environments, and wsgi application responses. + """ + + def inject_wsgi(self, environ: "WSGIEnvironment") -> None: + """Inject the cookies as client headers into the server's wsgi + environment. + """ + cvals = [f"{c.name}={c.value}" for c in self] + + if cvals: + environ["HTTP_COOKIE"] = "; ".join(cvals) + else: + environ.pop("HTTP_COOKIE", None) + + def extract_wsgi( + self, + environ: "WSGIEnvironment", + headers: t.Union[Headers, t.List[t.Tuple[str, str]]], + ) -> None: + """Extract the server's set-cookie headers as cookies into the + cookie jar. + """ + self.extract_cookies( + _TestCookieResponse(headers), # type: ignore + _UrllibRequest(get_current_url(environ)), + ) + + +def _iter_data(data: t.Mapping[str, t.Any]) -> t.Iterator[t.Tuple[str, t.Any]]: + """Iterate over a mapping that might have a list of values, yielding + all key, value pairs. Almost like iter_multi_items but only allows + lists, not tuples, of values so tuples can be used for files. + """ + if isinstance(data, MultiDict): + yield from data.items(multi=True) + else: + for key, value in data.items(): + if isinstance(value, list): + for v in value: + yield key, v + else: + yield key, value + + +_TAnyMultiDict = t.TypeVar("_TAnyMultiDict", bound=MultiDict) + + +class EnvironBuilder: + """This class can be used to conveniently create a WSGI environment + for testing purposes. It can be used to quickly create WSGI environments + or request objects from arbitrary data. + + The signature of this class is also used in some other places as of + Werkzeug 0.5 (:func:`create_environ`, :meth:`Response.from_values`, + :meth:`Client.open`). Because of this most of the functionality is + available through the constructor alone. + + Files and regular form data can be manipulated independently of each + other with the :attr:`form` and :attr:`files` attributes, but are + passed with the same argument to the constructor: `data`. + + `data` can be any of these values: + + - a `str` or `bytes` object: The object is converted into an + :attr:`input_stream`, the :attr:`content_length` is set and you have to + provide a :attr:`content_type`. + - a `dict` or :class:`MultiDict`: The keys have to be strings. The values + have to be either any of the following objects, or a list of any of the + following objects: + + - a :class:`file`-like object: These are converted into + :class:`FileStorage` objects automatically. + - a `tuple`: The :meth:`~FileMultiDict.add_file` method is called + with the key and the unpacked `tuple` items as positional + arguments. + - a `str`: The string is set as form data for the associated key. + - a file-like object: The object content is loaded in memory and then + handled like a regular `str` or a `bytes`. + + :param path: the path of the request. In the WSGI environment this will + end up as `PATH_INFO`. If the `query_string` is not defined + and there is a question mark in the `path` everything after + it is used as query string. + :param base_url: the base URL is a URL that is used to extract the WSGI + URL scheme, host (server name + server port) and the + script root (`SCRIPT_NAME`). + :param query_string: an optional string or dict with URL parameters. + :param method: the HTTP method to use, defaults to `GET`. + :param input_stream: an optional input stream. Do not specify this and + `data`. As soon as an input stream is set you can't + modify :attr:`args` and :attr:`files` unless you + set the :attr:`input_stream` to `None` again. + :param content_type: The content type for the request. As of 0.5 you + don't have to provide this when specifying files + and form data via `data`. + :param content_length: The content length for the request. You don't + have to specify this when providing data via + `data`. + :param errors_stream: an optional error stream that is used for + `wsgi.errors`. Defaults to :data:`stderr`. + :param multithread: controls `wsgi.multithread`. Defaults to `False`. + :param multiprocess: controls `wsgi.multiprocess`. Defaults to `False`. + :param run_once: controls `wsgi.run_once`. Defaults to `False`. + :param headers: an optional list or :class:`Headers` object of headers. + :param data: a string or dict of form data or a file-object. + See explanation above. + :param json: An object to be serialized and assigned to ``data``. + Defaults the content type to ``"application/json"``. + Serialized with the function assigned to :attr:`json_dumps`. + :param environ_base: an optional dict of environment defaults. + :param environ_overrides: an optional dict of environment overrides. + :param charset: the charset used to encode string data. + :param auth: An authorization object to use for the + ``Authorization`` header value. A ``(username, password)`` tuple + is a shortcut for ``Basic`` authorization. + + .. versionchanged:: 2.0 + ``REQUEST_URI`` and ``RAW_URI`` is the full raw URI including + the query string, not only the path. + + .. versionchanged:: 2.0 + The default :attr:`request_class` is ``Request`` instead of + ``BaseRequest``. + + .. versionadded:: 2.0 + Added the ``auth`` parameter. + + .. versionadded:: 0.15 + The ``json`` param and :meth:`json_dumps` method. + + .. versionadded:: 0.15 + The environ has keys ``REQUEST_URI`` and ``RAW_URI`` containing + the path before perecent-decoding. This is not part of the WSGI + PEP, but many WSGI servers include it. + + .. versionchanged:: 0.6 + ``path`` and ``base_url`` can now be unicode strings that are + encoded with :func:`iri_to_uri`. + """ + + #: the server protocol to use. defaults to HTTP/1.1 + server_protocol = "HTTP/1.1" + + #: the wsgi version to use. defaults to (1, 0) + wsgi_version = (1, 0) + + #: The default request class used by :meth:`get_request`. + request_class = Request + + import json + + #: The serialization function used when ``json`` is passed. + json_dumps = staticmethod(json.dumps) + del json + + _args: t.Optional[MultiDict] + _query_string: t.Optional[str] + _input_stream: t.Optional[t.BinaryIO] + _form: t.Optional[MultiDict] + _files: t.Optional[FileMultiDict] + + def __init__( + self, + path: str = "/", + base_url: t.Optional[str] = None, + query_string: t.Optional[t.Union[t.Mapping[str, str], str]] = None, + method: str = "GET", + input_stream: t.Optional[t.BinaryIO] = None, + content_type: t.Optional[str] = None, + content_length: t.Optional[int] = None, + errors_stream: t.Optional[t.TextIO] = None, + multithread: bool = False, + multiprocess: bool = False, + run_once: bool = False, + headers: t.Optional[t.Union[Headers, t.Iterable[t.Tuple[str, str]]]] = None, + data: t.Optional[t.Union[t.BinaryIO, str, bytes, t.Mapping[str, t.Any]]] = None, + environ_base: t.Optional[t.Mapping[str, t.Any]] = None, + environ_overrides: t.Optional[t.Mapping[str, t.Any]] = None, + charset: str = "utf-8", + mimetype: t.Optional[str] = None, + json: t.Optional[t.Mapping[str, t.Any]] = None, + auth: t.Optional[t.Union[Authorization, t.Tuple[str, str]]] = None, + ) -> None: + path_s = _make_encode_wrapper(path) + if query_string is not None and path_s("?") in path: + raise ValueError("Query string is defined in the path and as an argument") + request_uri = url_parse(path) + if query_string is None and path_s("?") in path: + query_string = request_uri.query + self.charset = charset + self.path = iri_to_uri(request_uri.path) + self.request_uri = path + if base_url is not None: + base_url = url_fix(iri_to_uri(base_url, charset), charset) + self.base_url = base_url # type: ignore + if isinstance(query_string, (bytes, str)): + self.query_string = query_string + else: + if query_string is None: + query_string = MultiDict() + elif not isinstance(query_string, MultiDict): + query_string = MultiDict(query_string) + self.args = query_string + self.method = method + if headers is None: + headers = Headers() + elif not isinstance(headers, Headers): + headers = Headers(headers) + self.headers = headers + if content_type is not None: + self.content_type = content_type + if errors_stream is None: + errors_stream = sys.stderr + self.errors_stream = errors_stream + self.multithread = multithread + self.multiprocess = multiprocess + self.run_once = run_once + self.environ_base = environ_base + self.environ_overrides = environ_overrides + self.input_stream = input_stream + self.content_length = content_length + self.closed = False + + if auth is not None: + if isinstance(auth, tuple): + auth = Authorization( + "basic", {"username": auth[0], "password": auth[1]} + ) + + self.headers.set("Authorization", auth.to_header()) + + if json is not None: + if data is not None: + raise TypeError("can't provide both json and data") + + data = self.json_dumps(json) + + if self.content_type is None: + self.content_type = "application/json" + + if data: + if input_stream is not None: + raise TypeError("can't provide input stream and data") + if hasattr(data, "read"): + data = data.read() # type: ignore + if isinstance(data, str): + data = data.encode(self.charset) + if isinstance(data, bytes): + self.input_stream = BytesIO(data) + if self.content_length is None: + self.content_length = len(data) + else: + for key, value in _iter_data(data): # type: ignore + if isinstance(value, (tuple, dict)) or hasattr(value, "read"): + self._add_file_from_data(key, value) + else: + self.form.setlistdefault(key).append(value) + + if mimetype is not None: + self.mimetype = mimetype + + @classmethod + def from_environ( + cls, environ: "WSGIEnvironment", **kwargs: t.Any + ) -> "EnvironBuilder": + """Turn an environ dict back into a builder. Any extra kwargs + override the args extracted from the environ. + + .. versionchanged:: 2.0 + Path and query values are passed through the WSGI decoding + dance to avoid double encoding. + + .. versionadded:: 0.15 + """ + headers = Headers(EnvironHeaders(environ)) + out = { + "path": _wsgi_decoding_dance(environ["PATH_INFO"]), + "base_url": cls._make_base_url( + environ["wsgi.url_scheme"], + headers.pop("Host"), + _wsgi_decoding_dance(environ["SCRIPT_NAME"]), + ), + "query_string": _wsgi_decoding_dance(environ["QUERY_STRING"]), + "method": environ["REQUEST_METHOD"], + "input_stream": environ["wsgi.input"], + "content_type": headers.pop("Content-Type", None), + "content_length": headers.pop("Content-Length", None), + "errors_stream": environ["wsgi.errors"], + "multithread": environ["wsgi.multithread"], + "multiprocess": environ["wsgi.multiprocess"], + "run_once": environ["wsgi.run_once"], + "headers": headers, + } + out.update(kwargs) + return cls(**out) + + def _add_file_from_data( + self, + key: str, + value: t.Union[ + t.BinaryIO, t.Tuple[t.BinaryIO, str], t.Tuple[t.BinaryIO, str, str] + ], + ) -> None: + """Called in the EnvironBuilder to add files from the data dict.""" + if isinstance(value, tuple): + self.files.add_file(key, *value) + else: + self.files.add_file(key, value) + + @staticmethod + def _make_base_url(scheme: str, host: str, script_root: str) -> str: + return url_unparse((scheme, host, script_root, "", "")).rstrip("/") + "/" + + @property + def base_url(self) -> str: + """The base URL is used to extract the URL scheme, host name, + port, and root path. + """ + return self._make_base_url(self.url_scheme, self.host, self.script_root) + + @base_url.setter + def base_url(self, value: t.Optional[str]) -> None: + if value is None: + scheme = "http" + netloc = "localhost" + script_root = "" + else: + scheme, netloc, script_root, qs, anchor = url_parse(value) + if qs or anchor: + raise ValueError("base url must not contain a query string or fragment") + self.script_root = script_root.rstrip("/") + self.host = netloc + self.url_scheme = scheme + + @property + def content_type(self) -> t.Optional[str]: + """The content type for the request. Reflected from and to + the :attr:`headers`. Do not set if you set :attr:`files` or + :attr:`form` for auto detection. + """ + ct = self.headers.get("Content-Type") + if ct is None and not self._input_stream: + if self._files: + return "multipart/form-data" + if self._form: + return "application/x-www-form-urlencoded" + return None + return ct + + @content_type.setter + def content_type(self, value: t.Optional[str]) -> None: + if value is None: + self.headers.pop("Content-Type", None) + else: + self.headers["Content-Type"] = value + + @property + def mimetype(self) -> t.Optional[str]: + """The mimetype (content type without charset etc.) + + .. versionadded:: 0.14 + """ + ct = self.content_type + return ct.split(";")[0].strip() if ct else None + + @mimetype.setter + def mimetype(self, value: str) -> None: + self.content_type = get_content_type(value, self.charset) + + @property + def mimetype_params(self) -> t.Mapping[str, str]: + """The mimetype parameters as dict. For example if the + content type is ``text/html; charset=utf-8`` the params would be + ``{'charset': 'utf-8'}``. + + .. versionadded:: 0.14 + """ + + def on_update(d: t.Mapping[str, str]) -> None: + self.headers["Content-Type"] = dump_options_header(self.mimetype, d) + + d = parse_options_header(self.headers.get("content-type", ""))[1] + return CallbackDict(d, on_update) + + @property + def content_length(self) -> t.Optional[int]: + """The content length as integer. Reflected from and to the + :attr:`headers`. Do not set if you set :attr:`files` or + :attr:`form` for auto detection. + """ + return self.headers.get("Content-Length", type=int) + + @content_length.setter + def content_length(self, value: t.Optional[int]) -> None: + if value is None: + self.headers.pop("Content-Length", None) + else: + self.headers["Content-Length"] = str(value) + + def _get_form(self, name: str, storage: t.Type[_TAnyMultiDict]) -> _TAnyMultiDict: + """Common behavior for getting the :attr:`form` and + :attr:`files` properties. + + :param name: Name of the internal cached attribute. + :param storage: Storage class used for the data. + """ + if self.input_stream is not None: + raise AttributeError("an input stream is defined") + + rv = getattr(self, name) + + if rv is None: + rv = storage() + setattr(self, name, rv) + + return rv # type: ignore + + def _set_form(self, name: str, value: MultiDict) -> None: + """Common behavior for setting the :attr:`form` and + :attr:`files` properties. + + :param name: Name of the internal cached attribute. + :param value: Value to assign to the attribute. + """ + self._input_stream = None + setattr(self, name, value) + + @property + def form(self) -> MultiDict: + """A :class:`MultiDict` of form values.""" + return self._get_form("_form", MultiDict) + + @form.setter + def form(self, value: MultiDict) -> None: + self._set_form("_form", value) + + @property + def files(self) -> FileMultiDict: + """A :class:`FileMultiDict` of uploaded files. Use + :meth:`~FileMultiDict.add_file` to add new files. + """ + return self._get_form("_files", FileMultiDict) + + @files.setter + def files(self, value: FileMultiDict) -> None: + self._set_form("_files", value) + + @property + def input_stream(self) -> t.Optional[t.BinaryIO]: + """An optional input stream. This is mutually exclusive with + setting :attr:`form` and :attr:`files`, setting it will clear + those. Do not provide this if the method is not ``POST`` or + another method that has a body. + """ + return self._input_stream + + @input_stream.setter + def input_stream(self, value: t.Optional[t.BinaryIO]) -> None: + self._input_stream = value + self._form = None + self._files = None + + @property + def query_string(self) -> str: + """The query string. If you set this to a string + :attr:`args` will no longer be available. + """ + if self._query_string is None: + if self._args is not None: + return url_encode(self._args, charset=self.charset) + return "" + return self._query_string + + @query_string.setter + def query_string(self, value: t.Optional[str]) -> None: + self._query_string = value + self._args = None + + @property + def args(self) -> MultiDict: + """The URL arguments as :class:`MultiDict`.""" + if self._query_string is not None: + raise AttributeError("a query string is defined") + if self._args is None: + self._args = MultiDict() + return self._args + + @args.setter + def args(self, value: t.Optional[MultiDict]) -> None: + self._query_string = None + self._args = value + + @property + def server_name(self) -> str: + """The server name (read-only, use :attr:`host` to set)""" + return self.host.split(":", 1)[0] + + @property + def server_port(self) -> int: + """The server port as integer (read-only, use :attr:`host` to set)""" + pieces = self.host.split(":", 1) + if len(pieces) == 2 and pieces[1].isdigit(): + return int(pieces[1]) + if self.url_scheme == "https": + return 443 + return 80 + + def __del__(self) -> None: + try: + self.close() + except Exception: + pass + + def close(self) -> None: + """Closes all files. If you put real :class:`file` objects into the + :attr:`files` dict you can call this method to automatically close + them all in one go. + """ + if self.closed: + return + try: + files = self.files.values() + except AttributeError: + files = () # type: ignore + for f in files: + try: + f.close() + except Exception: + pass + self.closed = True + + def get_environ(self) -> "WSGIEnvironment": + """Return the built environ. + + .. versionchanged:: 0.15 + The content type and length headers are set based on + input stream detection. Previously this only set the WSGI + keys. + """ + input_stream = self.input_stream + content_length = self.content_length + + mimetype = self.mimetype + content_type = self.content_type + + if input_stream is not None: + start_pos = input_stream.tell() + input_stream.seek(0, 2) + end_pos = input_stream.tell() + input_stream.seek(start_pos) + content_length = end_pos - start_pos + elif mimetype == "multipart/form-data": + input_stream, content_length, boundary = stream_encode_multipart( + CombinedMultiDict([self.form, self.files]), charset=self.charset + ) + content_type = f'{mimetype}; boundary="{boundary}"' + elif mimetype == "application/x-www-form-urlencoded": + form_encoded = url_encode(self.form, charset=self.charset).encode("ascii") + content_length = len(form_encoded) + input_stream = BytesIO(form_encoded) + else: + input_stream = BytesIO() + + result: "WSGIEnvironment" = {} + if self.environ_base: + result.update(self.environ_base) + + def _path_encode(x: str) -> str: + return _wsgi_encoding_dance(url_unquote(x, self.charset), self.charset) + + raw_uri = _wsgi_encoding_dance(self.request_uri, self.charset) + result.update( + { + "REQUEST_METHOD": self.method, + "SCRIPT_NAME": _path_encode(self.script_root), + "PATH_INFO": _path_encode(self.path), + "QUERY_STRING": _wsgi_encoding_dance(self.query_string, self.charset), + # Non-standard, added by mod_wsgi, uWSGI + "REQUEST_URI": raw_uri, + # Non-standard, added by gunicorn + "RAW_URI": raw_uri, + "SERVER_NAME": self.server_name, + "SERVER_PORT": str(self.server_port), + "HTTP_HOST": self.host, + "SERVER_PROTOCOL": self.server_protocol, + "wsgi.version": self.wsgi_version, + "wsgi.url_scheme": self.url_scheme, + "wsgi.input": input_stream, + "wsgi.errors": self.errors_stream, + "wsgi.multithread": self.multithread, + "wsgi.multiprocess": self.multiprocess, + "wsgi.run_once": self.run_once, + } + ) + + headers = self.headers.copy() + + if content_type is not None: + result["CONTENT_TYPE"] = content_type + headers.set("Content-Type", content_type) + + if content_length is not None: + result["CONTENT_LENGTH"] = str(content_length) + headers.set("Content-Length", content_length) + + combined_headers = defaultdict(list) + + for key, value in headers.to_wsgi_list(): + combined_headers[f"HTTP_{key.upper().replace('-', '_')}"].append(value) + + for key, values in combined_headers.items(): + result[key] = ", ".join(values) + + if self.environ_overrides: + result.update(self.environ_overrides) + + return result + + def get_request(self, cls: t.Optional[t.Type[Request]] = None) -> Request: + """Returns a request with the data. If the request class is not + specified :attr:`request_class` is used. + + :param cls: The request wrapper to use. + """ + if cls is None: + cls = self.request_class + + return cls(self.get_environ()) + + +class ClientRedirectError(Exception): + """If a redirect loop is detected when using follow_redirects=True with + the :cls:`Client`, then this exception is raised. + """ + + +class Client: + """This class allows you to send requests to a wrapped application. + + The use_cookies parameter indicates whether cookies should be stored and + sent for subsequent requests. This is True by default, but passing False + will disable this behaviour. + + If you want to request some subdomain of your application you may set + `allow_subdomain_redirects` to `True` as if not no external redirects + are allowed. + + .. versionchanged:: 2.0 + ``response_wrapper`` is always a subclass of + :class:``TestResponse``. + + .. versionchanged:: 0.5 + Added the ``use_cookies`` parameter. + """ + + def __init__( + self, + application: "WSGIApplication", + response_wrapper: t.Optional[t.Type["Response"]] = None, + use_cookies: bool = True, + allow_subdomain_redirects: bool = False, + ) -> None: + self.application = application + + if response_wrapper in {None, Response}: + response_wrapper = TestResponse + elif not isinstance(response_wrapper, TestResponse): + response_wrapper = type( + "WrapperTestResponse", + (TestResponse, response_wrapper), # type: ignore + {}, + ) + + self.response_wrapper = t.cast(t.Type["TestResponse"], response_wrapper) + + if use_cookies: + self.cookie_jar: t.Optional[_TestCookieJar] = _TestCookieJar() + else: + self.cookie_jar = None + + self.allow_subdomain_redirects = allow_subdomain_redirects + + def set_cookie( + self, + server_name: str, + key: str, + value: str = "", + max_age: t.Optional[t.Union[timedelta, int]] = None, + expires: t.Optional[t.Union[str, datetime, int, float]] = None, + path: str = "/", + domain: t.Optional[str] = None, + secure: bool = False, + httponly: bool = False, + samesite: t.Optional[str] = None, + charset: str = "utf-8", + ) -> None: + """Sets a cookie in the client's cookie jar. The server name + is required and has to match the one that is also passed to + the open call. + """ + assert self.cookie_jar is not None, "cookies disabled" + header = dump_cookie( + key, + value, + max_age, + expires, + path, + domain, + secure, + httponly, + charset, + samesite=samesite, + ) + environ = create_environ(path, base_url=f"http://{server_name}") + headers = [("Set-Cookie", header)] + self.cookie_jar.extract_wsgi(environ, headers) + + def delete_cookie( + self, + server_name: str, + key: str, + path: str = "/", + domain: t.Optional[str] = None, + secure: bool = False, + httponly: bool = False, + samesite: t.Optional[str] = None, + ) -> None: + """Deletes a cookie in the test client.""" + self.set_cookie( + server_name, + key, + expires=0, + max_age=0, + path=path, + domain=domain, + secure=secure, + httponly=httponly, + samesite=samesite, + ) + + def run_wsgi_app( + self, environ: "WSGIEnvironment", buffered: bool = False + ) -> t.Tuple[t.Iterable[bytes], str, Headers]: + """Runs the wrapped WSGI app with the given environment. + + :meta private: + """ + if self.cookie_jar is not None: + self.cookie_jar.inject_wsgi(environ) + + rv = run_wsgi_app(self.application, environ, buffered=buffered) + + if self.cookie_jar is not None: + self.cookie_jar.extract_wsgi(environ, rv[2]) + + return rv + + def resolve_redirect( + self, response: "TestResponse", buffered: bool = False + ) -> "TestResponse": + """Perform a new request to the location given by the redirect + response to the previous request. + + :meta private: + """ + scheme, netloc, path, qs, anchor = url_parse(response.location) + builder = EnvironBuilder.from_environ(response.request.environ, query_string=qs) + + to_name_parts = netloc.split(":", 1)[0].split(".") + from_name_parts = builder.server_name.split(".") + + if to_name_parts != [""]: + # The new location has a host, use it for the base URL. + builder.url_scheme = scheme + builder.host = netloc + else: + # A local redirect with autocorrect_location_header=False + # doesn't have a host, so use the request's host. + to_name_parts = from_name_parts + + # Explain why a redirect to a different server name won't be followed. + if to_name_parts != from_name_parts: + if to_name_parts[-len(from_name_parts) :] == from_name_parts: + if not self.allow_subdomain_redirects: + raise RuntimeError("Following subdomain redirects is not enabled.") + else: + raise RuntimeError("Following external redirects is not supported.") + + path_parts = path.split("/") + root_parts = builder.script_root.split("/") + + if path_parts[: len(root_parts)] == root_parts: + # Strip the script root from the path. + builder.path = path[len(builder.script_root) :] + else: + # The new location is not under the script root, so use the + # whole path and clear the previous root. + builder.path = path + builder.script_root = "" + + # Only 307 and 308 preserve all of the original request. + if response.status_code not in {307, 308}: + # HEAD is preserved, everything else becomes GET. + if builder.method != "HEAD": + builder.method = "GET" + + # Clear the body and the headers that describe it. + + if builder.input_stream is not None: + builder.input_stream.close() + builder.input_stream = None + + builder.content_type = None + builder.content_length = None + builder.headers.pop("Transfer-Encoding", None) + + return self.open(builder, buffered=buffered) + + def open( + self, + *args: t.Any, + as_tuple: bool = False, + buffered: bool = False, + follow_redirects: bool = False, + **kwargs: t.Any, + ) -> "TestResponse": + """Generate an environ dict from the given arguments, make a + request to the application using it, and return the response. + + :param args: Passed to :class:`EnvironBuilder` to create the + environ for the request. If a single arg is passed, it can + be an existing :class:`EnvironBuilder` or an environ dict. + :param buffered: Convert the iterator returned by the app into + a list. If the iterator has a ``close()`` method, it is + called automatically. + :param follow_redirects: Make additional requests to follow HTTP + redirects until a non-redirect status is returned. + :attr:`TestResponse.history` lists the intermediate + responses. + + .. versionchanged:: 2.0 + ``as_tuple`` is deprecated and will be removed in Werkzeug + 2.1. Use :attr:`TestResponse.request` and + ``request.environ`` instead. + + .. versionchanged:: 2.0 + The request input stream is closed when calling + ``response.close()``. Input streams for redirects are + automatically closed. + + .. versionchanged:: 0.5 + If a dict is provided as file in the dict for the ``data`` + parameter the content type has to be called ``content_type`` + instead of ``mimetype``. This change was made for + consistency with :class:`werkzeug.FileWrapper`. + + .. versionchanged:: 0.5 + Added the ``follow_redirects`` parameter. + """ + request: t.Optional["Request"] = None + + if not kwargs and len(args) == 1: + arg = args[0] + + if isinstance(arg, EnvironBuilder): + request = arg.get_request() + elif isinstance(arg, dict): + request = EnvironBuilder.from_environ(arg).get_request() + elif isinstance(arg, Request): + request = arg + + if request is None: + builder = EnvironBuilder(*args, **kwargs) + + try: + request = builder.get_request() + finally: + builder.close() + + response = self.run_wsgi_app(request.environ, buffered=buffered) + response = self.response_wrapper(*response, request=request) + + redirects = set() + history: t.List["TestResponse"] = [] + + while follow_redirects and response.status_code in { + 301, + 302, + 303, + 305, + 307, + 308, + }: + # Exhaust intermediate response bodies to ensure middleware + # that returns an iterator runs any cleanup code. + if not buffered: + response.make_sequence() + response.close() + + new_redirect_entry = (response.location, response.status_code) + + if new_redirect_entry in redirects: + raise ClientRedirectError( + f"Loop detected: A {response.status_code} redirect" + f" to {response.location} was already made." + ) + + redirects.add(new_redirect_entry) + response.history = tuple(history) + history.append(response) + response = self.resolve_redirect(response, buffered=buffered) + else: + # This is the final request after redirects, or not + # following redirects. + response.history = tuple(history) + # Close the input stream when closing the response, in case + # the input is an open temporary file. + response.call_on_close(request.input_stream.close) + + if as_tuple: + warnings.warn( + "'as_tuple' is deprecated and will be removed in" + " Werkzeug 2.1. Access 'response.request.environ'" + " instead.", + DeprecationWarning, + stacklevel=2, + ) + return request.environ, response # type: ignore + + return response + + def get(self, *args: t.Any, **kw: t.Any) -> "TestResponse": + """Call :meth:`open` with ``method`` set to ``GET``.""" + kw["method"] = "GET" + return self.open(*args, **kw) + + def post(self, *args: t.Any, **kw: t.Any) -> "TestResponse": + """Call :meth:`open` with ``method`` set to ``POST``.""" + kw["method"] = "POST" + return self.open(*args, **kw) + + def put(self, *args: t.Any, **kw: t.Any) -> "TestResponse": + """Call :meth:`open` with ``method`` set to ``PUT``.""" + kw["method"] = "PUT" + return self.open(*args, **kw) + + def delete(self, *args: t.Any, **kw: t.Any) -> "TestResponse": + """Call :meth:`open` with ``method`` set to ``DELETE``.""" + kw["method"] = "DELETE" + return self.open(*args, **kw) + + def patch(self, *args: t.Any, **kw: t.Any) -> "TestResponse": + """Call :meth:`open` with ``method`` set to ``PATCH``.""" + kw["method"] = "PATCH" + return self.open(*args, **kw) + + def options(self, *args: t.Any, **kw: t.Any) -> "TestResponse": + """Call :meth:`open` with ``method`` set to ``OPTIONS``.""" + kw["method"] = "OPTIONS" + return self.open(*args, **kw) + + def head(self, *args: t.Any, **kw: t.Any) -> "TestResponse": + """Call :meth:`open` with ``method`` set to ``HEAD``.""" + kw["method"] = "HEAD" + return self.open(*args, **kw) + + def trace(self, *args: t.Any, **kw: t.Any) -> "TestResponse": + """Call :meth:`open` with ``method`` set to ``TRACE``.""" + kw["method"] = "TRACE" + return self.open(*args, **kw) + + def __repr__(self) -> str: + return f"<{type(self).__name__} {self.application!r}>" + + +def create_environ(*args: t.Any, **kwargs: t.Any) -> "WSGIEnvironment": + """Create a new WSGI environ dict based on the values passed. The first + parameter should be the path of the request which defaults to '/'. The + second one can either be an absolute path (in that case the host is + localhost:80) or a full path to the request with scheme, netloc port and + the path to the script. + + This accepts the same arguments as the :class:`EnvironBuilder` + constructor. + + .. versionchanged:: 0.5 + This function is now a thin wrapper over :class:`EnvironBuilder` which + was added in 0.5. The `headers`, `environ_base`, `environ_overrides` + and `charset` parameters were added. + """ + builder = EnvironBuilder(*args, **kwargs) + + try: + return builder.get_environ() + finally: + builder.close() + + +def run_wsgi_app( + app: "WSGIApplication", environ: "WSGIEnvironment", buffered: bool = False +) -> t.Tuple[t.Iterable[bytes], str, Headers]: + """Return a tuple in the form (app_iter, status, headers) of the + application output. This works best if you pass it an application that + returns an iterator all the time. + + Sometimes applications may use the `write()` callable returned + by the `start_response` function. This tries to resolve such edge + cases automatically. But if you don't get the expected output you + should set `buffered` to `True` which enforces buffering. + + If passed an invalid WSGI application the behavior of this function is + undefined. Never pass non-conforming WSGI applications to this function. + + :param app: the application to execute. + :param buffered: set to `True` to enforce buffering. + :return: tuple in the form ``(app_iter, status, headers)`` + """ + # Copy environ to ensure any mutations by the app (ProxyFix, for + # example) don't affect subsequent requests (such as redirects). + environ = _get_environ(environ).copy() + status: str + response: t.Optional[t.Tuple[str, t.List[t.Tuple[str, str]]]] = None + buffer: t.List[bytes] = [] + + def start_response(status, headers, exc_info=None): # type: ignore + nonlocal response + + if exc_info: + try: + raise exc_info[1].with_traceback(exc_info[2]) + finally: + exc_info = None + + response = (status, headers) + return buffer.append + + app_rv = app(environ, start_response) + close_func = getattr(app_rv, "close", None) + app_iter: t.Iterable[bytes] = iter(app_rv) + + # when buffering we emit the close call early and convert the + # application iterator into a regular list + if buffered: + try: + app_iter = list(app_iter) + finally: + if close_func is not None: + close_func() + + # otherwise we iterate the application iter until we have a response, chain + # the already received data with the already collected data and wrap it in + # a new `ClosingIterator` if we need to restore a `close` callable from the + # original return value. + else: + for item in app_iter: + buffer.append(item) + + if response is not None: + break + + if buffer: + app_iter = chain(buffer, app_iter) + + if close_func is not None and app_iter is not app_rv: + app_iter = ClosingIterator(app_iter, close_func) + + status, headers = response # type: ignore + return app_iter, status, Headers(headers) + + +class TestResponse(Response): + """:class:`~werkzeug.wrappers.Response` subclass that provides extra + information about requests made with the test :class:`Client`. + + Test client requests will always return an instance of this class. + If a custom response class is passed to the client, it is + subclassed along with this to support test information. + + If the test request included large files, or if the application is + serving a file, call :meth:`close` to close any open files and + prevent Python showing a ``ResourceWarning``. + """ + + request: Request + """A request object with the environ used to make the request that + resulted in this response. + """ + + history: t.Tuple["TestResponse", ...] + """A list of intermediate responses. Populated when the test request + is made with ``follow_redirects`` enabled. + """ + + def __init__( + self, + response: t.Iterable[bytes], + status: str, + headers: Headers, + request: Request, + history: t.Tuple["TestResponse"] = (), # type: ignore + **kwargs: t.Any, + ) -> None: + super().__init__(response, status, headers, **kwargs) + self.request = request + self.history = history + self._compat_tuple = response, status, headers + + def __iter__(self) -> t.Iterator: + warnings.warn( + ( + "The test client no longer returns a tuple, it returns" + " a 'TestResponse'. Tuple unpacking is deprecated and" + " will be removed in Werkzeug 2.1. Access the" + " attributes 'data', 'status', and 'headers' instead." + ), + DeprecationWarning, + stacklevel=2, + ) + return iter(self._compat_tuple) + + def __getitem__(self, item: int) -> t.Any: + warnings.warn( + ( + "The test client no longer returns a tuple, it returns" + " a 'TestResponse'. Item indexing is deprecated and" + " will be removed in Werkzeug 2.1. Access the" + " attributes 'data', 'status', and 'headers' instead." + ), + DeprecationWarning, + stacklevel=2, + ) + return self._compat_tuple[item] diff --git a/venv/lib/python3.9/site-packages/werkzeug/testapp.py b/venv/lib/python3.9/site-packages/werkzeug/testapp.py new file mode 100644 index 0000000..981f887 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/testapp.py @@ -0,0 +1,240 @@ +"""A small application that can be used to test a WSGI server and check +it for WSGI compliance. +""" +import base64 +import os +import sys +import typing as t +from html import escape +from textwrap import wrap + +from . import __version__ as _werkzeug_version +from .wrappers.request import Request +from .wrappers.response import Response + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIEnvironment + + +logo = Response( + base64.b64decode( + """ +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 +=""" + ), + mimetype="image/png", +) + + +TEMPLATE = """\ + +WSGI Information + +
    + +

    WSGI Information

    +

    + This page displays all available information about the WSGI server and + the underlying Python interpreter. +

    Python Interpreter

    + + + + + + +
    Python Version + %(python_version)s +
    Platform + %(platform)s [%(os)s] +
    API Version + %(api_version)s +
    Byteorder + %(byteorder)s +
    Werkzeug Version + %(werkzeug_version)s +
    +

    WSGI Environment

    + %(wsgi_env)s
    +

    Installed Eggs

    +

    + The following python packages were installed on the system as + Python eggs: +

      %(python_eggs)s
    +

    System Path

    +

    + The following paths are the current contents of the load path. The + following entries are looked up for Python packages. Note that not + all items in this path are folders. Gray and underlined items are + entries pointing to invalid resources or used by custom import hooks + such as the zip importer. +

    + Items with a bright background were expanded for display from a relative + path. If you encounter such paths in the output you might want to check + your setup as relative paths are usually problematic in multithreaded + environments. +

      %(sys_path)s
    +
    +""" + + +def iter_sys_path() -> t.Iterator[t.Tuple[str, bool, bool]]: + if os.name == "posix": + + def strip(x: str) -> str: + prefix = os.path.expanduser("~") + if x.startswith(prefix): + x = f"~{x[len(prefix) :]}" + return x + + else: + + def strip(x: str) -> str: + return x + + cwd = os.path.abspath(os.getcwd()) + for item in sys.path: + path = os.path.join(cwd, item or os.path.curdir) + yield strip(os.path.normpath(path)), not os.path.isdir(path), path != item + + +def render_testapp(req: Request) -> bytes: + try: + import pkg_resources + except ImportError: + eggs: t.Iterable[t.Any] = () + else: + eggs = sorted( + pkg_resources.working_set, + key=lambda x: x.project_name.lower(), # type: ignore + ) + python_eggs = [] + for egg in eggs: + try: + version = egg.version + except (ValueError, AttributeError): + version = "unknown" + python_eggs.append( + f"
  • {escape(egg.project_name)} [{escape(version)}]" + ) + + wsgi_env = [] + sorted_environ = sorted(req.environ.items(), key=lambda x: repr(x[0]).lower()) + for key, value in sorted_environ: + value = "".join(wrap(escape(repr(value)))) + wsgi_env.append(f"{escape(str(key))}{value}") + + sys_path = [] + for item, virtual, expanded in iter_sys_path(): + class_ = [] + if virtual: + class_.append("virtual") + if expanded: + class_.append("exp") + class_ = f' class="{" ".join(class_)}"' if class_ else "" + sys_path.append(f"{escape(item)}") + + return ( + TEMPLATE + % { + "python_version": "
    ".join(escape(sys.version).splitlines()), + "platform": escape(sys.platform), + "os": escape(os.name), + "api_version": sys.api_version, + "byteorder": sys.byteorder, + "werkzeug_version": _werkzeug_version, + "python_eggs": "\n".join(python_eggs), + "wsgi_env": "\n".join(wsgi_env), + "sys_path": "\n".join(sys_path), + } + ).encode("utf-8") + + +def test_app( + environ: "WSGIEnvironment", start_response: "StartResponse" +) -> t.Iterable[bytes]: + """Simple test application that dumps the environment. You can use + it to check if Werkzeug is working properly: + + .. sourcecode:: pycon + + >>> from werkzeug.serving import run_simple + >>> from werkzeug.testapp import test_app + >>> run_simple('localhost', 3000, test_app) + * Running on http://localhost:3000/ + + The application displays important information from the WSGI environment, + the Python interpreter and the installed libraries. + """ + req = Request(environ, populate_request=False) + if req.args.get("resource") == "logo": + response = logo + else: + response = Response(render_testapp(req), mimetype="text/html") + return response(environ, start_response) + + +if __name__ == "__main__": + from .serving import run_simple + + run_simple("localhost", 5000, test_app, use_reloader=True) diff --git a/venv/lib/python3.9/site-packages/werkzeug/urls.py b/venv/lib/python3.9/site-packages/werkzeug/urls.py new file mode 100644 index 0000000..7566ac2 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/urls.py @@ -0,0 +1,1211 @@ +"""Functions for working with URLs. + +Contains implementations of functions from :mod:`urllib.parse` that +handle bytes and strings. +""" +import codecs +import os +import re +import typing as t +import warnings + +from ._internal import _check_str_tuple +from ._internal import _decode_idna +from ._internal import _encode_idna +from ._internal import _make_encode_wrapper +from ._internal import _to_str + +if t.TYPE_CHECKING: + from . import datastructures as ds + +# A regular expression for what a valid schema looks like +_scheme_re = re.compile(r"^[a-zA-Z0-9+-.]+$") + +# Characters that are safe in any part of an URL. +_always_safe = frozenset( + bytearray( + b"abcdefghijklmnopqrstuvwxyz" + b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" + b"0123456789" + b"-._~" + ) +) + +_hexdigits = "0123456789ABCDEFabcdef" +_hextobyte = { + f"{a}{b}".encode("ascii"): int(f"{a}{b}", 16) + for a in _hexdigits + for b in _hexdigits +} +_bytetohex = [f"%{char:02X}".encode("ascii") for char in range(256)] + + +class _URLTuple(t.NamedTuple): + scheme: str + netloc: str + path: str + query: str + fragment: str + + +class BaseURL(_URLTuple): + """Superclass of :py:class:`URL` and :py:class:`BytesURL`.""" + + __slots__ = () + _at: str + _colon: str + _lbracket: str + _rbracket: str + + def __str__(self) -> str: + return self.to_url() + + def replace(self, **kwargs: t.Any) -> "BaseURL": + """Return an URL with the same values, except for those parameters + given new values by whichever keyword arguments are specified.""" + return self._replace(**kwargs) + + @property + def host(self) -> t.Optional[str]: + """The host part of the URL if available, otherwise `None`. The + host is either the hostname or the IP address mentioned in the + URL. It will not contain the port. + """ + return self._split_host()[0] + + @property + def ascii_host(self) -> t.Optional[str]: + """Works exactly like :attr:`host` but will return a result that + is restricted to ASCII. If it finds a netloc that is not ASCII + it will attempt to idna decode it. This is useful for socket + operations when the URL might include internationalized characters. + """ + rv = self.host + if rv is not None and isinstance(rv, str): + try: + rv = _encode_idna(rv) # type: ignore + except UnicodeError: + rv = rv.encode("ascii", "ignore") # type: ignore + return _to_str(rv, "ascii", "ignore") + + @property + def port(self) -> t.Optional[int]: + """The port in the URL as an integer if it was present, `None` + otherwise. This does not fill in default ports. + """ + try: + rv = int(_to_str(self._split_host()[1])) + if 0 <= rv <= 65535: + return rv + except (ValueError, TypeError): + pass + return None + + @property + def auth(self) -> t.Optional[str]: + """The authentication part in the URL if available, `None` + otherwise. + """ + return self._split_netloc()[0] + + @property + def username(self) -> t.Optional[str]: + """The username if it was part of the URL, `None` otherwise. + This undergoes URL decoding and will always be a string. + """ + rv = self._split_auth()[0] + if rv is not None: + return _url_unquote_legacy(rv) + return None + + @property + def raw_username(self) -> t.Optional[str]: + """The username if it was part of the URL, `None` otherwise. + Unlike :attr:`username` this one is not being decoded. + """ + return self._split_auth()[0] + + @property + def password(self) -> t.Optional[str]: + """The password if it was part of the URL, `None` otherwise. + This undergoes URL decoding and will always be a string. + """ + rv = self._split_auth()[1] + if rv is not None: + return _url_unquote_legacy(rv) + return None + + @property + def raw_password(self) -> t.Optional[str]: + """The password if it was part of the URL, `None` otherwise. + Unlike :attr:`password` this one is not being decoded. + """ + return self._split_auth()[1] + + def decode_query(self, *args: t.Any, **kwargs: t.Any) -> "ds.MultiDict[str, str]": + """Decodes the query part of the URL. Ths is a shortcut for + calling :func:`url_decode` on the query argument. The arguments and + keyword arguments are forwarded to :func:`url_decode` unchanged. + """ + return url_decode(self.query, *args, **kwargs) + + def join(self, *args: t.Any, **kwargs: t.Any) -> "BaseURL": + """Joins this URL with another one. This is just a convenience + function for calling into :meth:`url_join` and then parsing the + return value again. + """ + return url_parse(url_join(self, *args, **kwargs)) + + def to_url(self) -> str: + """Returns a URL string or bytes depending on the type of the + information stored. This is just a convenience function + for calling :meth:`url_unparse` for this URL. + """ + return url_unparse(self) + + def encode_netloc(self) -> str: + """Encodes the netloc part to an ASCII safe URL as bytes.""" + rv = self.ascii_host or "" + if ":" in rv: + rv = f"[{rv}]" + port = self.port + if port is not None: + rv = f"{rv}:{port}" + auth = ":".join( + filter( + None, + [ + url_quote(self.raw_username or "", "utf-8", "strict", "/:%"), + url_quote(self.raw_password or "", "utf-8", "strict", "/:%"), + ], + ) + ) + if auth: + rv = f"{auth}@{rv}" + return rv + + def decode_netloc(self) -> str: + """Decodes the netloc part into a string.""" + rv = _decode_idna(self.host or "") + + if ":" in rv: + rv = f"[{rv}]" + port = self.port + if port is not None: + rv = f"{rv}:{port}" + auth = ":".join( + filter( + None, + [ + _url_unquote_legacy(self.raw_username or "", "/:%@"), + _url_unquote_legacy(self.raw_password or "", "/:%@"), + ], + ) + ) + if auth: + rv = f"{auth}@{rv}" + return rv + + def to_uri_tuple(self) -> "BaseURL": + """Returns a :class:`BytesURL` tuple that holds a URI. This will + encode all the information in the URL properly to ASCII using the + rules a web browser would follow. + + It's usually more interesting to directly call :meth:`iri_to_uri` which + will return a string. + """ + return url_parse(iri_to_uri(self)) + + def to_iri_tuple(self) -> "BaseURL": + """Returns a :class:`URL` tuple that holds a IRI. This will try + to decode as much information as possible in the URL without + losing information similar to how a web browser does it for the + URL bar. + + It's usually more interesting to directly call :meth:`uri_to_iri` which + will return a string. + """ + return url_parse(uri_to_iri(self)) + + def get_file_location( + self, pathformat: t.Optional[str] = None + ) -> t.Tuple[t.Optional[str], t.Optional[str]]: + """Returns a tuple with the location of the file in the form + ``(server, location)``. If the netloc is empty in the URL or + points to localhost, it's represented as ``None``. + + The `pathformat` by default is autodetection but needs to be set + when working with URLs of a specific system. The supported values + are ``'windows'`` when working with Windows or DOS paths and + ``'posix'`` when working with posix paths. + + If the URL does not point to a local file, the server and location + are both represented as ``None``. + + :param pathformat: The expected format of the path component. + Currently ``'windows'`` and ``'posix'`` are + supported. Defaults to ``None`` which is + autodetect. + """ + if self.scheme != "file": + return None, None + + path = url_unquote(self.path) + host = self.netloc or None + + if pathformat is None: + if os.name == "nt": + pathformat = "windows" + else: + pathformat = "posix" + + if pathformat == "windows": + if path[:1] == "/" and path[1:2].isalpha() and path[2:3] in "|:": + path = f"{path[1:2]}:{path[3:]}" + windows_share = path[:3] in ("\\" * 3, "/" * 3) + import ntpath + + path = ntpath.normpath(path) + # Windows shared drives are represented as ``\\host\\directory``. + # That results in a URL like ``file://///host/directory``, and a + # path like ``///host/directory``. We need to special-case this + # because the path contains the hostname. + if windows_share and host is None: + parts = path.lstrip("\\").split("\\", 1) + if len(parts) == 2: + host, path = parts + else: + host = parts[0] + path = "" + elif pathformat == "posix": + import posixpath + + path = posixpath.normpath(path) + else: + raise TypeError(f"Invalid path format {pathformat!r}") + + if host in ("127.0.0.1", "::1", "localhost"): + host = None + + return host, path + + def _split_netloc(self) -> t.Tuple[t.Optional[str], str]: + if self._at in self.netloc: + auth, _, netloc = self.netloc.partition(self._at) + return auth, netloc + return None, self.netloc + + def _split_auth(self) -> t.Tuple[t.Optional[str], t.Optional[str]]: + auth = self._split_netloc()[0] + if not auth: + return None, None + if self._colon not in auth: + return auth, None + + username, _, password = auth.partition(self._colon) + return username, password + + def _split_host(self) -> t.Tuple[t.Optional[str], t.Optional[str]]: + rv = self._split_netloc()[1] + if not rv: + return None, None + + if not rv.startswith(self._lbracket): + if self._colon in rv: + host, _, port = rv.partition(self._colon) + return host, port + return rv, None + + idx = rv.find(self._rbracket) + if idx < 0: + return rv, None + + host = rv[1:idx] + rest = rv[idx + 1 :] + if rest.startswith(self._colon): + return host, rest[1:] + return host, None + + +class URL(BaseURL): + """Represents a parsed URL. This behaves like a regular tuple but + also has some extra attributes that give further insight into the + URL. + """ + + __slots__ = () + _at = "@" + _colon = ":" + _lbracket = "[" + _rbracket = "]" + + def encode(self, charset: str = "utf-8", errors: str = "replace") -> "BytesURL": + """Encodes the URL to a tuple made out of bytes. The charset is + only being used for the path, query and fragment. + """ + return BytesURL( + self.scheme.encode("ascii"), # type: ignore + self.encode_netloc(), + self.path.encode(charset, errors), # type: ignore + self.query.encode(charset, errors), # type: ignore + self.fragment.encode(charset, errors), # type: ignore + ) + + +class BytesURL(BaseURL): + """Represents a parsed URL in bytes.""" + + __slots__ = () + _at = b"@" # type: ignore + _colon = b":" # type: ignore + _lbracket = b"[" # type: ignore + _rbracket = b"]" # type: ignore + + def __str__(self) -> str: + return self.to_url().decode("utf-8", "replace") # type: ignore + + def encode_netloc(self) -> bytes: # type: ignore + """Returns the netloc unchanged as bytes.""" + return self.netloc # type: ignore + + def decode(self, charset: str = "utf-8", errors: str = "replace") -> "URL": + """Decodes the URL to a tuple made out of strings. The charset is + only being used for the path, query and fragment. + """ + return URL( + self.scheme.decode("ascii"), # type: ignore + self.decode_netloc(), + self.path.decode(charset, errors), # type: ignore + self.query.decode(charset, errors), # type: ignore + self.fragment.decode(charset, errors), # type: ignore + ) + + +_unquote_maps: t.Dict[t.FrozenSet[int], t.Dict[bytes, int]] = {frozenset(): _hextobyte} + + +def _unquote_to_bytes( + string: t.Union[str, bytes], unsafe: t.Union[str, bytes] = "" +) -> bytes: + if isinstance(string, str): + string = string.encode("utf-8") + + if isinstance(unsafe, str): + unsafe = unsafe.encode("utf-8") + + unsafe = frozenset(bytearray(unsafe)) + groups = iter(string.split(b"%")) + result = bytearray(next(groups, b"")) + + try: + hex_to_byte = _unquote_maps[unsafe] + except KeyError: + hex_to_byte = _unquote_maps[unsafe] = { + h: b for h, b in _hextobyte.items() if b not in unsafe + } + + for group in groups: + code = group[:2] + + if code in hex_to_byte: + result.append(hex_to_byte[code]) + result.extend(group[2:]) + else: + result.append(37) # % + result.extend(group) + + return bytes(result) + + +def _url_encode_impl( + obj: t.Union[t.Mapping[str, str], t.Iterable[t.Tuple[str, str]]], + charset: str, + sort: bool, + key: t.Optional[t.Callable[[t.Tuple[str, str]], t.Any]], +) -> t.Iterator[str]: + from .datastructures import iter_multi_items + + iterable: t.Iterable[t.Tuple[str, str]] = iter_multi_items(obj) + + if sort: + iterable = sorted(iterable, key=key) + + for key_str, value_str in iterable: + if value_str is None: + continue + + if not isinstance(key_str, bytes): + key_bytes = str(key_str).encode(charset) + else: + key_bytes = key_str + + if not isinstance(value_str, bytes): + value_bytes = str(value_str).encode(charset) + else: + value_bytes = value_str + + yield f"{_fast_url_quote_plus(key_bytes)}={_fast_url_quote_plus(value_bytes)}" + + +def _url_unquote_legacy(value: str, unsafe: str = "") -> str: + try: + return url_unquote(value, charset="utf-8", errors="strict", unsafe=unsafe) + except UnicodeError: + return url_unquote(value, charset="latin1", unsafe=unsafe) + + +def url_parse( + url: str, scheme: t.Optional[str] = None, allow_fragments: bool = True +) -> BaseURL: + """Parses a URL from a string into a :class:`URL` tuple. If the URL + is lacking a scheme it can be provided as second argument. Otherwise, + it is ignored. Optionally fragments can be stripped from the URL + by setting `allow_fragments` to `False`. + + The inverse of this function is :func:`url_unparse`. + + :param url: the URL to parse. + :param scheme: the default schema to use if the URL is schemaless. + :param allow_fragments: if set to `False` a fragment will be removed + from the URL. + """ + s = _make_encode_wrapper(url) + is_text_based = isinstance(url, str) + + if scheme is None: + scheme = s("") + netloc = query = fragment = s("") + i = url.find(s(":")) + if i > 0 and _scheme_re.match(_to_str(url[:i], errors="replace")): + # make sure "iri" is not actually a port number (in which case + # "scheme" is really part of the path) + rest = url[i + 1 :] + if not rest or any(c not in s("0123456789") for c in rest): + # not a port number + scheme, url = url[:i].lower(), rest + + if url[:2] == s("//"): + delim = len(url) + for c in s("/?#"): + wdelim = url.find(c, 2) + if wdelim >= 0: + delim = min(delim, wdelim) + netloc, url = url[2:delim], url[delim:] + if (s("[") in netloc and s("]") not in netloc) or ( + s("]") in netloc and s("[") not in netloc + ): + raise ValueError("Invalid IPv6 URL") + + if allow_fragments and s("#") in url: + url, fragment = url.split(s("#"), 1) + if s("?") in url: + url, query = url.split(s("?"), 1) + + result_type = URL if is_text_based else BytesURL + return result_type(scheme, netloc, url, query, fragment) + + +def _make_fast_url_quote( + charset: str = "utf-8", + errors: str = "strict", + safe: t.Union[str, bytes] = "/:", + unsafe: t.Union[str, bytes] = "", +) -> t.Callable[[bytes], str]: + """Precompile the translation table for a URL encoding function. + + Unlike :func:`url_quote`, the generated function only takes the + string to quote. + + :param charset: The charset to encode the result with. + :param errors: How to handle encoding errors. + :param safe: An optional sequence of safe characters to never encode. + :param unsafe: An optional sequence of unsafe characters to always encode. + """ + if isinstance(safe, str): + safe = safe.encode(charset, errors) + + if isinstance(unsafe, str): + unsafe = unsafe.encode(charset, errors) + + safe = (frozenset(bytearray(safe)) | _always_safe) - frozenset(bytearray(unsafe)) + table = [chr(c) if c in safe else f"%{c:02X}" for c in range(256)] + + def quote(string: bytes) -> str: + return "".join([table[c] for c in string]) + + return quote + + +_fast_url_quote = _make_fast_url_quote() +_fast_quote_plus = _make_fast_url_quote(safe=" ", unsafe="+") + + +def _fast_url_quote_plus(string: bytes) -> str: + return _fast_quote_plus(string).replace(" ", "+") + + +def url_quote( + string: t.Union[str, bytes], + charset: str = "utf-8", + errors: str = "strict", + safe: t.Union[str, bytes] = "/:", + unsafe: t.Union[str, bytes] = "", +) -> str: + """URL encode a single string with a given encoding. + + :param s: the string to quote. + :param charset: the charset to be used. + :param safe: an optional sequence of safe characters. + :param unsafe: an optional sequence of unsafe characters. + + .. versionadded:: 0.9.2 + The `unsafe` parameter was added. + """ + if not isinstance(string, (str, bytes, bytearray)): + string = str(string) + if isinstance(string, str): + string = string.encode(charset, errors) + if isinstance(safe, str): + safe = safe.encode(charset, errors) + if isinstance(unsafe, str): + unsafe = unsafe.encode(charset, errors) + safe = (frozenset(bytearray(safe)) | _always_safe) - frozenset(bytearray(unsafe)) + rv = bytearray() + for char in bytearray(string): + if char in safe: + rv.append(char) + else: + rv.extend(_bytetohex[char]) + return bytes(rv).decode(charset) + + +def url_quote_plus( + string: str, charset: str = "utf-8", errors: str = "strict", safe: str = "" +) -> str: + """URL encode a single string with the given encoding and convert + whitespace to "+". + + :param s: The string to quote. + :param charset: The charset to be used. + :param safe: An optional sequence of safe characters. + """ + return url_quote(string, charset, errors, safe + " ", "+").replace(" ", "+") + + +def url_unparse(components: t.Tuple[str, str, str, str, str]) -> str: + """The reverse operation to :meth:`url_parse`. This accepts arbitrary + as well as :class:`URL` tuples and returns a URL as a string. + + :param components: the parsed URL as tuple which should be converted + into a URL string. + """ + _check_str_tuple(components) + scheme, netloc, path, query, fragment = components + s = _make_encode_wrapper(scheme) + url = s("") + + # We generally treat file:///x and file:/x the same which is also + # what browsers seem to do. This also allows us to ignore a schema + # register for netloc utilization or having to differentiate between + # empty and missing netloc. + if netloc or (scheme and path.startswith(s("/"))): + if path and path[:1] != s("/"): + path = s("/") + path + url = s("//") + (netloc or s("")) + path + elif path: + url += path + if scheme: + url = scheme + s(":") + url + if query: + url = url + s("?") + query + if fragment: + url = url + s("#") + fragment + return url + + +def url_unquote( + s: t.Union[str, bytes], + charset: str = "utf-8", + errors: str = "replace", + unsafe: str = "", +) -> str: + """URL decode a single string with a given encoding. If the charset + is set to `None` no decoding is performed and raw bytes are + returned. + + :param s: the string to unquote. + :param charset: the charset of the query string. If set to `None` + no decoding will take place. + :param errors: the error handling for the charset decoding. + """ + rv = _unquote_to_bytes(s, unsafe) + if charset is None: + return rv + return rv.decode(charset, errors) + + +def url_unquote_plus( + s: t.Union[str, bytes], charset: str = "utf-8", errors: str = "replace" +) -> str: + """URL decode a single string with the given `charset` and decode "+" to + whitespace. + + Per default encoding errors are ignored. If you want a different behavior + you can set `errors` to ``'replace'`` or ``'strict'``. + + :param s: The string to unquote. + :param charset: the charset of the query string. If set to `None` + no decoding will take place. + :param errors: The error handling for the `charset` decoding. + """ + if isinstance(s, str): + s = s.replace("+", " ") + else: + s = s.replace(b"+", b" ") + return url_unquote(s, charset, errors) + + +def url_fix(s: str, charset: str = "utf-8") -> str: + r"""Sometimes you get an URL by a user that just isn't a real URL because + it contains unsafe characters like ' ' and so on. This function can fix + some of the problems in a similar way browsers handle data entered by the + user: + + >>> url_fix('http://de.wikipedia.org/wiki/Elf (Begriffskl\xe4rung)') + 'http://de.wikipedia.org/wiki/Elf%20(Begriffskl%C3%A4rung)' + + :param s: the string with the URL to fix. + :param charset: The target charset for the URL if the url was given + as a string. + """ + # First step is to switch to text processing and to convert + # backslashes (which are invalid in URLs anyways) to slashes. This is + # consistent with what Chrome does. + s = _to_str(s, charset, "replace").replace("\\", "/") + + # For the specific case that we look like a malformed windows URL + # we want to fix this up manually: + if s.startswith("file://") and s[7:8].isalpha() and s[8:10] in (":/", "|/"): + s = f"file:///{s[7:]}" + + url = url_parse(s) + path = url_quote(url.path, charset, safe="/%+$!*'(),") + qs = url_quote_plus(url.query, charset, safe=":&%=+$!*'(),") + anchor = url_quote_plus(url.fragment, charset, safe=":&%=+$!*'(),") + return url_unparse((url.scheme, url.encode_netloc(), path, qs, anchor)) + + +# not-unreserved characters remain quoted when unquoting to IRI +_to_iri_unsafe = "".join([chr(c) for c in range(128) if c not in _always_safe]) + + +def _codec_error_url_quote(e: UnicodeError) -> t.Tuple[str, int]: + """Used in :func:`uri_to_iri` after unquoting to re-quote any + invalid bytes. + """ + # the docs state that UnicodeError does have these attributes, + # but mypy isn't picking them up + out = _fast_url_quote(e.object[e.start : e.end]) # type: ignore + return out, e.end # type: ignore + + +codecs.register_error("werkzeug.url_quote", _codec_error_url_quote) + + +def uri_to_iri( + uri: t.Union[str, t.Tuple[str, str, str, str, str]], + charset: str = "utf-8", + errors: str = "werkzeug.url_quote", +) -> str: + """Convert a URI to an IRI. All valid UTF-8 characters are unquoted, + leaving all reserved and invalid characters quoted. If the URL has + a domain, it is decoded from Punycode. + + >>> uri_to_iri("http://xn--n3h.net/p%C3%A5th?q=%C3%A8ry%DF") + 'http://\\u2603.net/p\\xe5th?q=\\xe8ry%DF' + + :param uri: The URI to convert. + :param charset: The encoding to encode unquoted bytes with. + :param errors: Error handler to use during ``bytes.encode``. By + default, invalid bytes are left quoted. + + .. versionchanged:: 0.15 + All reserved and invalid characters remain quoted. Previously, + only some reserved characters were preserved, and invalid bytes + were replaced instead of left quoted. + + .. versionadded:: 0.6 + """ + if isinstance(uri, tuple): + uri = url_unparse(uri) + + uri = url_parse(_to_str(uri, charset)) + path = url_unquote(uri.path, charset, errors, _to_iri_unsafe) + query = url_unquote(uri.query, charset, errors, _to_iri_unsafe) + fragment = url_unquote(uri.fragment, charset, errors, _to_iri_unsafe) + return url_unparse((uri.scheme, uri.decode_netloc(), path, query, fragment)) + + +# reserved characters remain unquoted when quoting to URI +_to_uri_safe = ":/?#[]@!$&'()*+,;=%" + + +def iri_to_uri( + iri: t.Union[str, t.Tuple[str, str, str, str, str]], + charset: str = "utf-8", + errors: str = "strict", + safe_conversion: bool = False, +) -> str: + """Convert an IRI to a URI. All non-ASCII and unsafe characters are + quoted. If the URL has a domain, it is encoded to Punycode. + + >>> iri_to_uri('http://\\u2603.net/p\\xe5th?q=\\xe8ry%DF') + 'http://xn--n3h.net/p%C3%A5th?q=%C3%A8ry%DF' + + :param iri: The IRI to convert. + :param charset: The encoding of the IRI. + :param errors: Error handler to use during ``bytes.encode``. + :param safe_conversion: Return the URL unchanged if it only contains + ASCII characters and no whitespace. See the explanation below. + + There is a general problem with IRI conversion with some protocols + that are in violation of the URI specification. Consider the + following two IRIs:: + + magnet:?xt=uri:whatever + itms-services://?action=download-manifest + + After parsing, we don't know if the scheme requires the ``//``, + which is dropped if empty, but conveys different meanings in the + final URL if it's present or not. In this case, you can use + ``safe_conversion``, which will return the URL unchanged if it only + contains ASCII characters and no whitespace. This can result in a + URI with unquoted characters if it was not already quoted correctly, + but preserves the URL's semantics. Werkzeug uses this for the + ``Location`` header for redirects. + + .. versionchanged:: 0.15 + All reserved characters remain unquoted. Previously, only some + reserved characters were left unquoted. + + .. versionchanged:: 0.9.6 + The ``safe_conversion`` parameter was added. + + .. versionadded:: 0.6 + """ + if isinstance(iri, tuple): + iri = url_unparse(iri) + + if safe_conversion: + # If we're not sure if it's safe to convert the URL, and it only + # contains ASCII characters, return it unconverted. + try: + native_iri = _to_str(iri) + ascii_iri = native_iri.encode("ascii") + + # Only return if it doesn't have whitespace. (Why?) + if len(ascii_iri.split()) == 1: + return native_iri + except UnicodeError: + pass + + iri = url_parse(_to_str(iri, charset, errors)) + path = url_quote(iri.path, charset, errors, _to_uri_safe) + query = url_quote(iri.query, charset, errors, _to_uri_safe) + fragment = url_quote(iri.fragment, charset, errors, _to_uri_safe) + return url_unparse((iri.scheme, iri.encode_netloc(), path, query, fragment)) + + +def url_decode( + s: t.AnyStr, + charset: str = "utf-8", + decode_keys: None = None, + include_empty: bool = True, + errors: str = "replace", + separator: str = "&", + cls: t.Optional[t.Type["ds.MultiDict"]] = None, +) -> "ds.MultiDict[str, str]": + """Parse a query string and return it as a :class:`MultiDict`. + + :param s: The query string to parse. + :param charset: Decode bytes to string with this charset. If not + given, bytes are returned as-is. + :param include_empty: Include keys with empty values in the dict. + :param errors: Error handling behavior when decoding bytes. + :param separator: Separator character between pairs. + :param cls: Container to hold result instead of :class:`MultiDict`. + + .. versionchanged:: 2.0 + The ``decode_keys`` parameter is deprecated and will be removed + in Werkzeug 2.1. + + .. versionchanged:: 0.5 + In previous versions ";" and "&" could be used for url decoding. + Now only "&" is supported. If you want to use ";", a different + ``separator`` can be provided. + + .. versionchanged:: 0.5 + The ``cls`` parameter was added. + """ + if decode_keys is not None: + warnings.warn( + "'decode_keys' is deprecated and will be removed in Werkzeug 2.1.", + DeprecationWarning, + stacklevel=2, + ) + if cls is None: + from .datastructures import MultiDict # noqa: F811 + + cls = MultiDict + if isinstance(s, str) and not isinstance(separator, str): + separator = separator.decode(charset or "ascii") + elif isinstance(s, bytes) and not isinstance(separator, bytes): + separator = separator.encode(charset or "ascii") # type: ignore + return cls( + _url_decode_impl( + s.split(separator), charset, include_empty, errors # type: ignore + ) + ) + + +def url_decode_stream( + stream: t.BinaryIO, + charset: str = "utf-8", + decode_keys: None = None, + include_empty: bool = True, + errors: str = "replace", + separator: bytes = b"&", + cls: t.Optional[t.Type["ds.MultiDict"]] = None, + limit: t.Optional[int] = None, + return_iterator: bool = False, +) -> "ds.MultiDict[str, str]": + """Works like :func:`url_decode` but decodes a stream. The behavior + of stream and limit follows functions like + :func:`~werkzeug.wsgi.make_line_iter`. The generator of pairs is + directly fed to the `cls` so you can consume the data while it's + parsed. + + :param stream: a stream with the encoded querystring + :param charset: the charset of the query string. If set to `None` + no decoding will take place. + :param include_empty: Set to `False` if you don't want empty values to + appear in the dict. + :param errors: the decoding error behavior. + :param separator: the pair separator to be used, defaults to ``&`` + :param cls: an optional dict class to use. If this is not specified + or `None` the default :class:`MultiDict` is used. + :param limit: the content length of the URL data. Not necessary if + a limited stream is provided. + + .. versionchanged:: 2.0 + The ``decode_keys`` and ``return_iterator`` parameters are + deprecated and will be removed in Werkzeug 2.1. + + .. versionadded:: 0.8 + """ + from .wsgi import make_chunk_iter + + if decode_keys is not None: + warnings.warn( + "'decode_keys' is deprecated and will be removed in Werkzeug 2.1.", + DeprecationWarning, + stacklevel=2, + ) + + pair_iter = make_chunk_iter(stream, separator, limit) + decoder = _url_decode_impl(pair_iter, charset, include_empty, errors) + + if return_iterator: + warnings.warn( + "'return_iterator' is deprecated and will be removed in Werkzeug 2.1.", + DeprecationWarning, + stacklevel=2, + ) + return decoder # type: ignore + + if cls is None: + from .datastructures import MultiDict # noqa: F811 + + cls = MultiDict + + return cls(decoder) + + +def _url_decode_impl( + pair_iter: t.Iterable[t.AnyStr], charset: str, include_empty: bool, errors: str +) -> t.Iterator[t.Tuple[str, str]]: + for pair in pair_iter: + if not pair: + continue + s = _make_encode_wrapper(pair) + equal = s("=") + if equal in pair: + key, value = pair.split(equal, 1) + else: + if not include_empty: + continue + key = pair + value = s("") + yield ( + url_unquote_plus(key, charset, errors), + url_unquote_plus(value, charset, errors), + ) + + +def url_encode( + obj: t.Union[t.Mapping[str, str], t.Iterable[t.Tuple[str, str]]], + charset: str = "utf-8", + encode_keys: None = None, + sort: bool = False, + key: t.Optional[t.Callable[[t.Tuple[str, str]], t.Any]] = None, + separator: str = "&", +) -> str: + """URL encode a dict/`MultiDict`. If a value is `None` it will not appear + in the result string. Per default only values are encoded into the target + charset strings. + + :param obj: the object to encode into a query string. + :param charset: the charset of the query string. + :param sort: set to `True` if you want parameters to be sorted by `key`. + :param separator: the separator to be used for the pairs. + :param key: an optional function to be used for sorting. For more details + check out the :func:`sorted` documentation. + + .. versionchanged:: 2.0 + The ``encode_keys`` parameter is deprecated and will be removed + in Werkzeug 2.1. + + .. versionchanged:: 0.5 + Added the ``sort``, ``key``, and ``separator`` parameters. + """ + if encode_keys is not None: + warnings.warn( + "'encode_keys' is deprecated and will be removed in Werkzeug 2.1.", + DeprecationWarning, + stacklevel=2, + ) + separator = _to_str(separator, "ascii") + return separator.join(_url_encode_impl(obj, charset, sort, key)) + + +def url_encode_stream( + obj: t.Union[t.Mapping[str, str], t.Iterable[t.Tuple[str, str]]], + stream: t.Optional[t.TextIO] = None, + charset: str = "utf-8", + encode_keys: None = None, + sort: bool = False, + key: t.Optional[t.Callable[[t.Tuple[str, str]], t.Any]] = None, + separator: str = "&", +) -> None: + """Like :meth:`url_encode` but writes the results to a stream + object. If the stream is `None` a generator over all encoded + pairs is returned. + + :param obj: the object to encode into a query string. + :param stream: a stream to write the encoded object into or `None` if + an iterator over the encoded pairs should be returned. In + that case the separator argument is ignored. + :param charset: the charset of the query string. + :param sort: set to `True` if you want parameters to be sorted by `key`. + :param separator: the separator to be used for the pairs. + :param key: an optional function to be used for sorting. For more details + check out the :func:`sorted` documentation. + + .. versionchanged:: 2.0 + The ``encode_keys`` parameter is deprecated and will be removed + in Werkzeug 2.1. + + .. versionadded:: 0.8 + """ + if encode_keys is not None: + warnings.warn( + "'encode_keys' is deprecated and will be removed in Werkzeug 2.1.", + DeprecationWarning, + stacklevel=2, + ) + separator = _to_str(separator, "ascii") + gen = _url_encode_impl(obj, charset, sort, key) + if stream is None: + return gen # type: ignore + for idx, chunk in enumerate(gen): + if idx: + stream.write(separator) + stream.write(chunk) + return None + + +def url_join( + base: t.Union[str, t.Tuple[str, str, str, str, str]], + url: t.Union[str, t.Tuple[str, str, str, str, str]], + allow_fragments: bool = True, +) -> str: + """Join a base URL and a possibly relative URL to form an absolute + interpretation of the latter. + + :param base: the base URL for the join operation. + :param url: the URL to join. + :param allow_fragments: indicates whether fragments should be allowed. + """ + if isinstance(base, tuple): + base = url_unparse(base) + if isinstance(url, tuple): + url = url_unparse(url) + + _check_str_tuple((base, url)) + s = _make_encode_wrapper(base) + + if not base: + return url + if not url: + return base + + bscheme, bnetloc, bpath, bquery, bfragment = url_parse( + base, allow_fragments=allow_fragments + ) + scheme, netloc, path, query, fragment = url_parse(url, bscheme, allow_fragments) + if scheme != bscheme: + return url + if netloc: + return url_unparse((scheme, netloc, path, query, fragment)) + netloc = bnetloc + + if path[:1] == s("/"): + segments = path.split(s("/")) + elif not path: + segments = bpath.split(s("/")) + if not query: + query = bquery + else: + segments = bpath.split(s("/"))[:-1] + path.split(s("/")) + + # If the rightmost part is "./" we want to keep the slash but + # remove the dot. + if segments[-1] == s("."): + segments[-1] = s("") + + # Resolve ".." and "." + segments = [segment for segment in segments if segment != s(".")] + while True: + i = 1 + n = len(segments) - 1 + while i < n: + if segments[i] == s("..") and segments[i - 1] not in (s(""), s("..")): + del segments[i - 1 : i + 1] + break + i += 1 + else: + break + + # Remove trailing ".." if the URL is absolute + unwanted_marker = [s(""), s("..")] + while segments[:2] == unwanted_marker: + del segments[1] + + path = s("/").join(segments) + return url_unparse((scheme, netloc, path, query, fragment)) + + +class Href: + """Implements a callable that constructs URLs with the given base. The + function can be called with any number of positional and keyword + arguments which than are used to assemble the URL. Works with URLs + and posix paths. + + Positional arguments are appended as individual segments to + the path of the URL: + + >>> href = Href('/foo') + >>> href('bar', 23) + '/foo/bar/23' + >>> href('foo', bar=23) + '/foo/foo?bar=23' + + If any of the arguments (positional or keyword) evaluates to `None` it + will be skipped. If no keyword arguments are given the last argument + can be a :class:`dict` or :class:`MultiDict` (or any other dict subclass), + otherwise the keyword arguments are used for the query parameters, cutting + off the first trailing underscore of the parameter name: + + >>> href(is_=42) + '/foo?is=42' + >>> href({'foo': 'bar'}) + '/foo?foo=bar' + + Combining of both methods is not allowed: + + >>> href({'foo': 'bar'}, bar=42) + Traceback (most recent call last): + ... + TypeError: keyword arguments and query-dicts can't be combined + + Accessing attributes on the href object creates a new href object with + the attribute name as prefix: + + >>> bar_href = href.bar + >>> bar_href("blub") + '/foo/bar/blub' + + If `sort` is set to `True` the items are sorted by `key` or the default + sorting algorithm: + + >>> href = Href("/", sort=True) + >>> href(a=1, b=2, c=3) + '/?a=1&b=2&c=3' + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Use :mod:`werkzeug.routing` + instead. + + .. versionadded:: 0.5 + `sort` and `key` were added. + """ + + def __init__( # type: ignore + self, base="./", charset="utf-8", sort=False, key=None + ): + warnings.warn( + "'Href' is deprecated and will be removed in Werkzeug 2.1." + " Use 'werkzeug.routing' instead.", + DeprecationWarning, + stacklevel=2, + ) + + if not base: + base = "./" + self.base = base + self.charset = charset + self.sort = sort + self.key = key + + def __getattr__(self, name): # type: ignore + if name[:2] == "__": + raise AttributeError(name) + base = self.base + if base[-1:] != "/": + base += "/" + return Href(url_join(base, name), self.charset, self.sort, self.key) + + def __call__(self, *path, **query): # type: ignore + if path and isinstance(path[-1], dict): + if query: + raise TypeError("keyword arguments and query-dicts can't be combined") + query, path = path[-1], path[:-1] + elif query: + query = {k[:-1] if k.endswith("_") else k: v for k, v in query.items()} + path = "/".join( + [ + _to_str(url_quote(x, self.charset), "ascii") + for x in path + if x is not None + ] + ).lstrip("/") + rv = self.base + if path: + if not rv.endswith("/"): + rv += "/" + rv = url_join(rv, f"./{path}") + if query: + rv += "?" + _to_str( + url_encode(query, self.charset, sort=self.sort, key=self.key), "ascii" + ) + return rv diff --git a/venv/lib/python3.9/site-packages/werkzeug/user_agent.py b/venv/lib/python3.9/site-packages/werkzeug/user_agent.py new file mode 100644 index 0000000..66ffcbe --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/user_agent.py @@ -0,0 +1,47 @@ +import typing as t + + +class UserAgent: + """Represents a parsed user agent header value. + + The default implementation does no parsing, only the :attr:`string` + attribute is set. A subclass may parse the string to set the + common attributes or expose other information. Set + :attr:`werkzeug.wrappers.Request.user_agent_class` to use a + subclass. + + :param string: The header value to parse. + + .. versionadded:: 2.0 + This replaces the previous ``useragents`` module, but does not + provide a built-in parser. + """ + + platform: t.Optional[str] = None + """The OS name, if it could be parsed from the string.""" + + browser: t.Optional[str] = None + """The browser name, if it could be parsed from the string.""" + + version: t.Optional[str] = None + """The browser version, if it could be parsed from the string.""" + + language: t.Optional[str] = None + """The browser language, if it could be parsed from the string.""" + + def __init__(self, string: str) -> None: + self.string: str = string + """The original header value.""" + + def __repr__(self) -> str: + return f"<{type(self).__name__} {self.browser}/{self.version}>" + + def __str__(self) -> str: + return self.string + + def __bool__(self) -> bool: + return bool(self.browser) + + def to_header(self) -> str: + """Convert to a header value.""" + return self.string diff --git a/venv/lib/python3.9/site-packages/werkzeug/useragents.py b/venv/lib/python3.9/site-packages/werkzeug/useragents.py new file mode 100644 index 0000000..4deed8f --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/useragents.py @@ -0,0 +1,215 @@ +import re +import typing as t +import warnings + +from .user_agent import UserAgent as _BaseUserAgent + +if t.TYPE_CHECKING: + from _typeshed.wsgi import WSGIEnvironment + + +class _UserAgentParser: + platform_rules: t.ClassVar[t.Iterable[t.Tuple[str, str]]] = ( + (" cros ", "chromeos"), + ("iphone|ios", "iphone"), + ("ipad", "ipad"), + (r"darwin\b|mac\b|os\s*x", "macos"), + ("win", "windows"), + (r"android", "android"), + ("netbsd", "netbsd"), + ("openbsd", "openbsd"), + ("freebsd", "freebsd"), + ("dragonfly", "dragonflybsd"), + ("(sun|i86)os", "solaris"), + (r"x11\b|lin(\b|ux)?", "linux"), + (r"nintendo\s+wii", "wii"), + ("irix", "irix"), + ("hp-?ux", "hpux"), + ("aix", "aix"), + ("sco|unix_sv", "sco"), + ("bsd", "bsd"), + ("amiga", "amiga"), + ("blackberry|playbook", "blackberry"), + ("symbian", "symbian"), + ) + browser_rules: t.ClassVar[t.Iterable[t.Tuple[str, str]]] = ( + ("googlebot", "google"), + ("msnbot", "msn"), + ("yahoo", "yahoo"), + ("ask jeeves", "ask"), + (r"aol|america\s+online\s+browser", "aol"), + (r"opera|opr", "opera"), + ("edge|edg", "edge"), + ("chrome|crios", "chrome"), + ("seamonkey", "seamonkey"), + ("firefox|firebird|phoenix|iceweasel", "firefox"), + ("galeon", "galeon"), + ("safari|version", "safari"), + ("webkit", "webkit"), + ("camino", "camino"), + ("konqueror", "konqueror"), + ("k-meleon", "kmeleon"), + ("netscape", "netscape"), + (r"msie|microsoft\s+internet\s+explorer|trident/.+? rv:", "msie"), + ("lynx", "lynx"), + ("links", "links"), + ("Baiduspider", "baidu"), + ("bingbot", "bing"), + ("mozilla", "mozilla"), + ) + + _browser_version_re = r"(?:{pattern})[/\sa-z(]*(\d+[.\da-z]+)?" + _language_re = re.compile( + r"(?:;\s*|\s+)(\b\w{2}\b(?:-\b\w{2}\b)?)\s*;|" + r"(?:\(|\[|;)\s*(\b\w{2}\b(?:-\b\w{2}\b)?)\s*(?:\]|\)|;)" + ) + + def __init__(self) -> None: + self.platforms = [(b, re.compile(a, re.I)) for a, b in self.platform_rules] + self.browsers = [ + (b, re.compile(self._browser_version_re.format(pattern=a), re.I)) + for a, b in self.browser_rules + ] + + def __call__( + self, user_agent: str + ) -> t.Tuple[t.Optional[str], t.Optional[str], t.Optional[str], t.Optional[str]]: + platform: t.Optional[str] + browser: t.Optional[str] + version: t.Optional[str] + language: t.Optional[str] + + for platform, regex in self.platforms: # noqa: B007 + match = regex.search(user_agent) + if match is not None: + break + else: + platform = None + + # Except for Trident, all browser key words come after the last ')' + last_closing_paren = 0 + if ( + not re.compile(r"trident/.+? rv:", re.I).search(user_agent) + and ")" in user_agent + and user_agent[-1] != ")" + ): + last_closing_paren = user_agent.rindex(")") + + for browser, regex in self.browsers: # noqa: B007 + match = regex.search(user_agent[last_closing_paren:]) + if match is not None: + version = match.group(1) + break + else: + browser = version = None + match = self._language_re.search(user_agent) + if match is not None: + language = match.group(1) or match.group(2) + else: + language = None + return platform, browser, version, language + + +# It wasn't public, but users might have imported it anyway, show a +# warning if a user created an instance. +class UserAgentParser(_UserAgentParser): + """A simple user agent parser. Used by the `UserAgent`. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Use a dedicated parser library + instead. + """ + + def __init__(self) -> None: + warnings.warn( + "'UserAgentParser' is deprecated and will be removed in" + " Werkzeug 2.1. Use a dedicated parser library instead.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__() + + +class _deprecated_property(property): + def __init__(self, fget: t.Callable[["_UserAgent"], t.Any]) -> None: + super().__init__(fget) + self.message = ( + "The built-in user agent parser is deprecated and will be" + f" removed in Werkzeug 2.1. The {fget.__name__!r} property" + " will be 'None'. Subclass 'werkzeug.user_agent.UserAgent'" + " and set 'Request.user_agent_class' to use a different" + " parser." + ) + + def __get__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: + warnings.warn(self.message, DeprecationWarning, stacklevel=3) + return super().__get__(*args, **kwargs) + + +# This is what Request.user_agent returns for now, only show warnings on +# attribute access, not creation. +class _UserAgent(_BaseUserAgent): + _parser = _UserAgentParser() + + def __init__(self, string: str) -> None: + super().__init__(string) + info = self._parser(string) + self._platform, self._browser, self._version, self._language = info + + @_deprecated_property + def platform(self) -> t.Optional[str]: # type: ignore + return self._platform + + @_deprecated_property + def browser(self) -> t.Optional[str]: # type: ignore + return self._browser + + @_deprecated_property + def version(self) -> t.Optional[str]: # type: ignore + return self._version + + @_deprecated_property + def language(self) -> t.Optional[str]: # type: ignore + return self._language + + +# This is what users might be importing, show warnings on create. +class UserAgent(_UserAgent): + """Represents a parsed user agent header value. + + This uses a basic parser to try to extract some information from the + header. + + :param environ_or_string: The header value to parse, or a WSGI + environ containing the header. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Subclass + :class:`werkzeug.user_agent.UserAgent` (note the new module + name) to use a dedicated parser instead. + + .. versionchanged:: 2.0 + Passing a WSGI environ is deprecated and will be removed in 2.1. + """ + + def __init__(self, environ_or_string: "t.Union[str, WSGIEnvironment]") -> None: + if isinstance(environ_or_string, dict): + warnings.warn( + "Passing an environ to 'UserAgent' is deprecated and" + " will be removed in Werkzeug 2.1. Pass the header" + " value string instead.", + DeprecationWarning, + stacklevel=2, + ) + string = environ_or_string.get("HTTP_USER_AGENT", "") + else: + string = environ_or_string + + warnings.warn( + "The 'werkzeug.useragents' module is deprecated and will be" + " removed in Werkzeug 2.1. The new base API is" + " 'werkzeug.user_agent.UserAgent'.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(string) diff --git a/venv/lib/python3.9/site-packages/werkzeug/utils.py b/venv/lib/python3.9/site-packages/werkzeug/utils.py new file mode 100644 index 0000000..7bb02bb --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/utils.py @@ -0,0 +1,1091 @@ +import codecs +import io +import mimetypes +import os +import pkgutil +import re +import sys +import typing as t +import unicodedata +import warnings +from datetime import datetime +from html.entities import name2codepoint +from time import time +from zlib import adler32 + +from ._internal import _DictAccessorProperty +from ._internal import _missing +from ._internal import _parse_signature +from ._internal import _TAccessorValue +from .datastructures import Headers +from .exceptions import NotFound +from .exceptions import RequestedRangeNotSatisfiable +from .security import safe_join +from .urls import url_quote +from .wsgi import wrap_file + +if t.TYPE_CHECKING: + from _typeshed.wsgi import WSGIEnvironment + from .wrappers.request import Request + from .wrappers.response import Response + +_T = t.TypeVar("_T") + +_entity_re = re.compile(r"&([^;]+);") +_filename_ascii_strip_re = re.compile(r"[^A-Za-z0-9_.-]") +_windows_device_files = ( + "CON", + "AUX", + "COM1", + "COM2", + "COM3", + "COM4", + "LPT1", + "LPT2", + "LPT3", + "PRN", + "NUL", +) + + +class cached_property(property, t.Generic[_T]): + """A :func:`property` that is only evaluated once. Subsequent access + returns the cached value. Setting the property sets the cached + value. Deleting the property clears the cached value, accessing it + again will evaluate it again. + + .. code-block:: python + + class Example: + @cached_property + def value(self): + # calculate something important here + return 42 + + e = Example() + e.value # evaluates + e.value # uses cache + e.value = 16 # sets cache + del e.value # clears cache + + The class must have a ``__dict__`` for this to work. + + .. versionchanged:: 2.0 + ``del obj.name`` clears the cached value. + """ + + def __init__( + self, + fget: t.Callable[[t.Any], _T], + name: t.Optional[str] = None, + doc: t.Optional[str] = None, + ) -> None: + super().__init__(fget, doc=doc) + self.__name__ = name or fget.__name__ + self.__module__ = fget.__module__ + + def __set__(self, obj: object, value: _T) -> None: + obj.__dict__[self.__name__] = value + + def __get__(self, obj: object, type: type = None) -> _T: # type: ignore + if obj is None: + return self # type: ignore + + value: _T = obj.__dict__.get(self.__name__, _missing) + + if value is _missing: + value = self.fget(obj) # type: ignore + obj.__dict__[self.__name__] = value + + return value + + def __delete__(self, obj: object) -> None: + del obj.__dict__[self.__name__] + + +def invalidate_cached_property(obj: object, name: str) -> None: + """Invalidates the cache for a :class:`cached_property`: + + >>> class Test(object): + ... @cached_property + ... def magic_number(self): + ... print("recalculating...") + ... return 42 + ... + >>> var = Test() + >>> var.magic_number + recalculating... + 42 + >>> var.magic_number + 42 + >>> invalidate_cached_property(var, "magic_number") + >>> var.magic_number + recalculating... + 42 + + You must pass the name of the cached property as the second argument. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Use ``del obj.name`` instead. + """ + warnings.warn( + "'invalidate_cached_property' is deprecated and will be removed" + " in Werkzeug 2.1. Use 'del obj.name' instead.", + DeprecationWarning, + stacklevel=2, + ) + delattr(obj, name) + + +class environ_property(_DictAccessorProperty[_TAccessorValue]): + """Maps request attributes to environment variables. This works not only + for the Werkzeug request object, but also any other class with an + environ attribute: + + >>> class Test(object): + ... environ = {'key': 'value'} + ... test = environ_property('key') + >>> var = Test() + >>> var.test + 'value' + + If you pass it a second value it's used as default if the key does not + exist, the third one can be a converter that takes a value and converts + it. If it raises :exc:`ValueError` or :exc:`TypeError` the default value + is used. If no default value is provided `None` is used. + + Per default the property is read only. You have to explicitly enable it + by passing ``read_only=False`` to the constructor. + """ + + read_only = True + + def lookup(self, obj: "Request") -> "WSGIEnvironment": + return obj.environ + + +class header_property(_DictAccessorProperty[_TAccessorValue]): + """Like `environ_property` but for headers.""" + + def lookup(self, obj: t.Union["Request", "Response"]) -> Headers: + return obj.headers + + +class HTMLBuilder: + """Helper object for HTML generation. + + Per default there are two instances of that class. The `html` one, and + the `xhtml` one for those two dialects. The class uses keyword parameters + and positional parameters to generate small snippets of HTML. + + Keyword parameters are converted to XML/SGML attributes, positional + arguments are used as children. Because Python accepts positional + arguments before keyword arguments it's a good idea to use a list with the + star-syntax for some children: + + >>> html.p(class_='foo', *[html.a('foo', href='foo.html'), ' ', + ... html.a('bar', href='bar.html')]) + '

    foo bar

    ' + + This class works around some browser limitations and can not be used for + arbitrary SGML/XML generation. For that purpose lxml and similar + libraries exist. + + Calling the builder escapes the string passed: + + >>> html.p(html("")) + '

    <foo>

    ' + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. + """ + + _entity_re = re.compile(r"&([^;]+);") + _entities = name2codepoint.copy() + _entities["apos"] = 39 + _empty_elements = { + "area", + "base", + "basefont", + "br", + "col", + "command", + "embed", + "frame", + "hr", + "img", + "input", + "keygen", + "isindex", + "link", + "meta", + "param", + "source", + "wbr", + } + _boolean_attributes = { + "selected", + "checked", + "compact", + "declare", + "defer", + "disabled", + "ismap", + "multiple", + "nohref", + "noresize", + "noshade", + "nowrap", + } + _plaintext_elements = {"textarea"} + _c_like_cdata = {"script", "style"} + + def __init__(self, dialect): # type: ignore + self._dialect = dialect + + def __call__(self, s): # type: ignore + import html + + warnings.warn( + "'utils.HTMLBuilder' is deprecated and will be removed in Werkzeug 2.1.", + DeprecationWarning, + stacklevel=2, + ) + return html.escape(s) + + def __getattr__(self, tag): # type: ignore + import html + + warnings.warn( + "'utils.HTMLBuilder' is deprecated and will be removed in Werkzeug 2.1.", + DeprecationWarning, + stacklevel=2, + ) + if tag[:2] == "__": + raise AttributeError(tag) + + def proxy(*children, **arguments): # type: ignore + buffer = f"<{tag}" + for key, value in arguments.items(): + if value is None: + continue + if key[-1] == "_": + key = key[:-1] + if key in self._boolean_attributes: + if not value: + continue + if self._dialect == "xhtml": + value = f'="{key}"' + else: + value = "" + else: + value = f'="{html.escape(value)}"' + buffer += f" {key}{value}" + if not children and tag in self._empty_elements: + if self._dialect == "xhtml": + buffer += " />" + else: + buffer += ">" + return buffer + buffer += ">" + + children_as_string = "".join([str(x) for x in children if x is not None]) + + if children_as_string: + if tag in self._plaintext_elements: + children_as_string = html.escape(children_as_string) + elif tag in self._c_like_cdata and self._dialect == "xhtml": + children_as_string = f"/**/" + buffer += children_as_string + f"" + return buffer + + return proxy + + def __repr__(self) -> str: + return f"<{type(self).__name__} for {self._dialect!r}>" + + +html = HTMLBuilder("html") +xhtml = HTMLBuilder("xhtml") + +# https://cgit.freedesktop.org/xdg/shared-mime-info/tree/freedesktop.org.xml.in +# https://www.iana.org/assignments/media-types/media-types.xhtml +# Types listed in the XDG mime info that have a charset in the IANA registration. +_charset_mimetypes = { + "application/ecmascript", + "application/javascript", + "application/sql", + "application/xml", + "application/xml-dtd", + "application/xml-external-parsed-entity", +} + + +def get_content_type(mimetype: str, charset: str) -> str: + """Returns the full content type string with charset for a mimetype. + + If the mimetype represents text, the charset parameter will be + appended, otherwise the mimetype is returned unchanged. + + :param mimetype: The mimetype to be used as content type. + :param charset: The charset to be appended for text mimetypes. + :return: The content type. + + .. versionchanged:: 0.15 + Any type that ends with ``+xml`` gets a charset, not just those + that start with ``application/``. Known text types such as + ``application/javascript`` are also given charsets. + """ + if ( + mimetype.startswith("text/") + or mimetype in _charset_mimetypes + or mimetype.endswith("+xml") + ): + mimetype += f"; charset={charset}" + + return mimetype + + +def detect_utf_encoding(data: bytes) -> str: + """Detect which UTF encoding was used to encode the given bytes. + + The latest JSON standard (:rfc:`8259`) suggests that only UTF-8 is + accepted. Older documents allowed 8, 16, or 32. 16 and 32 can be big + or little endian. Some editors or libraries may prepend a BOM. + + :internal: + + :param data: Bytes in unknown UTF encoding. + :return: UTF encoding name + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. This is built in to + :func:`json.loads`. + + .. versionadded:: 0.15 + """ + warnings.warn( + "'detect_utf_encoding' is deprecated and will be removed in" + " Werkzeug 2.1. This is built in to 'json.loads'.", + DeprecationWarning, + stacklevel=2, + ) + head = data[:4] + + if head[:3] == codecs.BOM_UTF8: + return "utf-8-sig" + + if b"\x00" not in head: + return "utf-8" + + if head in (codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE): + return "utf-32" + + if head[:2] in (codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE): + return "utf-16" + + if len(head) == 4: + if head[:3] == b"\x00\x00\x00": + return "utf-32-be" + + if head[::2] == b"\x00\x00": + return "utf-16-be" + + if head[1:] == b"\x00\x00\x00": + return "utf-32-le" + + if head[1::2] == b"\x00\x00": + return "utf-16-le" + + if len(head) == 2: + return "utf-16-be" if head.startswith(b"\x00") else "utf-16-le" + + return "utf-8" + + +def format_string(string: str, context: t.Mapping[str, t.Any]) -> str: + """String-template format a string: + + >>> format_string('$foo and ${foo}s', dict(foo=42)) + '42 and 42s' + + This does not do any attribute lookup. + + :param string: the format string. + :param context: a dict with the variables to insert. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Use :class:`string.Template` + instead. + """ + from string import Template + + warnings.warn( + "'utils.format_string' is deprecated and will be removed in" + " Werkzeug 2.1. Use 'string.Template' instead.", + DeprecationWarning, + stacklevel=2, + ) + return Template(string).substitute(context) + + +def secure_filename(filename: str) -> str: + r"""Pass it a filename and it will return a secure version of it. This + filename can then safely be stored on a regular file system and passed + to :func:`os.path.join`. The filename returned is an ASCII only string + for maximum portability. + + On windows systems the function also makes sure that the file is not + named after one of the special device files. + + >>> secure_filename("My cool movie.mov") + 'My_cool_movie.mov' + >>> secure_filename("../../../etc/passwd") + 'etc_passwd' + >>> secure_filename('i contain cool \xfcml\xe4uts.txt') + 'i_contain_cool_umlauts.txt' + + The function might return an empty filename. It's your responsibility + to ensure that the filename is unique and that you abort or + generate a random filename if the function returned an empty one. + + .. versionadded:: 0.5 + + :param filename: the filename to secure + """ + filename = unicodedata.normalize("NFKD", filename) + filename = filename.encode("ascii", "ignore").decode("ascii") + + for sep in os.path.sep, os.path.altsep: + if sep: + filename = filename.replace(sep, " ") + filename = str(_filename_ascii_strip_re.sub("", "_".join(filename.split()))).strip( + "._" + ) + + # on nt a couple of special files are present in each folder. We + # have to ensure that the target file is not such a filename. In + # this case we prepend an underline + if ( + os.name == "nt" + and filename + and filename.split(".")[0].upper() in _windows_device_files + ): + filename = f"_{filename}" + + return filename + + +def escape(s: t.Any) -> str: + """Replace ``&``, ``<``, ``>``, ``"``, and ``'`` with HTML-safe + sequences. + + ``None`` is escaped to an empty string. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Use MarkupSafe instead. + """ + import html + + warnings.warn( + "'utils.escape' is deprecated and will be removed in Werkzeug" + " 2.1. Use MarkupSafe instead.", + DeprecationWarning, + stacklevel=2, + ) + + if s is None: + return "" + + if hasattr(s, "__html__"): + return s.__html__() # type: ignore + + if not isinstance(s, str): + s = str(s) + + return html.escape(s, quote=True) # type: ignore + + +def unescape(s: str) -> str: + """The reverse of :func:`escape`. This unescapes all the HTML + entities, not only those inserted by ``escape``. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Use MarkupSafe instead. + """ + import html + + warnings.warn( + "'utils.unescape' is deprecated and will be removed in Werkzueg" + " 2.1. Use MarkupSafe instead.", + DeprecationWarning, + stacklevel=2, + ) + return html.unescape(s) + + +def redirect( + location: str, code: int = 302, Response: t.Optional[t.Type["Response"]] = None +) -> "Response": + """Returns a response object (a WSGI application) that, if called, + redirects the client to the target location. Supported codes are + 301, 302, 303, 305, 307, and 308. 300 is not supported because + it's not a real redirect and 304 because it's the answer for a + request with a request with defined If-Modified-Since headers. + + .. versionadded:: 0.6 + The location can now be a unicode string that is encoded using + the :func:`iri_to_uri` function. + + .. versionadded:: 0.10 + The class used for the Response object can now be passed in. + + :param location: the location the response should redirect to. + :param code: the redirect status code. defaults to 302. + :param class Response: a Response class to use when instantiating a + response. The default is :class:`werkzeug.wrappers.Response` if + unspecified. + """ + import html + + if Response is None: + from .wrappers import Response # type: ignore + + display_location = html.escape(location) + if isinstance(location, str): + # Safe conversion is necessary here as we might redirect + # to a broken URI scheme (for instance itms-services). + from .urls import iri_to_uri + + location = iri_to_uri(location, safe_conversion=True) + response = Response( # type: ignore + '\n' + "Redirecting...\n" + "

    Redirecting...

    \n" + "

    You should be redirected automatically to target URL: " + f'{display_location}. If' + " not click the link.", + code, + mimetype="text/html", + ) + response.headers["Location"] = location + return response + + +def append_slash_redirect(environ: "WSGIEnvironment", code: int = 301) -> "Response": + """Redirects to the same URL but with a slash appended. The behavior + of this function is undefined if the path ends with a slash already. + + :param environ: the WSGI environment for the request that triggers + the redirect. + :param code: the status code for the redirect. + """ + new_path = environ["PATH_INFO"].strip("/") + "/" + query_string = environ.get("QUERY_STRING") + if query_string: + new_path += f"?{query_string}" + return redirect(new_path, code) + + +def send_file( + path_or_file: t.Union[os.PathLike, str, t.BinaryIO], + environ: "WSGIEnvironment", + mimetype: t.Optional[str] = None, + as_attachment: bool = False, + download_name: t.Optional[str] = None, + conditional: bool = True, + etag: t.Union[bool, str] = True, + last_modified: t.Optional[t.Union[datetime, int, float]] = None, + max_age: t.Optional[ + t.Union[int, t.Callable[[t.Optional[str]], t.Optional[int]]] + ] = None, + use_x_sendfile: bool = False, + response_class: t.Optional[t.Type["Response"]] = None, + _root_path: t.Optional[t.Union[os.PathLike, str]] = 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. + + 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``, ``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 environ: The WSGI environ for the current request. + :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. + :param use_x_sendfile: Set the ``X-Sendfile`` header to let the + server to efficiently send the file. Requires support from the + HTTP server. Requires passing a file path. + :param response_class: Build the response using this class. Defaults + to :class:`~werkzeug.wrappers.Response`. + :param _root_path: Do not use. For internal use only. Use + :func:`send_from_directory` to safely send files under a path. + + .. versionadded:: 2.0 + Adapted from Flask's implementation. + + .. versionchanged:: 2.0 + ``download_name`` replaces Flask's ``attachment_filename`` + parameter. If ``as_attachment=False``, it is passed with + ``Content-Disposition: inline`` instead. + + .. versionchanged:: 2.0 + ``max_age`` replaces Flask's ``cache_timeout`` parameter. + ``conditional`` is enabled and ``max_age`` is not set by + default. + + .. versionchanged:: 2.0 + ``etag`` replaces Flask's ``add_etags`` parameter. It can be a + string to use instead of generating one. + + .. versionchanged:: 2.0 + If an encoding is returned when guessing ``mimetype`` from + ``download_name``, set the ``Content-Encoding`` header. + """ + if response_class is None: + from .wrappers import Response + + response_class = Response + + path: t.Optional[str] = None + file: t.Optional[t.BinaryIO] = None + size: t.Optional[int] = None + mtime: t.Optional[float] = None + headers = Headers() + + if isinstance(path_or_file, (os.PathLike, str)) or hasattr( + path_or_file, "__fspath__" + ): + path_or_file = t.cast(t.Union[os.PathLike, str], path_or_file) + + # Flask will pass app.root_path, allowing its send_file wrapper + # to not have to deal with paths. + if _root_path is not None: + path = os.path.join(_root_path, path_or_file) + else: + path = os.path.abspath(path_or_file) + + stat = os.stat(path) + size = stat.st_size + mtime = stat.st_mtime + else: + file = path_or_file + + if download_name is None and path is not None: + download_name = os.path.basename(path) + + if mimetype is None: + if download_name is None: + raise TypeError( + "Unable to detect the MIME type because a file name is" + " not available. Either set 'download_name', pass a" + " path instead of a file, or set 'mimetype'." + ) + + mimetype, encoding = mimetypes.guess_type(download_name) + + if mimetype is None: + mimetype = "application/octet-stream" + + if encoding is not None: + headers.set("Content-Encoding", encoding) + + if download_name is not None: + try: + download_name.encode("ascii") + except UnicodeEncodeError: + simple = unicodedata.normalize("NFKD", download_name) + simple = simple.encode("ascii", "ignore").decode("ascii") + quoted = url_quote(download_name, safe="") + names = {"filename": simple, "filename*": f"UTF-8''{quoted}"} + else: + names = {"filename": download_name} + + value = "attachment" if as_attachment else "inline" + headers.set("Content-Disposition", value, **names) + elif as_attachment: + raise TypeError( + "No name provided for attachment. Either set" + " 'download_name' or pass a path instead of a file." + ) + + if use_x_sendfile and path is not None: + headers["X-Sendfile"] = path + data = None + else: + if file is None: + file = open(path, "rb") # type: ignore + elif isinstance(file, io.BytesIO): + size = file.getbuffer().nbytes + elif isinstance(file, io.TextIOBase): + raise ValueError("Files must be opened in binary mode or use BytesIO.") + + data = wrap_file(environ, file) + + rv = response_class( + data, mimetype=mimetype, headers=headers, direct_passthrough=True + ) + + if size is not None: + rv.content_length = size + + if last_modified is not None: + rv.last_modified = last_modified # type: ignore + elif mtime is not None: + rv.last_modified = mtime # type: ignore + + rv.cache_control.no_cache = True + + # Flask will pass app.get_send_file_max_age, allowing its send_file + # wrapper to not have to deal with paths. + if callable(max_age): + max_age = max_age(path) + + if max_age is not None: + if max_age > 0: + rv.cache_control.no_cache = None + rv.cache_control.public = True + + rv.cache_control.max_age = max_age + rv.expires = int(time() + max_age) # type: ignore + + if isinstance(etag, str): + rv.set_etag(etag) + elif etag and path is not None: + check = adler32(path.encode("utf-8")) & 0xFFFFFFFF + rv.set_etag(f"{mtime}-{size}-{check}") + + if conditional: + try: + rv = rv.make_conditional(environ, accept_ranges=True, complete_length=size) + except RequestedRangeNotSatisfiable: + if file is not None: + file.close() + + raise + + # Some x-sendfile implementations incorrectly ignore the 304 + # status code and send the file anyway. + if rv.status_code == 304: + rv.headers.pop("x-sendfile", None) + + return rv + + +def send_from_directory( + directory: t.Union[os.PathLike, str], + path: t.Union[os.PathLike, str], + environ: "WSGIEnvironment", + **kwargs: t.Any, +) -> "Response": + """Send a file from within a directory using :func:`send_file`. + + 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, + returns a 404 :exc:`~werkzeug.exceptions.NotFound` error. + + :param directory: The directory that ``path`` must be located under. + :param path: The path to the file to send, relative to + ``directory``. + :param environ: The WSGI environ for the current request. + :param kwargs: Arguments to pass to :func:`send_file`. + + .. versionadded:: 2.0 + Adapted from Flask's implementation. + """ + path = safe_join(os.fspath(directory), os.fspath(path)) + + if path is None: + raise NotFound() + + # Flask will pass app.root_path, allowing its send_from_directory + # wrapper to not have to deal with paths. + if "_root_path" in kwargs: + path = os.path.join(kwargs["_root_path"], path) + + try: + if not os.path.isfile(path): + raise NotFound() + except ValueError: + # path contains null byte on Python < 3.8 + raise NotFound() + + return send_file(path, environ, **kwargs) + + +def import_string(import_name: str, silent: bool = False) -> t.Any: + """Imports an object based on a string. This is useful if you want to + use import paths as endpoints or something similar. An import path can + be specified either in dotted notation (``xml.sax.saxutils.escape``) + or with a colon as object delimiter (``xml.sax.saxutils:escape``). + + If `silent` is True the return value will be `None` if the import fails. + + :param import_name: the dotted name for the object to import. + :param silent: if set to `True` import errors are ignored and + `None` is returned instead. + :return: imported object + """ + import_name = import_name.replace(":", ".") + try: + try: + __import__(import_name) + except ImportError: + if "." not in import_name: + raise + else: + return sys.modules[import_name] + + module_name, obj_name = import_name.rsplit(".", 1) + module = __import__(module_name, globals(), locals(), [obj_name]) + try: + return getattr(module, obj_name) + except AttributeError as e: + raise ImportError(e) + + except ImportError as e: + if not silent: + raise ImportStringError(import_name, e).with_traceback(sys.exc_info()[2]) + + return None + + +def find_modules( + import_path: str, include_packages: bool = False, recursive: bool = False +) -> t.Iterator[str]: + """Finds all the modules below a package. This can be useful to + automatically import all views / controllers so that their metaclasses / + function decorators have a chance to register themselves on the + application. + + Packages are not returned unless `include_packages` is `True`. This can + also recursively list modules but in that case it will import all the + packages to get the correct load path of that module. + + :param import_path: the dotted name for the package to find child modules. + :param include_packages: set to `True` if packages should be returned, too. + :param recursive: set to `True` if recursion should happen. + :return: generator + """ + module = import_string(import_path) + path = getattr(module, "__path__", None) + if path is None: + raise ValueError(f"{import_path!r} is not a package") + basename = f"{module.__name__}." + for _importer, modname, ispkg in pkgutil.iter_modules(path): + modname = basename + modname + if ispkg: + if include_packages: + yield modname + if recursive: + yield from find_modules(modname, include_packages, True) + else: + yield modname + + +def validate_arguments(func, args, kwargs, drop_extra=True): # type: ignore + """Checks if the function accepts the arguments and keyword arguments. + Returns a new ``(args, kwargs)`` tuple that can safely be passed to + the function without causing a `TypeError` because the function signature + is incompatible. If `drop_extra` is set to `True` (which is the default) + any extra positional or keyword arguments are dropped automatically. + + The exception raised provides three attributes: + + `missing` + A set of argument names that the function expected but where + missing. + + `extra` + A dict of keyword arguments that the function can not handle but + where provided. + + `extra_positional` + A list of values that where given by positional argument but the + function cannot accept. + + This can be useful for decorators that forward user submitted data to + a view function:: + + from werkzeug.utils import ArgumentValidationError, validate_arguments + + def sanitize(f): + def proxy(request): + data = request.values.to_dict() + try: + args, kwargs = validate_arguments(f, (request,), data) + except ArgumentValidationError: + raise BadRequest('The browser failed to transmit all ' + 'the data expected.') + return f(*args, **kwargs) + return proxy + + :param func: the function the validation is performed against. + :param args: a tuple of positional arguments. + :param kwargs: a dict of keyword arguments. + :param drop_extra: set to `False` if you don't want extra arguments + to be silently dropped. + :return: tuple in the form ``(args, kwargs)``. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Use :func:`inspect.signature` + instead. + """ + warnings.warn( + "'utils.validate_arguments' is deprecated and will be removed" + " in Werkzeug 2.1. Use 'inspect.signature' instead.", + DeprecationWarning, + stacklevel=2, + ) + parser = _parse_signature(func) + args, kwargs, missing, extra, extra_positional = parser(args, kwargs)[:5] + if missing: + raise ArgumentValidationError(tuple(missing)) + elif (extra or extra_positional) and not drop_extra: + raise ArgumentValidationError(None, extra, extra_positional) + return tuple(args), kwargs + + +def bind_arguments(func, args, kwargs): # type: ignore + """Bind the arguments provided into a dict. When passed a function, + a tuple of arguments and a dict of keyword arguments `bind_arguments` + returns a dict of names as the function would see it. This can be useful + to implement a cache decorator that uses the function arguments to build + the cache key based on the values of the arguments. + + :param func: the function the arguments should be bound for. + :param args: tuple of positional arguments. + :param kwargs: a dict of keyword arguments. + :return: a :class:`dict` of bound keyword arguments. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Use :meth:`Signature.bind` + instead. + """ + warnings.warn( + "'utils.bind_arguments' is deprecated and will be removed in" + " Werkzeug 2.1. Use 'Signature.bind' instead.", + DeprecationWarning, + stacklevel=2, + ) + ( + args, + kwargs, + missing, + extra, + extra_positional, + arg_spec, + vararg_var, + kwarg_var, + ) = _parse_signature(func)(args, kwargs) + values = {} + for (name, _has_default, _default), value in zip(arg_spec, args): + values[name] = value + if vararg_var is not None: + values[vararg_var] = tuple(extra_positional) + elif extra_positional: + raise TypeError("too many positional arguments") + if kwarg_var is not None: + multikw = set(extra) & {x[0] for x in arg_spec} + if multikw: + raise TypeError( + f"got multiple values for keyword argument {next(iter(multikw))!r}" + ) + values[kwarg_var] = extra + elif extra: + raise TypeError(f"got unexpected keyword argument {next(iter(extra))!r}") + return values + + +class ArgumentValidationError(ValueError): + """Raised if :func:`validate_arguments` fails to validate + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1 along with ``utils.bind`` and + ``validate_arguments``. + """ + + def __init__(self, missing=None, extra=None, extra_positional=None): # type: ignore + self.missing = set(missing or ()) + self.extra = extra or {} + self.extra_positional = extra_positional or [] + super().__init__( + "function arguments invalid." + f" ({len(self.missing)} missing," + f" {len(self.extra) + len(self.extra_positional)} additional)" + ) + + +class ImportStringError(ImportError): + """Provides information about a failed :func:`import_string` attempt.""" + + #: String in dotted notation that failed to be imported. + import_name: str + #: Wrapped exception. + exception: BaseException + + def __init__(self, import_name: str, exception: BaseException) -> None: + self.import_name = import_name + self.exception = exception + msg = import_name + name = "" + tracked = [] + for part in import_name.replace(":", ".").split("."): + name = f"{name}.{part}" if name else part + imported = import_string(name, silent=True) + if imported: + tracked.append((name, getattr(imported, "__file__", None))) + else: + track = [f"- {n!r} found in {i!r}." for n, i in tracked] + track.append(f"- {name!r} not found.") + track_str = "\n".join(track) + msg = ( + f"import_string() failed for {import_name!r}. Possible reasons" + f" are:\n\n" + "- missing __init__.py in a package;\n" + "- package or module path not included in sys.path;\n" + "- duplicated package or module name taking precedence in" + " sys.path;\n" + "- missing module, class, function or variable;\n\n" + f"Debugged import:\n\n{track_str}\n\n" + f"Original exception:\n\n{type(exception).__name__}: {exception}" + ) + break + + super().__init__(msg) + + def __repr__(self) -> str: + return f"<{type(self).__name__}({self.import_name!r}, {self.exception!r})>" diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/__init__.py b/venv/lib/python3.9/site-packages/werkzeug/wrappers/__init__.py new file mode 100644 index 0000000..eb69a99 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wrappers/__init__.py @@ -0,0 +1,16 @@ +from .accept import AcceptMixin +from .auth import AuthorizationMixin +from .auth import WWWAuthenticateMixin +from .base_request import BaseRequest +from .base_response import BaseResponse +from .common_descriptors import CommonRequestDescriptorsMixin +from .common_descriptors import CommonResponseDescriptorsMixin +from .etag import ETagRequestMixin +from .etag import ETagResponseMixin +from .request import PlainRequest +from .request import Request as Request +from .request import StreamOnlyMixin +from .response import Response as Response +from .response import ResponseStream +from .response import ResponseStreamMixin +from .user_agent import UserAgentMixin diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8a27bef95b6b135e901f8a8ab2c9a0c5c1b196cb GIT binary patch literal 921 zcmaKq&5qMB5XX}?ZPVtXAKP8ZfxY*@=CCIugeV{41gv&Jm3#?qYFevy9Bijc_aS%> z-h-#;l@k&N&YT!K4GR(?QAWS{d&Xl=21ilPf#DhCs>h7@}VS3LvmQTst~y% z;NN>HI2ZXL;2BYwq=gnz)%mA&K$Y^3h{5wWcy-vI&Kg!)l~ar11;ey11+_c3$Le2c zNict%vt1qSUy|RajBBpKAou8RrA~_9Dk5hqXo6Kiq&Eg~mii_vPV6 zGB#S@n1Na7m2m15n`6r%2%jA}F^k6hUhfLJ#A;2p3H*qS7De)c>UFtD zE`-$Y1*0O_l6;#mx=4y0j7ffe_8?JIllukEHc&z(*F literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/accept.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/accept.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ae5f354fa8b34d6ecc953f5ac8dbbdc2718fbaf GIT binary patch literal 827 zcmYjPzi$&U6t?d!=}}sK33iKtC`jZ)nUD~oQl(Br2!={ojC+1b+&I3g?Mq12t(7{# zU%<%Hfq%#=QzZswSa?pNDo=XP@A+Auzwg;%cXykh{q}!8|D=Tcip8d-SiD1bPccX$ zsU`!uT$4d^NMs_@OCr;YWRObwiFC6YJV*LvjGLCN3-=roSYiwkNKdlplFHAHS>)b7bDfRbI!rkxp|(&850VKZ*<5MOj)7U2 zRx{jFh8=;OoIx{Ud%c%E*7*ph4LILnrkZ2B)Qtqk{217>TwOWl(Asv+(F(O#}gsR;|!-O$|2WoGYU|=W#j?^w7o$*f{cQ z8t!mjYT+E`*W~Y{7*|s$yqZ>iyr`8FZVa>H0Nlh^b#bWtxH&F9RMrnGt*T-MW>#o* zT+|CcuFR|6>%u7yFKT2eM&OG1T6{6LqDC^V5XCWK}*NfVm`9BWSV^gq~C+=&1H literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/auth.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/auth.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4279b7e2b92517dec13888b9f12867c82063ee85 GIT binary patch literal 1305 zcmb_cJ8u&~5Z=8zJ4bMMM1cYn=_)Lc@bRdS5F%2fR7400BR9+Dc5QFG-n;DX+1LtI zBBg>~KuMFobS+gR3TkMWv8~8bQXrI-W^QIjH#6VNr{!yFs|3zZ|Lfz2kdPnfEFZWd zuR+`sP=W}mNr%q9K_}QDA`sy*5#dqL3Bij*4ZIq7k)ZF%!}=NgMRqgP%O_em?hzPr zma!Aaa6dv3R0Q9`6Vjz36wz^`Q#&CM>C_=#tyosRoqnYh;6ll0cRFoe zEZR(zON1<}%(#~#;YK85rFF6=6Dx=L2=0_g+R_fDvg{?#T2EU^^PM~>rSr|iC@9b)IJfEk{zH)~Xm_8f5@+gjTh_y=Vjy zwCAC!=E_3aDrQU>U&k?ttpFZa^7x%J&#t2`Y^GfK7EON$At#5`}kNS*TXaRHt3o^X~F|oLWI*4n4A~d2w7|`HPePw$8;;38a5LOV5;X}z-waVBq7o|qK!Pr5`^&&!j z6>gb%k!o#$Fq2v{W;dYRT&<&Z2NjMO=i$(Z>CC@E#%{FRZ3HEaSICt)XD#yastEeI zd0CDBrKl@%7Ov#NI+R8}Dq|vl-*U@#^BjH!o}beC75oCcA8Fn-I8- t85dhaAKr($2j-fdy@&r@M}={V(WNx!jaBi>Ig4K5Tj7wCF^$6;jlU9COZxx- literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/base_request.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/base_request.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd785693aa0fe0b7438409ee45fbba386873d73d GIT binary patch literal 1780 zcmd5-&2Jk;6rb6hU9Zyw+9-U8FRc(FHKN`ECnSUljp!{x6jaHVVZHNWZ@k`hW@c?U z$}N$4Do0K|a_PS`S5A>Qa0U*%w_Z0cK?sQpBhAk{Z$94V?>XJs*kbGARrEv* zI*LDJz3wHx#11bxVvoDdH*iveu^CA>hmVVUIL%!IXtWMI@Q(!qia%|1Ux-17k`77) zN&*$4BvKvJ61iRZRXTx(^)M?^WA2Y3oAf*vnO5LJ4Yt;0=Hc_}LEiz+`#8-T2$mgl z#ciYQiO-q!&$t!m9%>MWr{n!EQvBR zfu5W~J&Hf>f7Fk^GZ63RW^L5%tS}$O?Snmhu{0J^)xRXeo^iKjY?@69m_yMET(n4a znU^Eu1bw;PgI0T9m5)|iZtLoCO%cTq_^3pam(Q4f8Gn8|NygO_5}QveJ6_Imm6|ck zlLIglTg{ROxgFQTvsKKW0Z<`AS@D4}!-`utA7y4BU+k zE*|!LCsK{f2q#F5ky(`mwVd@JG7t&KO!Gd%b*i7UV{yiFcIN%Wf8ZS3--`C;Khu8y zdCw@T1+qLVY6T{?V~CIHGP6kFw8-r;Rynp4TP*wkR4sw2kz|y&yv(hX30yYb#$d{8ljX|wWDL)dkg1PwfIQ9-^0%7-bOT$aqYt${R*DeuM)gQ@H)Yp1Tli! zX_aJ96l+CI9lT3Ns9ZIvqYH*wTEv?*{ta}efUS)>HMZ{1Vizh$tJjGduG998h7C^O hJ~Z{yT;E_sqpYDt^x3L(Kc}P{qFKZvZ`;4Q_b2N*!m0oO literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/base_response.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/base_response.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..311fbc7f4699b1d897afee7211340b55f3541260 GIT binary patch literal 1791 zcmd5-&5zqe6rZujjri!Y-2nliiXMwm zNAU-2(7nKy*wFzX1!h^51~L*~9X>AZ;xz9gK%;i#fj<)vDE_2TelA8KN;)VJ zC<#=El1Oz>P2>*b7wH@x)Z?s3jk!04Y(DT@WOf1eCJk%hLPGj(RPj15ig*mMhDEhPSzg8u zLC;U1p2QyxKN!Z}7>N71X|1}G73STzeQ|(Kmc~M=h8JYoQ||VRO|y9cD<}qmi`J1LU$)J$QO z9D6?X(^zUsl>4S4CbWD=1evcxSkupM4Ob>x^!9CC8-tS>}^49e{4zFFM%u=Y*G6PLT z`~OI5Yto%+Jp0?U>JHkf$?-v;iHiC;0tx~puD!oYoPM4*4+to2Tev}IF_`VyT`+H= z_}>QeFISHST^C7NrVEhL?Mb<)R9(<_Ps;D=wAk%%>%`ZaB{(szszQ@S=YLji^sPUQ zd)7>iEryZDhCU*G&}}5ws872z%sU9rP#@{9xbmL(kJvF+z7prXQSgWfHVToFf$Lo* z52?*2wj&s1=ylP9Z+7%giE;(;~NsQ^5qLMygTj@-nwllKTdVWBoch zrr$uo2GW(XX^2u@mXD5c?=_s41>+<8ehWJ%x32~idAEDHqi^GJ{UX6j1TPc3N)RKs z{hgK!ilWuj)WVx|gi2PEKDuD2vqijF;~zqI0odWFWn&KyEjFWavVEQC;i9&MG?Z`x i4?t5y&HXF1XtXulh(6iY@28Y_LtKk^Yx15VdzVX(%a$3OFDY?Wqw+WcfHDAq1jQPgDpFm2xrLwUfAU?5*uhNYxW9 z>Ir@UM=t$Kd*xJ#182A}lcZ6kRt2G2n%NnTc4pqplhdW8MFQuC|M~u7NXU0|<`3MF z7a;B-C{8$4q(#TypcQNo9`Nvx@bDmLh2TZJ0$v5Yh|_oEUiAe2BAXfN`4deYcOMKf z&e#e>xD%mp%7d@r5ouE%^60SMsvMDsw5pJ=Qm(!-{l3v}#cm;-Ul%U3GWW*1*YbnZ zo5x`prMBbBYHv9CTHy<;GdfouF;zg8LEIWBPj)D$K0q{|LrQ#jKz5>iD#?EEjeemN zkVExobMI5*!upL^x|oaHiY)bl$EoJ=P%0H~i`a_38Ni*?@s_Z?JyCSx$IVC0xG@FO zh_x9)I8y}|F7{m!w+o$lX>_WjAH`fkUav;YlK`4NrsbmZY1UI>Ak=ZCtN~&zHGq%M zDp%I0jX;8}NvN#2A{Vx-F($S2jN!bTP;HAFu{ab+dxfz~rOrW^{2C@*(-(=CedD{M zT=LX)#UO#n_q@rI4e7hZcJjtp-!@8`WFYh)QF1%UN4{(HljhUJNiQDc&}rHcE*Vb2 zCqtX&(2Ps6@k$whK3!%rA6eW^6~xs+5gO4T3~2DXy0Eu);SQQJYzv4}r+vX#xyV@G z@Is+oXKc4f)igqV8NSq$dgam-dM1=&%-)2`6SacYEmSyr9F#+&M#ugo68!EdIF}pk z#2JQLWbb9s`DjMx^Q-+YpC{S=ozQjxK-n59e2(mORO6A4H!z+%@&T{T^5HKaW`wY} zG3|LfU4_66%st&H`taCPJrG`Z>>d2?Dk_XyjLxN*wOH1kO*r-(UmJ(ytmbW+rd$EzLl7z{qo z*mbzO@1ZctoUiUF=~3n~@1)uFPl-pm4an!0tM5K+?`-pff*bo@917Jrb4xGLeN#4u zlj^IvEwoDMLPdn(gWLu&4?$V7PZ_li0{HAwV%=l1?;TM=j+}4w3#9-S3VNN{Ve4|q zRwzu!c&>SxSkA&kv2Y@!4EK1b`6wI1olxN}*TWev`r-5Tvv%03n{I_Fn?N{~1>+{P z10MDYm0FRhL<&0%nSi`jPTS`W^m#_hWn+_cDEXMnGrtS~q!J47dT5pFn{^|QV7CgD zzA199%OH-05;l%;M25?r#<^>p1EjqX$Ei$=fiU?cqCqy|krkuN4yL(ai5c*5w8_oT zW_h$F?4a0-K4#kXGAXiX%+)xOVlT?4c95wT?U#`emOsg%)1=Q$G^xQy6P@JHjET}r zn|40cxPk_VX@VluqmJuP=XYaicK`CA+ZORxaxl-dxxs-9N??ACit)q1p6%H7uVbBQZ+`mSyu2pzUo+-mCvT7vabun{RGjpN9 z|5CF`@$cN!OMpWMsPO&JtElFKozHnbU0gI?U0w9XmBCzWTHnJ=e_PfA2&`ecdRgeh ogV3-*SJl@W_}@)b7}pqGNORFu8N8~<^BSKAgG3By;NEKf0ebL5+5i9m literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/etag.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/etag.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b646deb7cff419364fed2f917651fe38496272b GIT binary patch literal 1290 zcmb_cOKTKC5bmDGW{ew6f(izNIk_mf}nGwJTx%`Ukm zkdyubk6!YZ=ISZn!Lweh+8M%U1x_dhq=duxkpad1^j^XdMJ!C=c{`{dX%}$J8pLU6XKC>1M>Oh`kRkQ|2^L?xUp}=fl!@OxAYR-H)Ufq zt-hMuLaUT6RYVv*$W0J)ACx6S%BXb^z-N~d>mHGzcSr>}biUCqlmb{N=ym1?t&1gF zp)euix#nqNISUiT!l{rl+~c9<<7@(VLWR3rkLJAShfmv2+F`41x)rKy3gJ{1jGNF7 zc-SjcYDK0JDeNp{0`gipYo9sL=P4~$jZM;#=wHjZ_rHo^J3yM{06Rq2*aKJbXgGN9X{uOd{qrzkIOc`F0RU;9vikb78nM(!! zmzq_If9IxN0USC&h3|)6N3|I2V$O@{;-c~D@}jpc4d#5)`VMCL+p_LKU<1?D%R(O> ngoXvWs=nUB|E{CLxW?#Gn)9y8;6+8Am-svwBw|1V_eS#%mT5%5 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/json.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/json.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ef175342e157887f8679255a6f4d838a64d4c9d GIT binary patch literal 819 zcmYjP&x;c=6i#NQb#~eH$Ab6Z!BW8v>PZk$SXdCO;vN=yiPOnzn>Ni%lT2%uz3sxD z^bZh^UiM$g)zg9p&*H(Cwv;}2FYo1r?|t7R`QhO{LHq6geEv=e`4x&?i?MivZXaO~ zL{LR~bah6(=!A$!#8*Vbmr*Yk^pv!dTYN{lMTonWYzq4X6IfyNB8bOHa6v`%BfcgB zDq@jb9rPO4Bq6;f;x+u-FEDg+zhR6P8RFafUAuzkondE;|BUYbo&^C zBV#J4ivriLF(od(B;(|QN^%kXq~9n-U4eP`eAe2|YB6bFLgtT-H$)KNY~At=TUTIw%DL3iaUOPKK@CjMZ^F87 zsNdtfP`S07-;lpD8n{XXZ@Qq(Hs2b|C9Tx~kk`S`6~WBbF6umY6g+}y`0>u@(@4?+l= t4gbJ~B&Dmmo%p6h>3V1$hBs*lp}&K$!U_mJeYK|YI(#o1R+`c@{tv`Q*mVE^ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/request.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/request.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e697b8450fa6b382fc1f80666d7195ef7ffae53a GIT binary patch literal 21308 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 Rjsl(*rvAXu|5qjt{U2@gzGnac literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/response.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/response.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bdb95af5e6e315d97fcb03c6efc8d45117eb0ae GIT binary patch literal 29702 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/user_agent.cpython-39.pyc b/venv/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/user_agent.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ededc9d1810491b2a9460acdd2065c7a6f513da3 GIT binary patch literal 840 zcmY*XO>Yx15VhBvbgA0%AtA072cjU66>vgAh)R`uqCy~4DHpR{PZBqdcWZkS67|+f zJ;5*F$falgjjx<4ao`LW#z|DQBh7eb$9nVLtc&gKO@j8@|M~or67nk+H;rNO7TrC@ zAc>@!^y%_U`pG_#iDc(Qva_VmB>hOb=@s512W5;mEnOGxDJHPQ=qJFA)98}QWdo6Z;ISi=-FiqBA@Q3lnfF$)j&)?|~cps?PV7A2mn$`^x%3rB#(r z!Ax_lj`Di$N0oWmdzCxo;aQDLiy^ptwichyY*8Z_mpAy+1on*Y)pNUrB--dMCWNLm zVF^wCwKo=zZZErcEn*`IGQ|Xh2%ADoD%t3mZwYbI6nfpEKCoT08W6VE8cWbx2zw7l zt-?;s?#B?99N&eDNk*4-Hw|r%TQEcWFy6^xi2WM~ORR_xvezprZ{l-val0AK*nboJ B;u8P> literal 0 HcmV?d00001 diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/accept.py b/venv/lib/python3.9/site-packages/werkzeug/wrappers/accept.py new file mode 100644 index 0000000..9605e63 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wrappers/accept.py @@ -0,0 +1,14 @@ +import typing as t +import warnings + + +class AcceptMixin: + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'AcceptMixin' is deprecated and will be removed in" + " Werkzeug 2.1. 'Request' now includes the functionality" + " directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) # type: ignore diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/auth.py b/venv/lib/python3.9/site-packages/werkzeug/wrappers/auth.py new file mode 100644 index 0000000..da31b7c --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wrappers/auth.py @@ -0,0 +1,26 @@ +import typing as t +import warnings + + +class AuthorizationMixin: + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'AuthorizationMixin' is deprecated and will be removed in" + " Werkzeug 2.1. 'Request' now includes the functionality" + " directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) # type: ignore + + +class WWWAuthenticateMixin: + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'WWWAuthenticateMixin' is deprecated and will be removed" + " in Werkzeug 2.1. 'Response' now includes the" + " functionality directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) # type: ignore diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/base_request.py b/venv/lib/python3.9/site-packages/werkzeug/wrappers/base_request.py new file mode 100644 index 0000000..451989f --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wrappers/base_request.py @@ -0,0 +1,36 @@ +import typing as t +import warnings + +from .request import Request + + +class _FakeSubclassCheck(type): + def __subclasscheck__(cls, subclass: t.Type) -> bool: + warnings.warn( + "'BaseRequest' is deprecated and will be removed in" + " Werkzeug 2.1. Use 'issubclass(cls, Request)' instead.", + DeprecationWarning, + stacklevel=2, + ) + return issubclass(subclass, Request) + + def __instancecheck__(cls, instance: t.Any) -> bool: + warnings.warn( + "'BaseRequest' is deprecated and will be removed in" + " Werkzeug 2.1. Use 'isinstance(obj, Request)' instead.", + DeprecationWarning, + stacklevel=2, + ) + return isinstance(instance, Request) + + +class BaseRequest(Request, metaclass=_FakeSubclassCheck): + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'BaseRequest' is deprecated and will be removed in" + " Werkzeug 2.1. 'Request' now includes the functionality" + " directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/base_response.py b/venv/lib/python3.9/site-packages/werkzeug/wrappers/base_response.py new file mode 100644 index 0000000..3e0dc67 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wrappers/base_response.py @@ -0,0 +1,36 @@ +import typing as t +import warnings + +from .response import Response + + +class _FakeSubclassCheck(type): + def __subclasscheck__(cls, subclass: t.Type) -> bool: + warnings.warn( + "'BaseResponse' is deprecated and will be removed in" + " Werkzeug 2.1. Use 'issubclass(cls, Response)' instead.", + DeprecationWarning, + stacklevel=2, + ) + return issubclass(subclass, Response) + + def __instancecheck__(cls, instance: t.Any) -> bool: + warnings.warn( + "'BaseResponse' is deprecated and will be removed in" + " Werkzeug 2.1. Use 'isinstance(obj, Response)' instead.", + DeprecationWarning, + stacklevel=2, + ) + return isinstance(instance, Response) + + +class BaseResponse(Response, metaclass=_FakeSubclassCheck): + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'BaseResponse' is deprecated and will be removed in" + " Werkzeug 2.1. 'Response' now includes the functionality" + " directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/common_descriptors.py b/venv/lib/python3.9/site-packages/werkzeug/wrappers/common_descriptors.py new file mode 100644 index 0000000..db87ea5 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wrappers/common_descriptors.py @@ -0,0 +1,26 @@ +import typing as t +import warnings + + +class CommonRequestDescriptorsMixin: + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'CommonRequestDescriptorsMixin' is deprecated and will be" + " removed in Werkzeug 2.1. 'Request' now includes the" + " functionality directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) # type: ignore + + +class CommonResponseDescriptorsMixin: + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'CommonResponseDescriptorsMixin' is deprecated and will be" + " removed in Werkzeug 2.1. 'Response' now includes the" + " functionality directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) # type: ignore diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/cors.py b/venv/lib/python3.9/site-packages/werkzeug/wrappers/cors.py new file mode 100644 index 0000000..89cf83e --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wrappers/cors.py @@ -0,0 +1,26 @@ +import typing as t +import warnings + + +class CORSRequestMixin: + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'CORSRequestMixin' is deprecated and will be removed in" + " Werkzeug 2.1. 'Request' now includes the functionality" + " directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) # type: ignore + + +class CORSResponseMixin: + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'CORSResponseMixin' is deprecated and will be removed in" + " Werkzeug 2.1. 'Response' now includes the functionality" + " directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) # type: ignore diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/etag.py b/venv/lib/python3.9/site-packages/werkzeug/wrappers/etag.py new file mode 100644 index 0000000..2e9015a --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wrappers/etag.py @@ -0,0 +1,26 @@ +import typing as t +import warnings + + +class ETagRequestMixin: + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'ETagRequestMixin' is deprecated and will be removed in" + " Werkzeug 2.1. 'Request' now includes the functionality" + " directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) # type: ignore + + +class ETagResponseMixin: + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'ETagResponseMixin' is deprecated and will be removed in" + " Werkzeug 2.1. 'Response' now includes the functionality" + " directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) # type: ignore diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/json.py b/venv/lib/python3.9/site-packages/werkzeug/wrappers/json.py new file mode 100644 index 0000000..ab6ed7b --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wrappers/json.py @@ -0,0 +1,13 @@ +import typing as t +import warnings + + +class JSONMixin: + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'JSONMixin' is deprecated and will be removed in Werkzeug" + " 2.1. 'Request' now includes the functionality directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) # type: ignore diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/request.py b/venv/lib/python3.9/site-packages/werkzeug/wrappers/request.py new file mode 100644 index 0000000..60c3b5f --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wrappers/request.py @@ -0,0 +1,660 @@ +import functools +import json +import typing +import typing as t +import warnings +from io import BytesIO + +from .._internal import _wsgi_decoding_dance +from ..datastructures import CombinedMultiDict +from ..datastructures import EnvironHeaders +from ..datastructures import FileStorage +from ..datastructures import ImmutableMultiDict +from ..datastructures import iter_multi_items +from ..datastructures import MultiDict +from ..formparser import default_stream_factory +from ..formparser import FormDataParser +from ..sansio.request import Request as _SansIORequest +from ..utils import cached_property +from ..utils import environ_property +from ..wsgi import _get_server +from ..wsgi import get_input_stream +from werkzeug.exceptions import BadRequest + +if t.TYPE_CHECKING: + import typing_extensions as te + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class Request(_SansIORequest): + """Represents an incoming WSGI HTTP request, with headers and body + taken from the WSGI environment. Has properties and methods for + using the functionality defined by various HTTP specs. The data in + requests object is read-only. + + Text data is assumed to use UTF-8 encoding, which should be true for + the vast majority of modern clients. Using an encoding set by the + client is unsafe in Python due to extra encodings it provides, such + as ``zip``. To change the assumed encoding, subclass and replace + :attr:`charset`. + + :param environ: The WSGI environ is generated by the WSGI server and + contains information about the server configuration and client + request. + :param populate_request: Add this request object to the WSGI environ + as ``environ['werkzeug.request']``. Can be useful when + debugging. + :param shallow: Makes reading from :attr:`stream` (and any method + that would read from it) raise a :exc:`RuntimeError`. Useful to + prevent consuming the form data in middleware, which would make + it unavailable to the final application. + + .. versionchanged:: 2.0 + Combine ``BaseRequest`` and mixins into a single ``Request`` + class. Using the old classes is deprecated and will be removed + in Werkzeug 2.1. + + .. versionchanged:: 0.5 + Read-only mode is enforced with immutable classes for all data. + """ + + #: the maximum content length. This is forwarded to the form data + #: parsing function (:func:`parse_form_data`). When set and the + #: :attr:`form` or :attr:`files` attribute is accessed and the + #: parsing fails because more than the specified value is transmitted + #: a :exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception is raised. + #: + #: Have a look at :doc:`/request_data` for more details. + #: + #: .. versionadded:: 0.5 + max_content_length: t.Optional[int] = None + + #: the maximum form field size. This is forwarded to the form data + #: parsing function (:func:`parse_form_data`). When set and the + #: :attr:`form` or :attr:`files` attribute is accessed and the + #: data in memory for post data is longer than the specified value a + #: :exc:`~werkzeug.exceptions.RequestEntityTooLarge` exception is raised. + #: + #: Have a look at :doc:`/request_data` for more details. + #: + #: .. versionadded:: 0.5 + max_form_memory_size: t.Optional[int] = None + + #: The form data parser that shoud be used. Can be replaced to customize + #: the form date parsing. + form_data_parser_class: t.Type[FormDataParser] = FormDataParser + + #: Disable the :attr:`data` property to avoid reading from the input + #: stream. + #: + #: .. deprecated:: 2.0 + #: Will be removed in Werkzeug 2.1. Create the request with + #: ``shallow=True`` instead. + #: + #: .. versionadded:: 0.9 + disable_data_descriptor: t.Optional[bool] = None + + #: The WSGI environment containing HTTP headers and information from + #: the WSGI server. + environ: "WSGIEnvironment" + + #: Set when creating the request object. If ``True``, reading from + #: the request body will cause a ``RuntimeException``. Useful to + #: prevent modifying the stream from middleware. + shallow: bool + + def __init__( + self, + environ: "WSGIEnvironment", + populate_request: bool = True, + shallow: bool = False, + ) -> None: + super().__init__( + method=environ.get("REQUEST_METHOD", "GET"), + scheme=environ.get("wsgi.url_scheme", "http"), + server=_get_server(environ), + root_path=_wsgi_decoding_dance( + environ.get("SCRIPT_NAME") or "", self.charset, self.encoding_errors + ), + path=_wsgi_decoding_dance( + environ.get("PATH_INFO") or "", self.charset, self.encoding_errors + ), + query_string=environ.get("QUERY_STRING", "").encode("latin1"), + headers=EnvironHeaders(environ), + remote_addr=environ.get("REMOTE_ADDR"), + ) + self.environ = environ + + if self.disable_data_descriptor is not None: + warnings.warn( + "'disable_data_descriptor' is deprecated and will be" + " removed in Werkzeug 2.1. Create the request with" + " 'shallow=True' instead.", + DeprecationWarning, + stacklevel=2, + ) + shallow = shallow or self.disable_data_descriptor + + self.shallow = shallow + + if populate_request and not shallow: + self.environ["werkzeug.request"] = self + + @classmethod + def from_values(cls, *args: t.Any, **kwargs: t.Any) -> "Request": + """Create a new request object based on the values provided. If + environ is given missing values are filled from there. This method is + useful for small scripts when you need to simulate a request from an URL. + Do not use this method for unittesting, there is a full featured client + object (:class:`Client`) that allows to create multipart requests, + support for cookies etc. + + This accepts the same options as the + :class:`~werkzeug.test.EnvironBuilder`. + + .. versionchanged:: 0.5 + This method now accepts the same arguments as + :class:`~werkzeug.test.EnvironBuilder`. Because of this the + `environ` parameter is now called `environ_overrides`. + + :return: request object + """ + from ..test import EnvironBuilder + + charset = kwargs.pop("charset", cls.charset) + kwargs["charset"] = charset + builder = EnvironBuilder(*args, **kwargs) + try: + return builder.get_request(cls) + finally: + builder.close() + + @classmethod + def application( + cls, f: t.Callable[["Request"], "WSGIApplication"] + ) -> "WSGIApplication": + """Decorate a function as responder that accepts the request as + the last argument. This works like the :func:`responder` + decorator but the function is passed the request object as the + last argument and the request object will be closed + automatically:: + + @Request.application + def my_wsgi_app(request): + return Response('Hello World!') + + As of Werkzeug 0.14 HTTP exceptions are automatically caught and + converted to responses instead of failing. + + :param f: the WSGI callable to decorate + :return: a new WSGI callable + """ + #: return a callable that wraps the -2nd argument with the request + #: and calls the function with all the arguments up to that one and + #: the request. The return value is then called with the latest + #: two arguments. This makes it possible to use this decorator for + #: both standalone WSGI functions as well as bound methods and + #: partially applied functions. + from ..exceptions import HTTPException + + @functools.wraps(f) + def application(*args): # type: ignore + request = cls(args[-2]) + with request: + try: + resp = f(*args[:-2] + (request,)) + except HTTPException as e: + resp = e.get_response(args[-2]) + return resp(*args[-2:]) + + return t.cast("WSGIApplication", application) + + def _get_file_stream( + self, + total_content_length: t.Optional[int], + content_type: t.Optional[str], + filename: t.Optional[str] = None, + content_length: t.Optional[int] = None, + ) -> t.BinaryIO: + """Called to get a stream for the file upload. + + This must provide a file-like class with `read()`, `readline()` + and `seek()` methods that is both writeable and readable. + + The default implementation returns a temporary file if the total + content length is higher than 500KB. Because many browsers do not + provide a content length for the files only the total content + length matters. + + :param total_content_length: the total content length of all the + data in the request combined. This value + is guaranteed to be there. + :param content_type: the mimetype of the uploaded file. + :param filename: the filename of the uploaded file. May be `None`. + :param content_length: the length of this file. This value is usually + not provided because webbrowsers do not provide + this value. + """ + return default_stream_factory( + total_content_length=total_content_length, + filename=filename, + content_type=content_type, + content_length=content_length, + ) + + @property + def want_form_data_parsed(self) -> bool: + """``True`` if the request method carries content. By default + this is true if a ``Content-Type`` is sent. + + .. versionadded:: 0.8 + """ + return bool(self.environ.get("CONTENT_TYPE")) + + def make_form_data_parser(self) -> FormDataParser: + """Creates the form data parser. Instantiates the + :attr:`form_data_parser_class` with some parameters. + + .. versionadded:: 0.8 + """ + return self.form_data_parser_class( + self._get_file_stream, + self.charset, + self.encoding_errors, + self.max_form_memory_size, + self.max_content_length, + self.parameter_storage_class, + ) + + def _load_form_data(self) -> None: + """Method used internally to retrieve submitted data. After calling + this sets `form` and `files` on the request object to multi dicts + filled with the incoming form data. As a matter of fact the input + stream will be empty afterwards. You can also call this method to + force the parsing of the form data. + + .. versionadded:: 0.8 + """ + # abort early if we have already consumed the stream + if "form" in self.__dict__: + return + + if self.want_form_data_parsed: + parser = self.make_form_data_parser() + data = parser.parse( + self._get_stream_for_parsing(), + self.mimetype, + self.content_length, + self.mimetype_params, + ) + else: + data = ( + self.stream, + self.parameter_storage_class(), + self.parameter_storage_class(), + ) + + # inject the values into the instance dict so that we bypass + # our cached_property non-data descriptor. + d = self.__dict__ + d["stream"], d["form"], d["files"] = data + + def _get_stream_for_parsing(self) -> t.BinaryIO: + """This is the same as accessing :attr:`stream` with the difference + that if it finds cached data from calling :meth:`get_data` first it + will create a new stream out of the cached data. + + .. versionadded:: 0.9.3 + """ + cached_data = getattr(self, "_cached_data", None) + if cached_data is not None: + return BytesIO(cached_data) + return self.stream + + def close(self) -> None: + """Closes associated resources of this request object. This + closes all file handles explicitly. You can also use the request + object in a with statement which will automatically close it. + + .. versionadded:: 0.9 + """ + files = self.__dict__.get("files") + for _key, value in iter_multi_items(files or ()): + value.close() + + def __enter__(self) -> "Request": + return self + + def __exit__(self, exc_type, exc_value, tb) -> None: # type: ignore + self.close() + + @cached_property + def stream(self) -> t.BinaryIO: + """ + If the incoming form data was not encoded with a known mimetype + the data is stored unmodified in this stream for consumption. Most + of the time it is a better idea to use :attr:`data` which will give + you that data as a string. The stream only returns the data once. + + Unlike :attr:`input_stream` this stream is properly guarded that you + can't accidentally read past the length of the input. Werkzeug will + internally always refer to this stream to read data which makes it + possible to wrap this object with a stream that does filtering. + + .. versionchanged:: 0.9 + This stream is now always available but might be consumed by the + form parser later on. Previously the stream was only set if no + parsing happened. + """ + if self.shallow: + raise RuntimeError( + "This request was created with 'shallow=True', reading" + " from the input stream is disabled." + ) + + return get_input_stream(self.environ) + + input_stream = environ_property[t.BinaryIO]( + "wsgi.input", + doc="""The WSGI input stream. + + In general it's a bad idea to use this one because you can + easily read past the boundary. Use the :attr:`stream` + instead.""", + ) + + @cached_property + def data(self) -> bytes: + """ + Contains the incoming request data as string in case it came with + a mimetype Werkzeug does not handle. + """ + return self.get_data(parse_form_data=True) + + @typing.overload + def get_data( # type: ignore + self, + cache: bool = True, + as_text: "te.Literal[False]" = False, + parse_form_data: bool = False, + ) -> bytes: + ... + + @typing.overload + def get_data( + self, + cache: bool = True, + as_text: "te.Literal[True]" = ..., + parse_form_data: bool = False, + ) -> str: + ... + + def get_data( + self, cache: bool = True, as_text: bool = False, parse_form_data: bool = False + ) -> t.Union[bytes, str]: + """This reads the buffered incoming data from the client into one + bytes object. By default this is cached but that behavior can be + changed by setting `cache` to `False`. + + Usually it's a bad idea to call this method without checking the + content length first as a client could send dozens of megabytes or more + to cause memory problems on the server. + + Note that if the form data was already parsed this method will not + return anything as form data parsing does not cache the data like + this method does. To implicitly invoke form data parsing function + set `parse_form_data` to `True`. When this is done the return value + of this method will be an empty string if the form parser handles + the data. This generally is not necessary as if the whole data is + cached (which is the default) the form parser will used the cached + data to parse the form data. Please be generally aware of checking + the content length first in any case before calling this method + to avoid exhausting server memory. + + If `as_text` is set to `True` the return value will be a decoded + string. + + .. versionadded:: 0.9 + """ + rv = getattr(self, "_cached_data", None) + if rv is None: + if parse_form_data: + self._load_form_data() + rv = self.stream.read() + if cache: + self._cached_data = rv + if as_text: + rv = rv.decode(self.charset, self.encoding_errors) + return rv # type: ignore + + @cached_property + def form(self) -> "ImmutableMultiDict[str, str]": + """The form parameters. By default an + :class:`~werkzeug.datastructures.ImmutableMultiDict` + is returned from this function. This can be changed by setting + :attr:`parameter_storage_class` to a different type. This might + be necessary if the order of the form data is important. + + Please keep in mind that file uploads will not end up here, but instead + in the :attr:`files` attribute. + + .. versionchanged:: 0.9 + + Previous to Werkzeug 0.9 this would only contain form data for POST + and PUT requests. + """ + self._load_form_data() + return self.form + + @cached_property + def values(self) -> "CombinedMultiDict[str, str]": + """A :class:`werkzeug.datastructures.CombinedMultiDict` that + combines :attr:`args` and :attr:`form`. + + For GET requests, only ``args`` are present, not ``form``. + + .. versionchanged:: 2.0 + For GET requests, only ``args`` are present, not ``form``. + """ + sources = [self.args] + + if self.method != "GET": + # GET requests can have a body, and some caching proxies + # might not treat that differently than a normal GET + # request, allowing form data to "invisibly" affect the + # cache without indication in the query string / URL. + sources.append(self.form) + + args = [] + + for d in sources: + if not isinstance(d, MultiDict): + d = MultiDict(d) + + args.append(d) + + return CombinedMultiDict(args) + + @cached_property + def files(self) -> "ImmutableMultiDict[str, FileStorage]": + """:class:`~werkzeug.datastructures.MultiDict` object containing + all uploaded files. Each key in :attr:`files` is the name from the + ````. Each value in :attr:`files` is a + Werkzeug :class:`~werkzeug.datastructures.FileStorage` object. + + It basically behaves like a standard file object you know from Python, + with the difference that it also has a + :meth:`~werkzeug.datastructures.FileStorage.save` function that can + store the file on the filesystem. + + Note that :attr:`files` will only contain data if the request method was + POST, PUT or PATCH and the ``

    `` that posted to the request had + ``enctype="multipart/form-data"``. It will be empty otherwise. + + See the :class:`~werkzeug.datastructures.MultiDict` / + :class:`~werkzeug.datastructures.FileStorage` documentation for + more details about the used data structure. + """ + self._load_form_data() + return self.files + + @property + def script_root(self) -> str: + """Alias for :attr:`self.root_path`. ``environ["SCRIPT_ROOT"]`` + without a trailing slash. + """ + return self.root_path + + @cached_property + def url_root(self) -> str: + """Alias for :attr:`root_url`. The URL with scheme, host, and + root path. For example, ``https://example.com/app/``. + """ + return self.root_url + + remote_user = environ_property[str]( + "REMOTE_USER", + doc="""If the server supports user authentication, and the + script is protected, this attribute contains the username the + user has authenticated as.""", + ) + is_multithread = environ_property[bool]( + "wsgi.multithread", + doc="""boolean that is `True` if the application is served by a + multithreaded WSGI server.""", + ) + is_multiprocess = environ_property[bool]( + "wsgi.multiprocess", + doc="""boolean that is `True` if the application is served by a + WSGI server that spawns multiple processes.""", + ) + is_run_once = environ_property[bool]( + "wsgi.run_once", + doc="""boolean that is `True` if the application will be + executed only once in a process lifetime. This is the case for + CGI for example, but it's not guaranteed that the execution only + happens one time.""", + ) + + # JSON + + #: A module or other object that has ``dumps`` and ``loads`` + #: functions that match the API of the built-in :mod:`json` module. + json_module = json + + @property + def json(self) -> t.Optional[t.Any]: + """The parsed JSON data if :attr:`mimetype` indicates JSON + (:mimetype:`application/json`, see :meth:`is_json`). + + Calls :meth:`get_json` with default arguments. + """ + return self.get_json() + + # Cached values for ``(silent=False, silent=True)``. Initialized + # with sentinel values. + _cached_json: t.Tuple[t.Any, t.Any] = (Ellipsis, Ellipsis) + + def get_json( + self, force: bool = False, silent: bool = False, cache: bool = True + ) -> t.Optional[t.Any]: + """Parse :attr:`data` as JSON. + + If the mimetype does not indicate JSON + (:mimetype:`application/json`, see :meth:`is_json`), this + returns ``None``. + + If parsing fails, :meth:`on_json_loading_failed` is called and + its return value is used as the return value. + + :param force: Ignore the mimetype and always try to parse JSON. + :param silent: Silence parsing errors and return ``None`` + instead. + :param cache: Store the parsed JSON to return for subsequent + calls. + """ + if cache and self._cached_json[silent] is not Ellipsis: + return self._cached_json[silent] + + if not (force or self.is_json): + return None + + data = self.get_data(cache=cache) + + try: + rv = self.json_module.loads(data) + except ValueError as e: + if silent: + rv = None + + if cache: + normal_rv, _ = self._cached_json + self._cached_json = (normal_rv, rv) + else: + rv = self.on_json_loading_failed(e) + + if cache: + _, silent_rv = self._cached_json + self._cached_json = (rv, silent_rv) + else: + if cache: + self._cached_json = (rv, rv) + + return rv + + def on_json_loading_failed(self, e: ValueError) -> t.Any: + """Called if :meth:`get_json` parsing fails and isn't silenced. + If this method returns a value, it is used as the return value + for :meth:`get_json`. The default implementation raises + :exc:`~werkzeug.exceptions.BadRequest`. + """ + raise BadRequest(f"Failed to decode JSON object: {e}") + + +class StreamOnlyMixin: + """Mixin to create a ``Request`` that disables the ``data``, + ``form``, and ``files`` properties. Only ``stream`` is available. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Create the request with + ``shallow=True`` instead. + + .. versionadded:: 0.9 + """ + + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'StreamOnlyMixin' is deprecated and will be removed in" + " Werkzeug 2.1. Create the request with 'shallow=True'" + " instead.", + DeprecationWarning, + stacklevel=2, + ) + kwargs["shallow"] = True + super().__init__(*args, **kwargs) # type: ignore + + +class PlainRequest(StreamOnlyMixin, Request): + """A request object without ``data``, ``form``, and ``files``. + + .. deprecated:: 2.0 + Will be removed in Werkzeug 2.1. Create the request with + ``shallow=True`` instead. + + .. versionadded:: 0.9 + """ + + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'PlainRequest' is deprecated and will be removed in" + " Werkzeug 2.1. Create the request with 'shallow=True'" + " instead.", + DeprecationWarning, + stacklevel=2, + ) + + # Don't show the DeprecationWarning for StreamOnlyMixin. + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + super().__init__(*args, **kwargs) diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/response.py b/venv/lib/python3.9/site-packages/werkzeug/wrappers/response.py new file mode 100644 index 0000000..a43c8bc --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wrappers/response.py @@ -0,0 +1,890 @@ +import json +import typing +import typing as t +import warnings +from http import HTTPStatus + +from .._internal import _to_bytes +from ..datastructures import Headers +from ..http import remove_entity_headers +from ..sansio.response import Response as _SansIOResponse +from ..urls import iri_to_uri +from ..urls import url_join +from ..utils import cached_property +from ..wsgi import ClosingIterator +from ..wsgi import get_current_url +from werkzeug._internal import _get_environ +from werkzeug.http import generate_etag +from werkzeug.http import http_date +from werkzeug.http import is_resource_modified +from werkzeug.http import parse_etags +from werkzeug.http import parse_range_header +from werkzeug.wsgi import _RangeWrapper + +if t.TYPE_CHECKING: + import typing_extensions as te + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +def _warn_if_string(iterable: t.Iterable) -> None: + """Helper for the response objects to check if the iterable returned + to the WSGI server is not a string. + """ + if isinstance(iterable, str): + warnings.warn( + "Response iterable was set to a string. This will appear to" + " work but means that the server will send the data to the" + " client one character at a time. This is almost never" + " intended behavior, use 'response.data' to assign strings" + " to the response object.", + stacklevel=2, + ) + + +def _iter_encoded( + iterable: t.Iterable[t.Union[str, bytes]], charset: str +) -> t.Iterator[bytes]: + for item in iterable: + if isinstance(item, str): + yield item.encode(charset) + else: + yield item + + +def _clean_accept_ranges(accept_ranges: t.Union[bool, str]) -> str: + if accept_ranges is True: + return "bytes" + elif accept_ranges is False: + return "none" + elif isinstance(accept_ranges, str): + return accept_ranges + raise ValueError("Invalid accept_ranges value") + + +class Response(_SansIOResponse): + """Represents an outgoing WSGI HTTP response with body, status, and + headers. Has properties and methods for using the functionality + defined by various HTTP specs. + + The response body is flexible to support different use cases. The + simple form is passing bytes, or a string which will be encoded as + UTF-8. Passing an iterable of bytes or strings makes this a + streaming response. A generator is particularly useful for building + a CSV file in memory or using SSE (Server Sent Events). A file-like + object is also iterable, although the + :func:`~werkzeug.utils.send_file` helper should be used in that + case. + + The response object is itself a WSGI application callable. When + called (:meth:`__call__`) with ``environ`` and ``start_response``, + it will pass its status and headers to ``start_response`` then + return its body as an iterable. + + .. code-block:: python + + from werkzeug.wrappers.response import Response + + def index(): + return Response("Hello, World!") + + def application(environ, start_response): + path = environ.get("PATH_INFO") or "/" + + if path == "/": + response = index() + else: + response = Response("Not Found", status=404) + + return response(environ, start_response) + + :param response: The data for the body of the response. A string or + bytes, or tuple or list of strings or bytes, for a fixed-length + response, or any other iterable of strings or bytes for a + streaming response. Defaults to an empty body. + :param status: The status code for the response. Either an int, in + which case the default status message is added, or a string in + the form ``{code} {message}``, like ``404 Not Found``. Defaults + to 200. + :param headers: A :class:`~werkzeug.datastructures.Headers` object, + or a list of ``(key, value)`` tuples that will be converted to a + ``Headers`` object. + :param mimetype: The mime type (content type without charset or + other parameters) of the response. If the value starts with + ``text/`` (or matches some other special cases), the charset + will be added to create the ``content_type``. + :param content_type: The full content type of the response. + Overrides building the value from ``mimetype``. + :param direct_passthrough: Pass the response body directly through + as the WSGI iterable. This can be used when the body is a binary + file or other iterator of bytes, to skip some unnecessary + checks. Use :func:`~werkzeug.utils.send_file` instead of setting + this manually. + + .. versionchanged:: 2.0 + Combine ``BaseResponse`` and mixins into a single ``Response`` + class. Using the old classes is deprecated and will be removed + in Werkzeug 2.1. + + .. versionchanged:: 0.5 + The ``direct_passthrough`` parameter was added. + """ + + #: if set to `False` accessing properties on the response object will + #: not try to consume the response iterator and convert it into a list. + #: + #: .. versionadded:: 0.6.2 + #: + #: That attribute was previously called `implicit_seqence_conversion`. + #: (Notice the typo). If you did use this feature, you have to adapt + #: your code to the name change. + implicit_sequence_conversion = True + + #: Should this response object correct the location header to be RFC + #: conformant? This is true by default. + #: + #: .. versionadded:: 0.8 + autocorrect_location_header = True + + #: Should this response object automatically set the content-length + #: header if possible? This is true by default. + #: + #: .. versionadded:: 0.8 + automatically_set_content_length = True + + #: The response body to send as the WSGI iterable. A list of strings + #: or bytes represents a fixed-length response, any other iterable + #: is a streaming response. Strings are encoded to bytes as UTF-8. + #: + #: Do not set to a plain string or bytes, that will cause sending + #: the response to be very inefficient as it will iterate one byte + #: at a time. + response: t.Union[t.Iterable[str], t.Iterable[bytes]] + + def __init__( + self, + response: t.Optional[ + t.Union[t.Iterable[bytes], bytes, t.Iterable[str], str] + ] = None, + status: t.Optional[t.Union[int, str, HTTPStatus]] = None, + headers: t.Optional[ + t.Union[ + t.Mapping[str, t.Union[str, int, t.Iterable[t.Union[str, int]]]], + t.Iterable[t.Tuple[str, t.Union[str, int]]], + ] + ] = None, + mimetype: t.Optional[str] = None, + content_type: t.Optional[str] = None, + direct_passthrough: bool = False, + ) -> None: + super().__init__( + status=status, + headers=headers, + mimetype=mimetype, + content_type=content_type, + ) + + #: Pass the response body directly through as the WSGI iterable. + #: This can be used when the body is a binary file or other + #: iterator of bytes, to skip some unnecessary checks. Use + #: :func:`~werkzeug.utils.send_file` instead of setting this + #: manually. + self.direct_passthrough = direct_passthrough + self._on_close: t.List[t.Callable[[], t.Any]] = [] + + # we set the response after the headers so that if a class changes + # the charset attribute, the data is set in the correct charset. + if response is None: + self.response = [] + elif isinstance(response, (str, bytes, bytearray)): + self.set_data(response) + else: + self.response = response + + def call_on_close(self, func: t.Callable[[], t.Any]) -> t.Callable[[], t.Any]: + """Adds a function to the internal list of functions that should + be called as part of closing down the response. Since 0.7 this + function also returns the function that was passed so that this + can be used as a decorator. + + .. versionadded:: 0.6 + """ + self._on_close.append(func) + return func + + def __repr__(self) -> str: + if self.is_sequence: + body_info = f"{sum(map(len, self.iter_encoded()))} bytes" + else: + body_info = "streamed" if self.is_streamed else "likely-streamed" + return f"<{type(self).__name__} {body_info} [{self.status}]>" + + @classmethod + def force_type( + cls, response: "Response", environ: t.Optional["WSGIEnvironment"] = None + ) -> "Response": + """Enforce that the WSGI response is a response object of the current + type. Werkzeug will use the :class:`Response` internally in many + situations like the exceptions. If you call :meth:`get_response` on an + exception you will get back a regular :class:`Response` object, even + if you are using a custom subclass. + + This method can enforce a given response type, and it will also + convert arbitrary WSGI callables into response objects if an environ + is provided:: + + # convert a Werkzeug response object into an instance of the + # MyResponseClass subclass. + response = MyResponseClass.force_type(response) + + # convert any WSGI application into a response object + response = MyResponseClass.force_type(response, environ) + + This is especially useful if you want to post-process responses in + the main dispatcher and use functionality provided by your subclass. + + Keep in mind that this will modify response objects in place if + possible! + + :param response: a response object or wsgi application. + :param environ: a WSGI environment object. + :return: a response object. + """ + if not isinstance(response, Response): + if environ is None: + raise TypeError( + "cannot convert WSGI application into response" + " objects without an environ" + ) + + from ..test import run_wsgi_app + + response = Response(*run_wsgi_app(response, environ)) + + response.__class__ = cls + return response + + @classmethod + def from_app( + cls, app: "WSGIApplication", environ: "WSGIEnvironment", buffered: bool = False + ) -> "Response": + """Create a new response object from an application output. This + works best if you pass it an application that returns a generator all + the time. Sometimes applications may use the `write()` callable + returned by the `start_response` function. This tries to resolve such + edge cases automatically. But if you don't get the expected output + you should set `buffered` to `True` which enforces buffering. + + :param app: the WSGI application to execute. + :param environ: the WSGI environment to execute against. + :param buffered: set to `True` to enforce buffering. + :return: a response object. + """ + from ..test import run_wsgi_app + + return cls(*run_wsgi_app(app, environ, buffered)) + + @typing.overload + def get_data(self, as_text: "te.Literal[False]" = False) -> bytes: + ... + + @typing.overload + def get_data(self, as_text: "te.Literal[True]") -> str: + ... + + def get_data(self, as_text: bool = False) -> t.Union[bytes, str]: + """The string representation of the response body. Whenever you call + this property the response iterable is encoded and flattened. This + can lead to unwanted behavior if you stream big data. + + This behavior can be disabled by setting + :attr:`implicit_sequence_conversion` to `False`. + + If `as_text` is set to `True` the return value will be a decoded + string. + + .. versionadded:: 0.9 + """ + self._ensure_sequence() + rv = b"".join(self.iter_encoded()) + + if as_text: + return rv.decode(self.charset) + + return rv + + def set_data(self, value: t.Union[bytes, str]) -> None: + """Sets a new string as response. The value must be a string or + bytes. If a string is set it's encoded to the charset of the + response (utf-8 by default). + + .. versionadded:: 0.9 + """ + # if a string is set, it's encoded directly so that we + # can set the content length + if isinstance(value, str): + value = value.encode(self.charset) + else: + value = bytes(value) + self.response = [value] + if self.automatically_set_content_length: + self.headers["Content-Length"] = str(len(value)) + + data = property( + get_data, + set_data, + doc="A descriptor that calls :meth:`get_data` and :meth:`set_data`.", + ) + + def calculate_content_length(self) -> t.Optional[int]: + """Returns the content length if available or `None` otherwise.""" + try: + self._ensure_sequence() + except RuntimeError: + return None + return sum(len(x) for x in self.iter_encoded()) + + def _ensure_sequence(self, mutable: bool = False) -> None: + """This method can be called by methods that need a sequence. If + `mutable` is true, it will also ensure that the response sequence + is a standard Python list. + + .. versionadded:: 0.6 + """ + if self.is_sequence: + # if we need a mutable object, we ensure it's a list. + if mutable and not isinstance(self.response, list): + self.response = list(self.response) # type: ignore + return + if self.direct_passthrough: + raise RuntimeError( + "Attempted implicit sequence conversion but the" + " response object is in direct passthrough mode." + ) + if not self.implicit_sequence_conversion: + raise RuntimeError( + "The response object required the iterable to be a" + " sequence, but the implicit conversion was disabled." + " Call make_sequence() yourself." + ) + self.make_sequence() + + def make_sequence(self) -> None: + """Converts the response iterator in a list. By default this happens + automatically if required. If `implicit_sequence_conversion` is + disabled, this method is not automatically called and some properties + might raise exceptions. This also encodes all the items. + + .. versionadded:: 0.6 + """ + if not self.is_sequence: + # if we consume an iterable we have to ensure that the close + # method of the iterable is called if available when we tear + # down the response + close = getattr(self.response, "close", None) + self.response = list(self.iter_encoded()) + if close is not None: + self.call_on_close(close) + + def iter_encoded(self) -> t.Iterator[bytes]: + """Iter the response encoded with the encoding of the response. + If the response object is invoked as WSGI application the return + value of this method is used as application iterator unless + :attr:`direct_passthrough` was activated. + """ + if __debug__: + _warn_if_string(self.response) + # Encode in a separate function so that self.response is fetched + # early. This allows us to wrap the response with the return + # value from get_app_iter or iter_encoded. + return _iter_encoded(self.response, self.charset) + + @property + def is_streamed(self) -> bool: + """If the response is streamed (the response is not an iterable with + a length information) this property is `True`. In this case streamed + means that there is no information about the number of iterations. + This is usually `True` if a generator is passed to the response object. + + This is useful for checking before applying some sort of post + filtering that should not take place for streamed responses. + """ + try: + len(self.response) # type: ignore + except (TypeError, AttributeError): + return True + return False + + @property + def is_sequence(self) -> bool: + """If the iterator is buffered, this property will be `True`. A + response object will consider an iterator to be buffered if the + response attribute is a list or tuple. + + .. versionadded:: 0.6 + """ + return isinstance(self.response, (tuple, list)) + + def close(self) -> None: + """Close the wrapped response if possible. You can also use the object + in a with statement which will automatically close it. + + .. versionadded:: 0.9 + Can now be used in a with statement. + """ + if hasattr(self.response, "close"): + self.response.close() # type: ignore + for func in self._on_close: + func() + + def __enter__(self) -> "Response": + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self.close() + + def freeze(self, no_etag: None = None) -> None: + """Make the response object ready to be pickled. Does the + following: + + * Buffer the response into a list, ignoring + :attr:`implicity_sequence_conversion` and + :attr:`direct_passthrough`. + * Set the ``Content-Length`` header. + * Generate an ``ETag`` header if one is not already set. + + .. versionchanged:: 2.0 + An ``ETag`` header is added, the ``no_etag`` parameter is + deprecated and will be removed in Werkzeug 2.1. + + .. versionchanged:: 0.6 + The ``Content-Length`` header is set. + """ + # Always freeze the encoded response body, ignore + # implicit_sequence_conversion and direct_passthrough. + self.response = list(self.iter_encoded()) + self.headers["Content-Length"] = str(sum(map(len, self.response))) + + if no_etag is not None: + warnings.warn( + "The 'no_etag' parameter is deprecated and will be" + " removed in Werkzeug 2.1.", + DeprecationWarning, + stacklevel=2, + ) + + self.add_etag() + + def get_wsgi_headers(self, environ: "WSGIEnvironment") -> Headers: + """This is automatically called right before the response is started + and returns headers modified for the given environment. It returns a + copy of the headers from the response with some modifications applied + if necessary. + + For example the location header (if present) is joined with the root + URL of the environment. Also the content length is automatically set + to zero here for certain status codes. + + .. versionchanged:: 0.6 + Previously that function was called `fix_headers` and modified + the response object in place. Also since 0.6, IRIs in location + and content-location headers are handled properly. + + Also starting with 0.6, Werkzeug will attempt to set the content + length if it is able to figure it out on its own. This is the + case if all the strings in the response iterable are already + encoded and the iterable is buffered. + + :param environ: the WSGI environment of the request. + :return: returns a new :class:`~werkzeug.datastructures.Headers` + object. + """ + headers = Headers(self.headers) + location: t.Optional[str] = None + content_location: t.Optional[str] = None + content_length: t.Optional[t.Union[str, int]] = None + status = self.status_code + + # iterate over the headers to find all values in one go. Because + # get_wsgi_headers is used each response that gives us a tiny + # speedup. + for key, value in headers: + ikey = key.lower() + if ikey == "location": + location = value + elif ikey == "content-location": + content_location = value + elif ikey == "content-length": + content_length = value + + # make sure the location header is an absolute URL + if location is not None: + old_location = location + if isinstance(location, str): + # Safe conversion is necessary here as we might redirect + # to a broken URI scheme (for instance itms-services). + location = iri_to_uri(location, safe_conversion=True) + + if self.autocorrect_location_header: + current_url = get_current_url(environ, strip_querystring=True) + if isinstance(current_url, str): + current_url = iri_to_uri(current_url) + location = url_join(current_url, location) + if location != old_location: + headers["Location"] = location + + # make sure the content location is a URL + if content_location is not None and isinstance(content_location, str): + headers["Content-Location"] = iri_to_uri(content_location) + + if 100 <= status < 200 or status == 204: + # Per section 3.3.2 of RFC 7230, "a server MUST NOT send a + # Content-Length header field in any response with a status + # code of 1xx (Informational) or 204 (No Content)." + headers.remove("Content-Length") + elif status == 304: + remove_entity_headers(headers) + + # if we can determine the content length automatically, we + # should try to do that. But only if this does not involve + # flattening the iterator or encoding of strings in the + # response. We however should not do that if we have a 304 + # response. + if ( + self.automatically_set_content_length + and self.is_sequence + and content_length is None + and status not in (204, 304) + and not (100 <= status < 200) + ): + try: + content_length = sum(len(_to_bytes(x, "ascii")) for x in self.response) + except UnicodeError: + # Something other than bytes, can't safely figure out + # the length of the response. + pass + else: + headers["Content-Length"] = str(content_length) + + return headers + + def get_app_iter(self, environ: "WSGIEnvironment") -> t.Iterable[bytes]: + """Returns the application iterator for the given environ. Depending + on the request method and the current status code the return value + might be an empty response rather than the one from the response. + + If the request method is `HEAD` or the status code is in a range + where the HTTP specification requires an empty response, an empty + iterable is returned. + + .. versionadded:: 0.6 + + :param environ: the WSGI environment of the request. + :return: a response iterable. + """ + status = self.status_code + if ( + environ["REQUEST_METHOD"] == "HEAD" + or 100 <= status < 200 + or status in (204, 304) + ): + iterable: t.Iterable[bytes] = () + elif self.direct_passthrough: + if __debug__: + _warn_if_string(self.response) + return self.response # type: ignore + else: + iterable = self.iter_encoded() + return ClosingIterator(iterable, self.close) + + def get_wsgi_response( + self, environ: "WSGIEnvironment" + ) -> t.Tuple[t.Iterable[bytes], str, t.List[t.Tuple[str, str]]]: + """Returns the final WSGI response as tuple. The first item in + the tuple is the application iterator, the second the status and + the third the list of headers. The response returned is created + specially for the given environment. For example if the request + method in the WSGI environment is ``'HEAD'`` the response will + be empty and only the headers and status code will be present. + + .. versionadded:: 0.6 + + :param environ: the WSGI environment of the request. + :return: an ``(app_iter, status, headers)`` tuple. + """ + headers = self.get_wsgi_headers(environ) + app_iter = self.get_app_iter(environ) + return app_iter, self.status, headers.to_wsgi_list() + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + """Process this response as WSGI application. + + :param environ: the WSGI environment. + :param start_response: the response callable provided by the WSGI + server. + :return: an application iterator + """ + app_iter, status, headers = self.get_wsgi_response(environ) + start_response(status, headers) + return app_iter + + # JSON + + #: A module or other object that has ``dumps`` and ``loads`` + #: functions that match the API of the built-in :mod:`json` module. + json_module = json + + @property + def json(self) -> t.Optional[t.Any]: + """The parsed JSON data if :attr:`mimetype` indicates JSON + (:mimetype:`application/json`, see :meth:`is_json`). + + Calls :meth:`get_json` with default arguments. + """ + return self.get_json() + + def get_json(self, force: bool = False, silent: bool = False) -> t.Optional[t.Any]: + """Parse :attr:`data` as JSON. Useful during testing. + + If the mimetype does not indicate JSON + (:mimetype:`application/json`, see :meth:`is_json`), this + returns ``None``. + + Unlike :meth:`Request.get_json`, the result is not cached. + + :param force: Ignore the mimetype and always try to parse JSON. + :param silent: Silence parsing errors and return ``None`` + instead. + """ + if not (force or self.is_json): + return None + + data = self.get_data() + + try: + return self.json_module.loads(data) + except ValueError: + if not silent: + raise + + return None + + # Stream + + @cached_property + def stream(self) -> "ResponseStream": + """The response iterable as write-only stream.""" + return ResponseStream(self) + + def _wrap_range_response(self, start: int, length: int) -> None: + """Wrap existing Response in case of Range Request context.""" + if self.status_code == 206: + self.response = _RangeWrapper(self.response, start, length) # type: ignore + + def _is_range_request_processable(self, environ: "WSGIEnvironment") -> bool: + """Return ``True`` if `Range` header is present and if underlying + resource is considered unchanged when compared with `If-Range` header. + """ + return ( + "HTTP_IF_RANGE" not in environ + or not is_resource_modified( + environ, + self.headers.get("etag"), + None, + self.headers.get("last-modified"), + ignore_if_range=False, + ) + ) and "HTTP_RANGE" in environ + + def _process_range_request( + self, + environ: "WSGIEnvironment", + complete_length: t.Optional[int] = None, + accept_ranges: t.Optional[t.Union[bool, str]] = None, + ) -> bool: + """Handle Range Request related headers (RFC7233). If `Accept-Ranges` + header is valid, and Range Request is processable, we set the headers + as described by the RFC, and wrap the underlying response in a + RangeWrapper. + + Returns ``True`` if Range Request can be fulfilled, ``False`` otherwise. + + :raises: :class:`~werkzeug.exceptions.RequestedRangeNotSatisfiable` + if `Range` header could not be parsed or satisfied. + + .. versionchanged:: 2.0 + Returns ``False`` if the length is 0. + """ + from ..exceptions import RequestedRangeNotSatisfiable + + if ( + accept_ranges is None + or complete_length is None + or complete_length == 0 + or not self._is_range_request_processable(environ) + ): + return False + + parsed_range = parse_range_header(environ.get("HTTP_RANGE")) + + if parsed_range is None: + raise RequestedRangeNotSatisfiable(complete_length) + + range_tuple = parsed_range.range_for_length(complete_length) + content_range_header = parsed_range.to_content_range_header(complete_length) + + if range_tuple is None or content_range_header is None: + raise RequestedRangeNotSatisfiable(complete_length) + + content_length = range_tuple[1] - range_tuple[0] + self.headers["Content-Length"] = content_length + self.headers["Accept-Ranges"] = accept_ranges + self.content_range = content_range_header # type: ignore + self.status_code = 206 + self._wrap_range_response(range_tuple[0], content_length) + return True + + def make_conditional( + self, + request_or_environ: "WSGIEnvironment", + accept_ranges: t.Union[bool, str] = False, + complete_length: t.Optional[int] = None, + ) -> "Response": + """Make the response conditional to the request. This method works + best if an etag was defined for the response already. The `add_etag` + method can be used to do that. If called without etag just the date + header is set. + + This does nothing if the request method in the request or environ is + anything but GET or HEAD. + + For optimal performance when handling range requests, it's recommended + that your response data object implements `seekable`, `seek` and `tell` + methods as described by :py:class:`io.IOBase`. Objects returned by + :meth:`~werkzeug.wsgi.wrap_file` automatically implement those methods. + + It does not remove the body of the response because that's something + the :meth:`__call__` function does for us automatically. + + Returns self so that you can do ``return resp.make_conditional(req)`` + but modifies the object in-place. + + :param request_or_environ: a request object or WSGI environment to be + used to make the response conditional + against. + :param accept_ranges: This parameter dictates the value of + `Accept-Ranges` header. If ``False`` (default), + the header is not set. If ``True``, it will be set + to ``"bytes"``. If ``None``, it will be set to + ``"none"``. If it's a string, it will use this + value. + :param complete_length: Will be used only in valid Range Requests. + It will set `Content-Range` complete length + value and compute `Content-Length` real value. + This parameter is mandatory for successful + Range Requests completion. + :raises: :class:`~werkzeug.exceptions.RequestedRangeNotSatisfiable` + if `Range` header could not be parsed or satisfied. + + .. versionchanged:: 2.0 + Range processing is skipped if length is 0 instead of + raising a 416 Range Not Satisfiable error. + """ + environ = _get_environ(request_or_environ) + if environ["REQUEST_METHOD"] in ("GET", "HEAD"): + # if the date is not in the headers, add it now. We however + # will not override an already existing header. Unfortunately + # this header will be overriden by many WSGI servers including + # wsgiref. + if "date" not in self.headers: + self.headers["Date"] = http_date() + accept_ranges = _clean_accept_ranges(accept_ranges) + is206 = self._process_range_request(environ, complete_length, accept_ranges) + if not is206 and not is_resource_modified( + environ, + self.headers.get("etag"), + None, + self.headers.get("last-modified"), + ): + if parse_etags(environ.get("HTTP_IF_MATCH")): + self.status_code = 412 + else: + self.status_code = 304 + if ( + self.automatically_set_content_length + and "content-length" not in self.headers + ): + length = self.calculate_content_length() + if length is not None: + self.headers["Content-Length"] = length + return self + + def add_etag(self, overwrite: bool = False, weak: bool = False) -> None: + """Add an etag for the current response if there is none yet. + + .. versionchanged:: 2.0 + SHA-1 is used to generate the value. MD5 may not be + available in some environments. + """ + if overwrite or "etag" not in self.headers: + self.set_etag(generate_etag(self.get_data()), weak) + + +class ResponseStream: + """A file descriptor like object used by the :class:`ResponseStreamMixin` to + represent the body of the stream. It directly pushes into the response + iterable of the response object. + """ + + mode = "wb+" + + def __init__(self, response: Response): + self.response = response + self.closed = False + + def write(self, value: bytes) -> int: + if self.closed: + raise ValueError("I/O operation on closed file") + self.response._ensure_sequence(mutable=True) + self.response.response.append(value) # type: ignore + self.response.headers.pop("Content-Length", None) + return len(value) + + def writelines(self, seq: t.Iterable[bytes]) -> None: + for item in seq: + self.write(item) + + def close(self) -> None: + self.closed = True + + def flush(self) -> None: + if self.closed: + raise ValueError("I/O operation on closed file") + + def isatty(self) -> bool: + if self.closed: + raise ValueError("I/O operation on closed file") + return False + + def tell(self) -> int: + self.response._ensure_sequence() + return sum(map(len, self.response.response)) + + @property + def encoding(self) -> str: + return self.response.charset + + +class ResponseStreamMixin: + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'ResponseStreamMixin' is deprecated and will be removed in" + " Werkzeug 2.1. 'Response' now includes the functionality" + " directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) # type: ignore diff --git a/venv/lib/python3.9/site-packages/werkzeug/wrappers/user_agent.py b/venv/lib/python3.9/site-packages/werkzeug/wrappers/user_agent.py new file mode 100644 index 0000000..184ffd0 --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wrappers/user_agent.py @@ -0,0 +1,14 @@ +import typing as t +import warnings + + +class UserAgentMixin: + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + warnings.warn( + "'UserAgentMixin' is deprecated and will be removed in" + " Werkzeug 2.1. 'Request' now includes the functionality" + " directly.", + DeprecationWarning, + stacklevel=2, + ) + super().__init__(*args, **kwargs) # type: ignore diff --git a/venv/lib/python3.9/site-packages/werkzeug/wsgi.py b/venv/lib/python3.9/site-packages/werkzeug/wsgi.py new file mode 100644 index 0000000..9439a1e --- /dev/null +++ b/venv/lib/python3.9/site-packages/werkzeug/wsgi.py @@ -0,0 +1,982 @@ +import io +import re +import typing as t +from functools import partial +from functools import update_wrapper +from itertools import chain + +from ._internal import _make_encode_wrapper +from ._internal import _to_bytes +from ._internal import _to_str +from .sansio import utils as _sansio_utils +from .sansio.utils import host_is_trusted # noqa: F401 # Imported as part of API +from .urls import _URLTuple +from .urls import uri_to_iri +from .urls import url_join +from .urls import url_parse +from .urls import url_quote + +if t.TYPE_CHECKING: + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +def responder(f: t.Callable[..., "WSGIApplication"]) -> "WSGIApplication": + """Marks a function as responder. Decorate a function with it and it + will automatically call the return value as WSGI application. + + Example:: + + @responder + def application(environ, start_response): + return Response('Hello World!') + """ + return update_wrapper(lambda *a: f(*a)(*a[-2:]), f) + + +def get_current_url( + environ: "WSGIEnvironment", + root_only: bool = False, + strip_querystring: bool = False, + host_only: bool = False, + trusted_hosts: t.Optional[t.Iterable[str]] = None, +) -> str: + """Recreate the URL for a request from the parts in a WSGI + environment. + + The URL is an IRI, not a URI, so it may contain Unicode characters. + Use :func:`~werkzeug.urls.iri_to_uri` to convert it to ASCII. + + :param environ: The WSGI environment to get the URL parts from. + :param root_only: Only build the root path, don't include the + remaining path or query string. + :param strip_querystring: Don't include the query string. + :param host_only: Only build the scheme and host. + :param trusted_hosts: A list of trusted host names to validate the + host against. + """ + parts = { + "scheme": environ["wsgi.url_scheme"], + "host": get_host(environ, trusted_hosts), + } + + if not host_only: + parts["root_path"] = environ.get("SCRIPT_NAME", "") + + if not root_only: + parts["path"] = environ.get("PATH_INFO", "") + + if not strip_querystring: + parts["query_string"] = environ.get("QUERY_STRING", "").encode("latin1") + + return _sansio_utils.get_current_url(**parts) + + +def _get_server( + environ: "WSGIEnvironment", +) -> t.Optional[t.Tuple[str, t.Optional[int]]]: + name = environ.get("SERVER_NAME") + + if name is None: + return None + + try: + port: t.Optional[int] = int(environ.get("SERVER_PORT", None)) + except (TypeError, ValueError): + # unix socket + port = None + + return name, port + + +def get_host( + environ: "WSGIEnvironment", trusted_hosts: t.Optional[t.Iterable[str]] = None +) -> str: + """Return the host for the given WSGI environment. + + The ``Host`` header is preferred, then ``SERVER_NAME`` if it's not + set. The returned host will only contain the port if it is different + than the standard port for the protocol. + + Optionally, verify that the host is trusted using + :func:`host_is_trusted` and raise a + :exc:`~werkzeug.exceptions.SecurityError` if it is not. + + :param environ: A WSGI environment dict. + :param trusted_hosts: A list of trusted host names. + + :return: Host, with port if necessary. + :raise ~werkzeug.exceptions.SecurityError: If the host is not + trusted. + """ + return _sansio_utils.get_host( + environ["wsgi.url_scheme"], + environ.get("HTTP_HOST"), + _get_server(environ), + trusted_hosts, + ) + + +def get_content_length(environ: "WSGIEnvironment") -> t.Optional[int]: + """Returns the content length from the WSGI environment as + integer. If it's not available or chunked transfer encoding is used, + ``None`` is returned. + + .. versionadded:: 0.9 + + :param environ: the WSGI environ to fetch the content length from. + """ + if environ.get("HTTP_TRANSFER_ENCODING", "") == "chunked": + return None + + content_length = environ.get("CONTENT_LENGTH") + if content_length is not None: + try: + return max(0, int(content_length)) + except (ValueError, TypeError): + pass + return None + + +def get_input_stream( + environ: "WSGIEnvironment", safe_fallback: bool = True +) -> t.BinaryIO: + """Returns the input stream from the WSGI environment and wraps it + in the most sensible way possible. The stream returned is not the + raw WSGI stream in most cases but one that is safe to read from + without taking into account the content length. + + If content length is not set, the stream will be empty for safety reasons. + If the WSGI server supports chunked or infinite streams, it should set + the ``wsgi.input_terminated`` value in the WSGI environ to indicate that. + + .. versionadded:: 0.9 + + :param environ: the WSGI environ to fetch the stream from. + :param safe_fallback: use an empty stream as a safe fallback when the + content length is not set. Disabling this allows infinite streams, + which can be a denial-of-service risk. + """ + stream = t.cast(t.BinaryIO, environ["wsgi.input"]) + content_length = get_content_length(environ) + + # A wsgi extension that tells us if the input is terminated. In + # that case we return the stream unchanged as we know we can safely + # read it until the end. + if environ.get("wsgi.input_terminated"): + return stream + + # If the request doesn't specify a content length, returning the stream is + # potentially dangerous because it could be infinite, malicious or not. If + # safe_fallback is true, return an empty stream instead for safety. + if content_length is None: + return io.BytesIO() if safe_fallback else stream + + # Otherwise limit the stream to the content length + return t.cast(t.BinaryIO, LimitedStream(stream, content_length)) + + +def get_query_string(environ: "WSGIEnvironment") -> str: + """Returns the ``QUERY_STRING`` from the WSGI environment. This also + takes care of the WSGI decoding dance. The string returned will be + restricted to ASCII characters. + + :param environ: WSGI environment to get the query string from. + + .. versionadded:: 0.9 + """ + qs = environ.get("QUERY_STRING", "").encode("latin1") + # QUERY_STRING really should be ascii safe but some browsers + # will send us some unicode stuff (I am looking at you IE). + # In that case we want to urllib quote it badly. + return url_quote(qs, safe=":&%=+$!*'(),") + + +def get_path_info( + environ: "WSGIEnvironment", charset: str = "utf-8", errors: str = "replace" +) -> str: + """Return the ``PATH_INFO`` from the WSGI environment and decode it + unless ``charset`` is ``None``. + + :param environ: WSGI environment to get the path from. + :param charset: The charset for the path info, or ``None`` if no + decoding should be performed. + :param errors: The decoding error handling. + + .. versionadded:: 0.9 + """ + path = environ.get("PATH_INFO", "").encode("latin1") + return _to_str(path, charset, errors, allow_none_charset=True) # type: ignore + + +def get_script_name( + environ: "WSGIEnvironment", charset: str = "utf-8", errors: str = "replace" +) -> str: + """Return the ``SCRIPT_NAME`` from the WSGI environment and decode + it unless `charset` is set to ``None``. + + :param environ: WSGI environment to get the path from. + :param charset: The charset for the path, or ``None`` if no decoding + should be performed. + :param errors: The decoding error handling. + + .. versionadded:: 0.9 + """ + path = environ.get("SCRIPT_NAME", "").encode("latin1") + return _to_str(path, charset, errors, allow_none_charset=True) # type: ignore + + +def pop_path_info( + environ: "WSGIEnvironment", charset: str = "utf-8", errors: str = "replace" +) -> t.Optional[str]: + """Removes and returns the next segment of `PATH_INFO`, pushing it onto + `SCRIPT_NAME`. Returns `None` if there is nothing left on `PATH_INFO`. + + If the `charset` is set to `None` bytes are returned. + + If there are empty segments (``'/foo//bar``) these are ignored but + properly pushed to the `SCRIPT_NAME`: + + >>> env = {'SCRIPT_NAME': '/foo', 'PATH_INFO': '/a/b'} + >>> pop_path_info(env) + 'a' + >>> env['SCRIPT_NAME'] + '/foo/a' + >>> pop_path_info(env) + 'b' + >>> env['SCRIPT_NAME'] + '/foo/a/b' + + .. versionadded:: 0.5 + + .. versionchanged:: 0.9 + The path is now decoded and a charset and encoding + parameter can be provided. + + :param environ: the WSGI environment that is modified. + :param charset: The ``encoding`` parameter passed to + :func:`bytes.decode`. + :param errors: The ``errors`` paramater passed to + :func:`bytes.decode`. + """ + path = environ.get("PATH_INFO") + if not path: + return None + + script_name = environ.get("SCRIPT_NAME", "") + + # shift multiple leading slashes over + old_path = path + path = path.lstrip("/") + if path != old_path: + script_name += "/" * (len(old_path) - len(path)) + + if "/" not in path: + environ["PATH_INFO"] = "" + environ["SCRIPT_NAME"] = script_name + path + rv = path.encode("latin1") + else: + segment, path = path.split("/", 1) + environ["PATH_INFO"] = f"/{path}" + environ["SCRIPT_NAME"] = script_name + segment + rv = segment.encode("latin1") + + return _to_str(rv, charset, errors, allow_none_charset=True) # type: ignore + + +def peek_path_info( + environ: "WSGIEnvironment", charset: str = "utf-8", errors: str = "replace" +) -> t.Optional[str]: + """Returns the next segment on the `PATH_INFO` or `None` if there + is none. Works like :func:`pop_path_info` without modifying the + environment: + + >>> env = {'SCRIPT_NAME': '/foo', 'PATH_INFO': '/a/b'} + >>> peek_path_info(env) + 'a' + >>> peek_path_info(env) + 'a' + + If the `charset` is set to `None` bytes are returned. + + .. versionadded:: 0.5 + + .. versionchanged:: 0.9 + The path is now decoded and a charset and encoding + parameter can be provided. + + :param environ: the WSGI environment that is checked. + """ + segments = environ.get("PATH_INFO", "").lstrip("/").split("/", 1) + if segments: + return _to_str( # type: ignore + segments[0].encode("latin1"), charset, errors, allow_none_charset=True + ) + return None + + +def extract_path_info( + environ_or_baseurl: t.Union[str, "WSGIEnvironment"], + path_or_url: t.Union[str, _URLTuple], + charset: str = "utf-8", + errors: str = "werkzeug.url_quote", + collapse_http_schemes: bool = True, +) -> t.Optional[str]: + """Extracts the path info from the given URL (or WSGI environment) and + path. The path info returned is a string. The URLs might also be IRIs. + + If the path info could not be determined, `None` is returned. + + Some examples: + + >>> extract_path_info('http://example.com/app', '/app/hello') + '/hello' + >>> extract_path_info('http://example.com/app', + ... 'https://example.com/app/hello') + '/hello' + >>> extract_path_info('http://example.com/app', + ... 'https://example.com/app/hello', + ... collapse_http_schemes=False) is None + True + + Instead of providing a base URL you can also pass a WSGI environment. + + :param environ_or_baseurl: a WSGI environment dict, a base URL or + base IRI. This is the root of the + application. + :param path_or_url: an absolute path from the server root, a + relative path (in which case it's the path info) + or a full URL. + :param charset: the charset for byte data in URLs + :param errors: the error handling on decode + :param collapse_http_schemes: if set to `False` the algorithm does + not assume that http and https on the + same server point to the same + resource. + + .. versionchanged:: 0.15 + The ``errors`` parameter defaults to leaving invalid bytes + quoted instead of replacing them. + + .. versionadded:: 0.6 + """ + + def _normalize_netloc(scheme: str, netloc: str) -> str: + parts = netloc.split("@", 1)[-1].split(":", 1) + port: t.Optional[str] + + if len(parts) == 2: + netloc, port = parts + if (scheme == "http" and port == "80") or ( + scheme == "https" and port == "443" + ): + port = None + else: + netloc = parts[0] + port = None + + if port is not None: + netloc += f":{port}" + + return netloc + + # make sure whatever we are working on is a IRI and parse it + path = uri_to_iri(path_or_url, charset, errors) + if isinstance(environ_or_baseurl, dict): + environ_or_baseurl = get_current_url(environ_or_baseurl, root_only=True) + base_iri = uri_to_iri(environ_or_baseurl, charset, errors) + base_scheme, base_netloc, base_path = url_parse(base_iri)[:3] + cur_scheme, cur_netloc, cur_path = url_parse(url_join(base_iri, path))[:3] + + # normalize the network location + base_netloc = _normalize_netloc(base_scheme, base_netloc) + cur_netloc = _normalize_netloc(cur_scheme, cur_netloc) + + # is that IRI even on a known HTTP scheme? + if collapse_http_schemes: + for scheme in base_scheme, cur_scheme: + if scheme not in ("http", "https"): + return None + else: + if not (base_scheme in ("http", "https") and base_scheme == cur_scheme): + return None + + # are the netlocs compatible? + if base_netloc != cur_netloc: + return None + + # are we below the application path? + base_path = base_path.rstrip("/") + if not cur_path.startswith(base_path): + return None + + return f"/{cur_path[len(base_path) :].lstrip('/')}" + + +class ClosingIterator: + """The WSGI specification requires that all middlewares and gateways + respect the `close` callback of the iterable returned by the application. + Because it is useful to add another close action to a returned iterable + and adding a custom iterable is a boring task this class can be used for + that:: + + return ClosingIterator(app(environ, start_response), [cleanup_session, + cleanup_locals]) + + If there is just one close function it can be passed instead of the list. + + A closing iterator is not needed if the application uses response objects + and finishes the processing if the response is started:: + + try: + return response(environ, start_response) + finally: + cleanup_session() + cleanup_locals() + """ + + def __init__( + self, + iterable: t.Iterable[bytes], + callbacks: t.Optional[ + t.Union[t.Callable[[], None], t.Iterable[t.Callable[[], None]]] + ] = None, + ) -> None: + iterator = iter(iterable) + self._next = t.cast(t.Callable[[], bytes], partial(next, iterator)) + if callbacks is None: + callbacks = [] + elif callable(callbacks): + callbacks = [callbacks] + else: + callbacks = list(callbacks) + iterable_close = getattr(iterable, "close", None) + if iterable_close: + callbacks.insert(0, iterable_close) + self._callbacks = callbacks + + def __iter__(self) -> "ClosingIterator": + return self + + def __next__(self) -> bytes: + return self._next() + + def close(self) -> None: + for callback in self._callbacks: + callback() + + +def wrap_file( + environ: "WSGIEnvironment", file: t.BinaryIO, buffer_size: int = 8192 +) -> t.Iterable[bytes]: + """Wraps a file. This uses the WSGI server's file wrapper if available + or otherwise the generic :class:`FileWrapper`. + + .. versionadded:: 0.5 + + If the file wrapper from the WSGI server is used it's important to not + iterate over it from inside the application but to pass it through + unchanged. If you want to pass out a file wrapper inside a response + object you have to set :attr:`Response.direct_passthrough` to `True`. + + More information about file wrappers are available in :pep:`333`. + + :param file: a :class:`file`-like object with a :meth:`~file.read` method. + :param buffer_size: number of bytes for one iteration. + """ + return environ.get("wsgi.file_wrapper", FileWrapper)( # type: ignore + file, buffer_size + ) + + +class FileWrapper: + """This class can be used to convert a :class:`file`-like object into + an iterable. It yields `buffer_size` blocks until the file is fully + read. + + You should not use this class directly but rather use the + :func:`wrap_file` function that uses the WSGI server's file wrapper + support if it's available. + + .. versionadded:: 0.5 + + If you're using this object together with a :class:`Response` you have + to use the `direct_passthrough` mode. + + :param file: a :class:`file`-like object with a :meth:`~file.read` method. + :param buffer_size: number of bytes for one iteration. + """ + + def __init__(self, file: t.BinaryIO, buffer_size: int = 8192) -> None: + self.file = file + self.buffer_size = buffer_size + + def close(self) -> None: + if hasattr(self.file, "close"): + self.file.close() + + def seekable(self) -> bool: + if hasattr(self.file, "seekable"): + return self.file.seekable() + if hasattr(self.file, "seek"): + return True + return False + + def seek(self, *args: t.Any) -> None: + if hasattr(self.file, "seek"): + self.file.seek(*args) + + def tell(self) -> t.Optional[int]: + if hasattr(self.file, "tell"): + return self.file.tell() + return None + + def __iter__(self) -> "FileWrapper": + return self + + def __next__(self) -> bytes: + data = self.file.read(self.buffer_size) + if data: + return data + raise StopIteration() + + +class _RangeWrapper: + # private for now, but should we make it public in the future ? + + """This class can be used to convert an iterable object into + an iterable that will only yield a piece of the underlying content. + It yields blocks until the underlying stream range is fully read. + The yielded blocks will have a size that can't exceed the original + iterator defined block size, but that can be smaller. + + If you're using this object together with a :class:`Response` you have + to use the `direct_passthrough` mode. + + :param iterable: an iterable object with a :meth:`__next__` method. + :param start_byte: byte from which read will start. + :param byte_range: how many bytes to read. + """ + + def __init__( + self, + iterable: t.Union[t.Iterable[bytes], t.BinaryIO], + start_byte: int = 0, + byte_range: t.Optional[int] = None, + ): + self.iterable = iter(iterable) + self.byte_range = byte_range + self.start_byte = start_byte + self.end_byte = None + + if byte_range is not None: + self.end_byte = start_byte + byte_range + + self.read_length = 0 + self.seekable = ( + hasattr(iterable, "seekable") and iterable.seekable() # type: ignore + ) + self.end_reached = False + + def __iter__(self) -> "_RangeWrapper": + return self + + def _next_chunk(self) -> bytes: + try: + chunk = next(self.iterable) + self.read_length += len(chunk) + return chunk + except StopIteration: + self.end_reached = True + raise + + def _first_iteration(self) -> t.Tuple[t.Optional[bytes], int]: + chunk = None + if self.seekable: + self.iterable.seek(self.start_byte) # type: ignore + self.read_length = self.iterable.tell() # type: ignore + contextual_read_length = self.read_length + else: + while self.read_length <= self.start_byte: + chunk = self._next_chunk() + if chunk is not None: + chunk = chunk[self.start_byte - self.read_length :] + contextual_read_length = self.start_byte + return chunk, contextual_read_length + + def _next(self) -> bytes: + if self.end_reached: + raise StopIteration() + chunk = None + contextual_read_length = self.read_length + if self.read_length == 0: + chunk, contextual_read_length = self._first_iteration() + if chunk is None: + chunk = self._next_chunk() + if self.end_byte is not None and self.read_length >= self.end_byte: + self.end_reached = True + return chunk[: self.end_byte - contextual_read_length] + return chunk + + def __next__(self) -> bytes: + chunk = self._next() + if chunk: + return chunk + self.end_reached = True + raise StopIteration() + + def close(self) -> None: + if hasattr(self.iterable, "close"): + self.iterable.close() # type: ignore + + +def _make_chunk_iter( + stream: t.Union[t.Iterable[bytes], t.BinaryIO], + limit: t.Optional[int], + buffer_size: int, +) -> t.Iterator[bytes]: + """Helper for the line and chunk iter functions.""" + if isinstance(stream, (bytes, bytearray, str)): + raise TypeError( + "Passed a string or byte object instead of true iterator or stream." + ) + if not hasattr(stream, "read"): + for item in stream: + if item: + yield item + return + stream = t.cast(t.BinaryIO, stream) + if not isinstance(stream, LimitedStream) and limit is not None: + stream = t.cast(t.BinaryIO, LimitedStream(stream, limit)) + _read = stream.read + while True: + item = _read(buffer_size) + if not item: + break + yield item + + +def make_line_iter( + stream: t.Union[t.Iterable[bytes], t.BinaryIO], + limit: t.Optional[int] = None, + buffer_size: int = 10 * 1024, + cap_at_buffer: bool = False, +) -> t.Iterator[bytes]: + """Safely iterates line-based over an input stream. If the input stream + is not a :class:`LimitedStream` the `limit` parameter is mandatory. + + This uses the stream's :meth:`~file.read` method internally as opposite + to the :meth:`~file.readline` method that is unsafe and can only be used + in violation of the WSGI specification. The same problem applies to the + `__iter__` function of the input stream which calls :meth:`~file.readline` + without arguments. + + If you need line-by-line processing it's strongly recommended to iterate + over the input stream using this helper function. + + .. versionchanged:: 0.8 + This function now ensures that the limit was reached. + + .. versionadded:: 0.9 + added support for iterators as input stream. + + .. versionadded:: 0.11.10 + added support for the `cap_at_buffer` parameter. + + :param stream: the stream or iterate to iterate over. + :param limit: the limit in bytes for the stream. (Usually + content length. Not necessary if the `stream` + is a :class:`LimitedStream`. + :param buffer_size: The optional buffer size. + :param cap_at_buffer: if this is set chunks are split if they are longer + than the buffer size. Internally this is implemented + that the buffer size might be exhausted by a factor + of two however. + """ + _iter = _make_chunk_iter(stream, limit, buffer_size) + + first_item = next(_iter, "") + if not first_item: + return + + s = _make_encode_wrapper(first_item) + empty = t.cast(bytes, s("")) + cr = t.cast(bytes, s("\r")) + lf = t.cast(bytes, s("\n")) + crlf = t.cast(bytes, s("\r\n")) + + _iter = t.cast(t.Iterator[bytes], chain((first_item,), _iter)) + + def _iter_basic_lines() -> t.Iterator[bytes]: + _join = empty.join + buffer: t.List[bytes] = [] + while True: + new_data = next(_iter, "") + if not new_data: + break + new_buf: t.List[bytes] = [] + buf_size = 0 + for item in t.cast( + t.Iterator[bytes], chain(buffer, new_data.splitlines(True)) + ): + new_buf.append(item) + buf_size += len(item) + if item and item[-1:] in crlf: + yield _join(new_buf) + new_buf = [] + elif cap_at_buffer and buf_size >= buffer_size: + rv = _join(new_buf) + while len(rv) >= buffer_size: + yield rv[:buffer_size] + rv = rv[buffer_size:] + new_buf = [rv] + buffer = new_buf + if buffer: + yield _join(buffer) + + # This hackery is necessary to merge 'foo\r' and '\n' into one item + # of 'foo\r\n' if we were unlucky and we hit a chunk boundary. + previous = empty + for item in _iter_basic_lines(): + if item == lf and previous[-1:] == cr: + previous += item + item = empty + if previous: + yield previous + previous = item + if previous: + yield previous + + +def make_chunk_iter( + stream: t.Union[t.Iterable[bytes], t.BinaryIO], + separator: bytes, + limit: t.Optional[int] = None, + buffer_size: int = 10 * 1024, + cap_at_buffer: bool = False, +) -> t.Iterator[bytes]: + """Works like :func:`make_line_iter` but accepts a separator + which divides chunks. If you want newline based processing + you should use :func:`make_line_iter` instead as it + supports arbitrary newline markers. + + .. versionadded:: 0.8 + + .. versionadded:: 0.9 + added support for iterators as input stream. + + .. versionadded:: 0.11.10 + added support for the `cap_at_buffer` parameter. + + :param stream: the stream or iterate to iterate over. + :param separator: the separator that divides chunks. + :param limit: the limit in bytes for the stream. (Usually + content length. Not necessary if the `stream` + is otherwise already limited). + :param buffer_size: The optional buffer size. + :param cap_at_buffer: if this is set chunks are split if they are longer + than the buffer size. Internally this is implemented + that the buffer size might be exhausted by a factor + of two however. + """ + _iter = _make_chunk_iter(stream, limit, buffer_size) + + first_item = next(_iter, b"") + if not first_item: + return + + _iter = t.cast(t.Iterator[bytes], chain((first_item,), _iter)) + if isinstance(first_item, str): + separator = _to_str(separator) + _split = re.compile(f"({re.escape(separator)})").split + _join = "".join + else: + separator = _to_bytes(separator) + _split = re.compile(b"(" + re.escape(separator) + b")").split + _join = b"".join + + buffer: t.List[bytes] = [] + while True: + new_data = next(_iter, b"") + if not new_data: + break + chunks = _split(new_data) + new_buf: t.List[bytes] = [] + buf_size = 0 + for item in chain(buffer, chunks): + if item == separator: + yield _join(new_buf) + new_buf = [] + buf_size = 0 + else: + buf_size += len(item) + new_buf.append(item) + + if cap_at_buffer and buf_size >= buffer_size: + rv = _join(new_buf) + while len(rv) >= buffer_size: + yield rv[:buffer_size] + rv = rv[buffer_size:] + new_buf = [rv] + buf_size = len(rv) + + buffer = new_buf + if buffer: + yield _join(buffer) + + +class LimitedStream(io.IOBase): + """Wraps a stream so that it doesn't read more than n bytes. If the + stream is exhausted and the caller tries to get more bytes from it + :func:`on_exhausted` is called which by default returns an empty + string. The return value of that function is forwarded + to the reader function. So if it returns an empty string + :meth:`read` will return an empty string as well. + + The limit however must never be higher than what the stream can + output. Otherwise :meth:`readlines` will try to read past the + limit. + + .. admonition:: Note on WSGI compliance + + calls to :meth:`readline` and :meth:`readlines` are not + WSGI compliant because it passes a size argument to the + readline methods. Unfortunately the WSGI PEP is not safely + implementable without a size argument to :meth:`readline` + because there is no EOF marker in the stream. As a result + of that the use of :meth:`readline` is discouraged. + + For the same reason iterating over the :class:`LimitedStream` + is not portable. It internally calls :meth:`readline`. + + We strongly suggest using :meth:`read` only or using the + :func:`make_line_iter` which safely iterates line-based + over a WSGI input stream. + + :param stream: the stream to wrap. + :param limit: the limit for the stream, must not be longer than + what the string can provide if the stream does not + end with `EOF` (like `wsgi.input`) + """ + + def __init__(self, stream: t.BinaryIO, limit: int) -> None: + self._read = stream.read + self._readline = stream.readline + self._pos = 0 + self.limit = limit + + def __iter__(self) -> "LimitedStream": + return self + + @property + def is_exhausted(self) -> bool: + """If the stream is exhausted this attribute is `True`.""" + return self._pos >= self.limit + + def on_exhausted(self) -> bytes: + """This is called when the stream tries to read past the limit. + The return value of this function is returned from the reading + function. + """ + # Read null bytes from the stream so that we get the + # correct end of stream marker. + return self._read(0) + + def on_disconnect(self) -> bytes: + """What should happen if a disconnect is detected? The return + value of this function is returned from read functions in case + the client went away. By default a + :exc:`~werkzeug.exceptions.ClientDisconnected` exception is raised. + """ + from .exceptions import ClientDisconnected + + raise ClientDisconnected() + + def exhaust(self, chunk_size: int = 1024 * 64) -> None: + """Exhaust the stream. This consumes all the data left until the + limit is reached. + + :param chunk_size: the size for a chunk. It will read the chunk + until the stream is exhausted and throw away + the results. + """ + to_read = self.limit - self._pos + chunk = chunk_size + while to_read > 0: + chunk = min(to_read, chunk) + self.read(chunk) + to_read -= chunk + + def read(self, size: t.Optional[int] = None) -> bytes: + """Read `size` bytes or if size is not provided everything is read. + + :param size: the number of bytes read. + """ + if self._pos >= self.limit: + return self.on_exhausted() + if size is None or size == -1: # -1 is for consistence with file + size = self.limit + to_read = min(self.limit - self._pos, size) + try: + read = self._read(to_read) + except (OSError, ValueError): + return self.on_disconnect() + if to_read and len(read) != to_read: + return self.on_disconnect() + self._pos += len(read) + return read + + def readline(self, size: t.Optional[int] = None) -> bytes: + """Reads one line from the stream.""" + if self._pos >= self.limit: + return self.on_exhausted() + if size is None: + size = self.limit - self._pos + else: + size = min(size, self.limit - self._pos) + try: + line = self._readline(size) + except (ValueError, OSError): + return self.on_disconnect() + if size and not line: + return self.on_disconnect() + self._pos += len(line) + return line + + def readlines(self, size: t.Optional[int] = None) -> t.List[bytes]: + """Reads a file into a list of strings. It calls :meth:`readline` + until the file is read to the end. It does support the optional + `size` argument if the underlying stream supports it for + `readline`. + """ + last_pos = self._pos + result = [] + if size is not None: + end = min(self.limit, last_pos + size) + else: + end = self.limit + while True: + if size is not None: + size -= last_pos - self._pos + if self._pos >= end: + break + result.append(self.readline(size)) + if size is not None: + last_pos = self._pos + return result + + def tell(self) -> int: + """Returns the position of the stream. + + .. versionadded:: 0.9 + """ + return self._pos + + def __next__(self) -> bytes: + line = self.readline() + if not line: + raise StopIteration() + return line + + def readable(self) -> bool: + return True diff --git a/venv/pyvenv.cfg b/venv/pyvenv.cfg index 853404e..5c102c1 100644 --- a/venv/pyvenv.cfg +++ b/venv/pyvenv.cfg @@ -1,3 +1,3 @@ home = /usr/bin include-system-site-packages = false -version = 3.8.10 +version = 3.9.2 diff --git a/venv/requirements.txt b/venv/requirements.txt new file mode 100644 index 0000000..5c8c61b --- /dev/null +++ b/venv/requirements.txt @@ -0,0 +1 @@ +flask==1.0.2 \ No newline at end of file diff --git a/venv/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl b/venv/share/python-wheels/CacheControl-0.12.6-py2.py3-none-any.whl index adbd56e9cabd2cc2f8b3f46ad5e4a404a13c933b..3a4ecd11ae5ad3f627b7f67fca59f3ed3574f2d3 100644 GIT binary patch delta 6911 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 delta 11550 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 Itp0iaKg|Qp$N&HU diff --git a/venv/share/python-wheels/appdirs-1.4.3-py2.py3-none-any.whl b/venv/share/python-wheels/appdirs-1.4.3-py2.py3-none-any.whl deleted file mode 100644 index 8074a16d4c98b06654e53cb747c8ecb3f89a385a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18776 zcmaI7Ly#~`tTjBgZQHhO+qP}nwmtKVZQHhOoBw;O{>}XscaiGqO*&Ocx=%VM3evzJ zC;$Ke5CCxyHA<|VnN>%%^(~JLO&xB#Y?6A^$|IFE{$JV9s#Rsrp;2^BU3QEzVACj;$!i7JPL$+%wO|I z^7Q`SKTpy4#o1fYZ|Lj`JMi}Uxk}uRdE@g`gA4rhd+{xHq?+YLyjFEY$lPuW`0+4?+MmzAPcRhIGvsWdn-0`7A zX80b|K>S6nYJG?Hi>O${me~imjhiesfc%l)FXC%dzESBsosMj^HdR!sM=^Fq)>klQ zu^x+#xaT|UN}*cZE0=aP5nn>NB+M|nyi0WP*gJ)@gDTddF#hp<-tYI4MllzS8l?@E z00QP}tF9xeF1>0y?&N!<)~Xs)VTVN^1uDG}w>g?rdzGYDMsa&)IeeTSeoWh_Trb6^ z?W)$XfzrNcS24l5g~qziy>s6B=cIts5}ky^Zrbw;|Mc`^BRIexj$N35loId-bW}Q@ z7nXVt=EELyyj#ofj&ve= zRs$UK|IC%wtMCkGp)y%Mdx8DOoS6ysG_I(7z~GYUCrIv9%fLa}1~3hlu%~>B8D`!3_WC(-d7EODH(JHU(#>c2 zuzGqMG%BZ(dZM=obKkW(>`F~#hkHKJG?;pM6gAFV%hJ8Hy-g!FEtGMz>{=rAu=3Gb z93*U$J_KOvb}PVW{A*;!E+sU3a(Z2hxwLDF-?(VGXjEWK*vZPQ6Sqs!8;f#F9O{xcGRBNT= z$na%^OiN*}z=qHGzs@^qPs;?&@pAKce}A8!-vj%7&>rDoul-=He9SiIT%Q*$V^#Ac zsA&BWC-CaTp9u;gI;*@Ys?Kvn%JL04+k=7H7#B|J(gI=~ebWSwcvbVH z$yze?3fWlEWc23*Hha`70(8L;-ATX-DUg}~rFC9u-1sJJ_?2hg8CdL_;%;rwRgxYF zQ=eNTqZ3WJtg&!)-*$~-pvRRQfWSeIFru>0cbGzjK-nh;LEqG*Z{p(R%XCQ}#a!)D z%5E}#q0DSt6lqb@nqui%tjEXa)pU)y#~t2K{cw8_0e1y51xr*Aj+7zNR#TY}>;&-{ zUJMW#G3bJ+#11x|n}E=OKPy9 zvS3~+8+gT9@SMmj%IQ!!gHcUI_gwtnf1~w`J1m1#4ZKmfr4AEPRm?cub`)**Ho*?l zwksusVZgZ*Ey2$hE+B4Mj{R2Cu^=n1fUmEhCx5L;kv(eBG%Umtq|OF#$-L497dX|z5@+wok6LZ+%jRqVxsSI!%FRYi%O>0zC8`G9Up*G-Wv`P0qpzD$15jpXuDMT!vn_qi+)O27SyK zj_?iq4TZoVJ77{OR?0of&uof;@Mm3;_x;h%3!wn$ZaR|}fg&Y;va0uaF$X5>d9>Sk zMXHM1sPv^lDa(Q`jePOf3SUBr_;&*MbJpFP2&paCQm_RV?H%z|o`9nHRMI?v^Ck`O z?6(@rqU~bbv;=GlTD}9S=kaa zH=c9F@nKas)YI>ovz8$z-4V0gGxR7^)E`4P=@Y1_9XS zOcd>WiW4>latb#E8)_P*j8$1W0PO_;DK$c9w%$AHXZk%hum_YL`sH=JaaHo;+X^0K z9SF)_p{)7K3=}jL&cb17iO6%HmSAipv)2Y9R?zIj^ToGA7B&~5?4#tPFJmNl$oHqDShjRZn1P@(dfWmEYDoNHU_~*qkvUO z?G3d%A-+wk+VI1bsA2V$h}F*Jva)g6v7AV`_aN^z^OP=qhlbRgI_nnNlleW*4M5km zYG%xiQRzzrX0^%G1?8@?WdFRRD03lMsydYG>}SmtWp2QhuLG2@da@VeiZNvBhpHeC1&Q%kbB#U?!G7HtB8r}k|YDGfyb@> z3h2`h=4eV67Jp2{d53?JLjbSF)=GX|d?10VVPSdLx`kV)tL^G;%s0#g__-6%a_|wU zCFBU@GI+X%7F@;Hk6_G)PSY7i;J@v`dNvm3<;4E)3Cx0T2oerYHsO*GB9BnN;?AHi zmzp%7cq$pU7$Kt8fS7sVlYR(m$qbS(;7C^P`B0l^wk)96Iat$w1+J( z8OyVsYUXZ$Mt8B19n|}qOKs3UalQq8VwdNjU^C1~g?HNAN7(op3`fH3vt?w;#y?z| zMp=Yq&guIm!{yWg)Jaq>yi@MPL zZrM+)pS(8MH>1BULL;$NFA(n#z{D}N3)E$ORYP>LS~0dKSjmhB;u2pgg19d_-a9Xu zW+j81;}3y&Qn9nN;IcCYb56$@iE+_RiLnQ5u z{y+SKLM8JPrq{4j6wpOowfS@0Xh|~N35GLUWcq?{QI09Tgczk`i=!6IS($7iuNK=w zOpS{&`NI5NOTuOc&TmT85eQ!BMuC-|s7Dc>mht?4T_oQ$8ljgW=Ye-EX(7* z)Gc-{&nO0AG0cR?aCl*LD&&n!yA^xCr=p`34FaI)$APm}6CCpsx#7PU8}sAAU1dr=8ZtCIx`Gy#oBkHUi;R&Md~?y0 zBJP$AK?9J`T3>`8CXLBY&;=qL&HX`FcmG}PibE&E1ojm@HcOSw!By-lF`B}%A=|Fj zW1>@y>(GpruyT0Dfuwp-*PRs$lgA@iQ!Svu$9T}zjkS6VHc4V@9wT_L5HI0b%XS!1 zx0cUT8i$}~Khj*8nM(Es2T?_+`=q{x?=01GB@V^FoVIBkTZXULD)c>j!s+-Gt!Xh;#nw+ao>8sU7it zB-*o?&9FMGeRDF-z}{!$ZTr^yy$Il|%hJl3XhfCGyWcN+pNsc`CL^ULtmB!_#f^v2 z(c*Byh_$V5&NO!_@r)~jZu&>|ggQ>VM=Eo|YS*LHl0QnR@&iLp9CxhMcGFjFh-(^j zo79`W*8^l_4duT4tR4DXn;dIItd{pD4yt4iCF)SW=ruKXKH%C^a+&XFKv^eZ+}$Lw z{of_1h3ue0HzMo|TNK4kO0Lw)bX4$RG3@{dg`KMpZ01VYtxue7O1tNWPx+X(cuYxB z==YhyPCG@nShbi*R}Dx_R80%W&`r6w|+ zrl-23iMydpRRu4UmYY{8Y5D+0~7Y*v$f=@u#CU^t<`qOeHvc|LvM51^;3rbX*eN#^ooO;E(zY~A*! zotFF4x#)z%il`z5csl9Q_9>{)AVm-bQf;{3r#GA-Q+#K9h`)63qI)2(V0jcaC@m^+ zZib4k2)D^}h@e}jaikwjsWzg26vIPayElANl_mMsEOJD!xA^0SFavBj6 z0b@Hld?u(ejdpl=WPo-KC8CPP&{M}Hz~Q(II&@+qZzzag{G43eTl5{*idxndbzkpf z{C$<^?_#hnC{aa#<%PoV%&ZXXz%ss*MyUD^m|7Km`>J%AEFYpLP-iea`d~4IE9Boh zp|!w6_o(v8s-dzyTL~FzPmhNmVvlNC7AO#1n{(>q?G_(@(>s=6L zY30xpv?`W*R7;cW?dqRa>Q4;v`AGmU1n8DbMV%r3>Ta5KC8QS8u70HAc1$Tlr{a)N zXuilVnDJ#x(bZS=;RJBzA}I4>VqR+_xGNR2!h!1g-p5EPLY}uJjxlIxn0K-SvADC@ zjgi<$s|9ESWR3W^D}8e#9Qc#Rd%tqwD+A4 zB2dLs!d23u3&YyW`?Zf88~T$eWAgAWCR!kmIv86;AvkrU$vZBgYAloiBHQZkNxovT z3CV%D5e)QB#uqY$3`eN5Il0j%1>!K;-b&nIGR=ZBA-ZNq6kr3{P?7$52oRI~@;8Zhg~0+^4r3!8E(#^($h?}+CP zn!=ole{^*g7@VS3|7V+Q27$(C()PcC0^swZiZ38)M^G_r&Oq_!#i9kVG-L@GM*{Me z=XxI+GUKO@_-gPgJ7(Cm-dk!%(ROq&5dvh1fEREL8b2Vf(k`OwZ#oj<*>ITJ=Y1)p z30rqv?J!w1A+l(h^T1rS4@!M5T4M_fj`d=HntyMsIZnts&oO!PCO}D?k@mLcr@=Yh zN-V1y8dS+djy{hLZ>6;=HB=e+u<$!B`#eC2Bh1zp3?ZdP3rs=08IGgS$uOFY@oGZL zmg}$zfLq5UkTXBs)~Yfr=(qdnp*9i)z!y_5YqU`559>6)fwiV}6 z$JNOj0`iJ&7B0j_y)c|{n0-*h(&tjn=8u;2jEP8O;g)73qgWbT*YJ%Qh3_%t6xz*1xyAH`;y6?248y-wVJO>m@LTH_f7dHjlZ;gxy+l@#$<@*J2 zp=8&!%9ugW$PoY-OR=XUW3V*Ajix%M-OaQx*9*hFK^l};s6AT=tP<<7Tzo@Wxzl3s z8`!$#YcXN<=_Q7^D?;)KS5n(r@{qoIK~Y-*H$@aa9eODt-)@y2LEgpRWsUU}-Ta+F zo&v8lg2SZ=`awt5;kx0Y2`s#pzdl_kq z0Z{#NCd$Zjb_E(Bz6Lz$3dE{hB*>5~=SE`-*nOdR@2AH%0-{86k}{T8q&0A))`L+W zJArs<$DrE5l$A?VT1d#$*09gt*2JPym0#HOB)C4FEi=}4>3UP(Li?)m|M>yS?IFOJ zyE+4WoIc?*uH^q|dJq!P`}`6QH6Dlc!+deO^u3D+{5dJ#gDP$8R^CuWz?hJHJD0R} zaL>P0)vn40JdBe>>=2Tcy&W}#%m4eKfY*hmal0SM;M#6Oxr*1?%L7fTc z# z)DoIy-5S{U0Lc^$G5i47$MjT-liPOlQIyLp?tfN+_#}f(#o}na=oc?~ zcfhG5n45V3!*Sk@b6%H#^|V-b;!^+(*?865({gLN`tEHouu^Z~eS4Ram&fP%ef%X3 zAC@CLcMl-u;`jZtksLk-{{V6!?6DrAr*7T&labSnOv6p8{Y~iTLV?5@M9=ra!n*uQ z$!g;B?-bq9rBvsiskCeV*h#`u4R|fphBm52YDj*Pr}8?5YKXc_W%A7AY-`-qJi-il zo2^k7Vxj?a?Z{(Qge$x)T%$UaD@>y`;6dTf5t{TCjA{+JgAL zf`nB=)D%-T2;-iWouN>6WW&-uz!8l?eA&Wm8-~L(IsGunNQJ~D^{_6wOGwTnO|q(C z1;rHZu(xvhkRc$%U6y;Xm;d9rO&!&g?0tFK!VZ~&0@VqM3feW#99Dg+m_T|1ds^7>>ma|G~X5+;x8(NmBnCHaJ zGhOzm(%y`#rgfhAn9nBtFx}{^XPA{Gq=D5VPka}bg)uE76SYY<0#iffQEY*|Q+Rh;NA%ng3?HI&_hX!^l zQlp-l-o~D=C@yU)-ZQ}Lo|wKhd#!fc2}OHpNtu{_>|NxpMTb3H>)U@ARZ`;@TY#>% zw6+0kd1Eo1=XC(~sqRqIt87W{Ro}V#4=AxL#-u-}A&Am=guX)+I?Ot~1ijkN!UU-t zUH}T3zT~SK)SQy<55~PBboR?gM}Uq$KsO6p`>-pl@`L#NTztMBpZo4Tt24~ejyyaG z)KNyLuiG1kQQQLSpivdl4)*x63Tz;&nme~M8U1+_5O-^1u` zpwu?iLG|%fNNptjYC<<`!%K_exsa%mmkNJ{GAu1sQF(%}Z_*Kbqz#p9J?X$Q>?ket zxuc5~&~co<(>oTB5*M%}edAXE5X*?3Uf|CS^F;y?8(XxdoYjkK`F|$}!Fn_IX(lT6z9<&WDG3%|-G$iE!yS|*C ziAw*KPpkIyKU_+O=glm&Tdx1&L?FjasjKgMan)Jli&7ges2lKZdaiHM{4Lr@_jnQq zz@tYt-B?nJx^`)0*fEsd*{H`ojf6arzRDtbww<43TWY2QO_m?tmY`?)O|S9{)pvD> zqe|x97>;YK>v8RU*B+xO--*)gb5?QZ-h%fg%1Dmr5_mAfPqqN<41nO+haW(C2=aVV ziHmIul3%At`>@*HQau?`7YW!W8(>{VIIkAno)5Y=ap`$m;2UU)|%%Y*G#%#4eoHSKwVwd0OA zOfWlaM)RiOXd<+AvGrc9D;aQ)ePw0W;|gmmA6gw274zb~cFl(toW--PiE8X+vnECB ztW(uT%P3Ey!lQQ*@YlLNyyYiz>kb6!xY3**>OEN=V(n<(!0n-Y<=c`kTIb)qA?&(s z;ElR4-;OioqTGNwLK74*FDm3})Tui&$})(RkKpN8GJ9lFJ#86_H)gIx;mM zuBFumj{sNQA@}T@n7eu_us2b;;`nsgoXP@?bH$9=^0I!sE4OIhCrv`~2VZJrgNz zy#B(A=A1orxXDTSK+7Q2>&)j5gSUH6NbloUqb?3sKd7>&)3w=I#!gOmKHwUnJAyea zi~j8s3N9M|gySzXx>sot!7^X2vH)0dCHYOuY-ez;wuEqa+FEa9zE~N`%i-tY@^9GA zJte@jAq(}ZNHD*|4UXQV9-u|k6BCE_9-V59V;X3M#v?0A5AklS@t_lSj#*HV4hz;)v@#Wf#bngu>GOf@1xRQP`&EE&MxGpm=G)O@W1PJ zxnT(TvpVm0H}`aYoxl5~yE-~Pz52E?w(MS&e~@eL%-wK1uTPAr=U~M92gZWyFo9oh zp_=dKJ&sqc8irdcJ{u& zOTyTZYwIV%Oc!R^#c0m;D4;w5`b%sOUG?_{S-n+AA8sm!zHOkosy|+osgSuTfpONf z9<~+8Ho-<;_9u~HK{CPoN*ob>v`L8$%1 zBtpO-{H2Qh^$M=^b5Gmb0`lHl^QSnP$jjrotA>?!@pKTk5zXMQ+ zxT5o|wYY}?X_wWuDgV|gt%4s~(-~0M+9YVmbu7%2nREOT+ z(hxLYZ?1G+(VKFQY%s&-S>^x%s3aj8Nz>NZDu0z z_y+l%Sj8-2R?dJJ{ZyNC8y}4r{&i_<$l#;aVIa`Q<&{q%)Ox_{9h|LB$N%u`}2zb z0U9v-9Clp{b`N@;1huj~wCCXo-~Sh%|L?Bvr#%0U^z)*{q>~-N+ zg{{S!{6mj4UIthgal}MAfR}Aq@nm5J1Xuci7>W9CgiXD-@Qb0WnuU@JMX~PS4wPcS z!m%s5-CJrB;IY*6<;&nz33#0XMun`4G(Cl%}FOW$kd(*(m;*TnNyy z_&RGH&|<<9y$vbj{_#ZrQA^zE%_g06{qKOZdbA2aVeYhhct2W&?!1w8p@ns;+ddJ@ zNj&i#9?-h*w>d6;@SWp6so_d>E@_o%xr!^waG-0#@`I}&?=1&<|LB}IQhpodSCgvnNgh%3_sg4n4B5Zhu_bx5gs z8bilJc1P+_xX5Qolb9$n7Kt`YWCR-&LuoiC%N6OI6X{W_?pfzva8wnc-kI?VbQ)-~ zOYHoS9@EE-%7>SvhNR3W$EHBznFi1>`=ksjNQ{keg(p|9BjqU~X`n2wPwl!6mrySm zze%*lc?RW>GOa_$FqEl&&^u8{;{z!bl?bIt6Z0-bLUJS!(x0fIRbl^ZK*Z0xDL=Z> zQ<`8pq=5W!^2GfC{&xu5aDxzrJh!E0ck^!Isl-}pIe0xA8BHzg367#aG2N5DP z@1OcEjnkfbp3^kC5%5&ztvxa3d4Z52!@B=>w#S+Rj(|p(rNzbHu zLrZfiO`7WY%4rieQaY^@EhlP?JcsC)W@{(J32aP8q5}=HS`z+Qi}Z&`-DgZq@5nW}b?c#N4>8uSfm<)@cY*jso< z-%*~r{!IHQX7}gRui?LvTF6?cIg=75U~WD99WZ`~CqftN9O>jthiJEC=n>;ox{V^T zn#0AJ2FC>k8lDYve0e`kZogNW4k-@C`|?bO8q=ahk0~;QXDDGWU)KSy8+`~@Xcv-Z zqG-_>uu&ROG)N+vH{#RU&8dSTj((1VU??k`t*^O|FHY7|oEiNn2Kz-UY9)U3C8I>- z9htU?@GV(Zd1cK9DdtN+j^(td-S@Wkx}WzWo7{S}9mf8;pANdzuR|}UIMqEzADi5( zFE^4|C+y6ekI}Sz=~Uu&1BaoV4bZisS1QktGsrV7C}jgbJyZH*5J3zk zOr_OFOL2m`j6_t;5H+XHmYs<(sd;=UfrC8RU@-Z;Ctg(7Opd%A%n&qi9C9llU|{xY z`2_E-qqfAj8JSc`8L3tCDGU^p?bX)xQhC~D3-}uouuGz+j|`gQ#9RS=t`_zR4S=qF z_#C-^m!5qoJ%YsWx+tEt%{M)x!c;Kff&i@=@2X}ES{SXMH%J4qrhl_#ku1zwhJCPY znWQ7soXMpb#lPnoqM###40$8hLK;%YX3w9*D*QOCrT9Z}3zbnGiv+-d@>k)-VQLP7 zwE=;WN`5^R;vUKVV_J^jvLF{?KvdVRsN0dvhDxt~6v;mm(L)cc*(j^n^pe#=CcYk% z3=p%-{q)p)1NI8zb-vRH{IHxd3I*IT;)qm0kWG`kxPNZn&H|>+l*<~|XB5~6v1mkS zr>j-lh1P?y0O;zb+WegrID_jBW=kMeZUwtkuZBW;x0out3ovdBc_N1B~!L%ljcr@eWvpHaMRgV2k-8ijjXiSnpnG#MyG|^^KfLA=$Y^d{n zQ(CdWTUhZI1FXF5qrndzU1gCfZp7uZRDb7mxzug6OkRyeOh`X6%0#^F#0v|}q+C_t zq)LhQlS6k|L<9x*!xZM!f>70t%OW>i#Z)+|l{9Ayw2$e5n3&0$DJTsDZNWWS2AWfx z?o}tH<`zhtxf>-W5;>T&Kx)QZhp2e}hJ|Hg2yKrNa;aRe8fQm8?vJmJziohn0!rGs z?0zK@4-=z&{j{b*cq>g4wj(RFhDCxX>&@mL7#|{)v&^gNJq_`NGPy-vx&9IQczBH4 zHA`KMqDtl

    Ju{8U@-I*sp^%X3Yb9h&d;A1P7yxp{psirxR`7f5Jq(a8MZ%J@ui)~oF)vx#0Fkw(28 zRyPNee*lVH=H8;cI+b-YybDwH@=ss`tcLmJ26f@VCO5Q>Dv)|5jo_~;tL;#Ez&n=+9YnaW%b8z7 z_^24E{B`KT>5cl*-Q0(cs=ffb$_?A9BHf)|r}_Nz>=vupbii>yG?@<(a7;9*_Yeqz zVzh{xvg_GCyt8v!vAp}4n`(Eb)C^9ufSHJ3=+Euk#VXOB&27m151r(t|J`0_3Anl! zOELaI3tcr2p3jvc&WtA;s=gz>3N;b`z%3hp8^90W&tR{|$5C|;|8)pmU^R!F$*le2 z0Y@F?!Tdlhq+#3BCD+$K8g;fLhSo82`zEMXT!xtelEg9=&b~Az@r#`{I?+;Wv@;0N5Jc@E~`AwjF-s`yF9_rQ{p?O-$U~?-t z*h1<+@Gf;$vkh+hlc;K8^wPMlDBtPhayue>^<)oZx{iiT>h_&K&HY95_4l2P{yA(J z?^iqY2&KFD82q@pq0(LOUFmiQDp_|i6T%V($&N`_z~P;waV0?0qcZhZ{70w@*&(P# zSM&vbAaDx#4Or96mE?rDq4<5fQ-+10z0QVUQky}Zz!YUU6`fU@x^?ixDo&VOD?4aQ zRY7&L?wgv&EzKNLM5Z<8fjGE0NSS&*plsBar`Rf_|wdi zNAOO;i*3VX^l$b-FFO``dfCs%-S(3nj0|Pp3x`kqeP2N^@Olrhu!cdGyHss11a&3!2-^cn~%gl$x z(aA?kS4&UD0~ap_93?iee6gSE$u#I~ikIdm@z?t2yHMb!vq)Z&Be&ga4$8*j!orr9 zl};vr{z-w$(i)9|XiUmxh?vl71R_nX3k)VB!zf&96u!0m#X|zh&XF-FU^61`G~1@y zn5dQ{US9bmhc|9!-EWXV&{M24RTsmmwPk{zyV9?<0b$;AZuz107>rePl5zD?X;sp?T{2zUo7Gore$$FEBiaT9%At>ubnmkS_40vfnZ_+iC)Vs>u^iR#=*%klp z7pvII^O;xwW^oDG?3LdS1h96Tg-zk*PM38H+IK*t@l_67?r3iVRZhU%7J?=m%t=6l=?7`5ZN#_28h_n zeDSw#I1j3$_`2TA4Rf@WKwo=-;aVCD`|N0&Mi&tB_Bi>`Z=Ur^D z>Bt(j6?-q=j=v|J&u;a|>|j)s0>P#=x8GJNV&?sM7J8iC?JhwlzL1nx#>9Zw2F_4& zSlI&WM_=G<#R73j07sO}ZU7Ls8X|uJ)-J|@q-Y#rJ__riF9?#DA)lQGZ@o5PPv2%1 zmhzP-T1>L0K8Pcu6aEyg*o_4EGZ|*I@JGq>udYE<>LResVAar`zSr~MFhwgt`h9Hu zI~vO{qEG*z8&LDdb(XZl?#1H6eGi3S72%1z+y|8~wys|RCI6LDB%G2PH}4vXC*}D8 z{_nb}zkEqU|36>Y{U^BphfmZcL`7ww=Okoj7GR}msb;6=nv@upnfIOKXQXMRXeQ_z zl_aDlXy_v8!7CN#8RnVU7MK^0p(f|(7hY&qVJT>(W+r4Bl_)5wWKW7T)9Nl3!2MzW`6ZxghzmMDQj}m8|$c`~ueY(1F`}(?6 zvvZSc>vlf63u`|jH?2v1J%&tvcunJQlf=mFeOF6 zk!f5GIn?kZExY#MGmuj-hI9ba9_tL8JoX)y8_tOS)$a9L=IS#$7$6&lgN76?Gfb!h zK)dQ}6#l}i?`A49Lzncx5o6?i+@VMz05U8Q|CT!(Zz~>C{)bSz#@&AVn+vWT`Tn&# z`+ECCj*YKXSEqM#!{guB)Ya6~)du`H0R8T+?R40FT{OaXeHH2T9rksQAZxv(4$wW(v1j}8JRhsURa?*=f4Atq>Z%_6?X4iffye;7Wsvqc!l$DZd%ec|K49!X zT=olcfdI<(5Y)3n#p>WcfMNg{)y-Bs@+`0_b`-Z~umj?P_Rd_E4xt74d=?`=@NSe?+?c6;MMmKbwj*%TUqqqZd)%s3SgIb= z%0pT|0L8%y0*~j)fa22sY`q^z@fG~Uun!x9BnK48qSTkFSf#IcE?|I-lf%W3+*k_{ zG_Q?EuGs$>dDql{46hj0E|f!w{>JdxpF)Cww7sX9 zFA3I1LZF9J1Om_$XftFHRzh@`^k!pB)}a%!NYLSilFL%(lVnb8Q1!@pxhKaTr;H^3GQT$Z57 z4(?(IQ_RvLE;;w+JwCO0 z2_wGL5|J-ZIy~4XQ|`VX;{-A64vvz5=SJQ>6kc^dyw+QtI>!dhDcmx@QK|F~INFYS zsv-&ITFEvON$88-R9|$3|KKACMUQ2$EQdzvT{yDSHi~0W3W^<_h306)v?(C_^y0h$ zZ6g+H48p?EAJUd09KQkD0Vy@JZC$=J&;C%x_bd8wDKPHnq8qx99n9NO0I+mJoR;}m z9d~$odOIBSjQWn3ucJ!_Yl#R2I}U(T6XmNg5AK0z4fDPu`1?)3ycYnOB~yPN+0}Ub zgoC4`1v!fNj2)>m^7H6F952gr$;(j-KW{HgM4_roC6@DTeG;U8R|3uEUM*M8>B?HP zxlNu^^bA;_(tf-SHCC9GO^TxygThs;PVM9l8;;DJ$zSM`bmHPpDJG;*MSD<-Q1quR zKrKkofJItDTB))(2n&3`8+H&2W&I4~z4b@~6_^NW8OcsB#Owr8S+Vdu?qSzLPlr&A z1tT7U}@>zLb z08_c5W;QF2KKy~7>-TzN1_3qTkP_HN!t~&2a-nbvdS-Muf+HiMblEff$||y!CpQcu zy7U)d8r7I11=vl>nE)Ei-4J&q^+$CRs{ihBGK5=<3FXj*PS)ST?dRrZ{Ws0W2r)&l z5E}`kyGV${q&I~k4fLPC@57W4a$(Hj!{1jyt)U)qb-O*C9rKKO|K84RGv|Kw)@_4Z zvAnhd(2TLnYKcKjqavFJWR5tff>P??2t=|%5iGtbZ$a^=Kz(wcO99CLX(CklO=iNz zmDKz9^QA#}Scyk4kFr_>LteUS-J!70FRKPDA8CyW{w#5UafZ{sXl)NPr_iYE zzfDZ)U>*7%{kG3ezoDNJKXH**>60xX=`pn0AW@CtG$f8IwNbbw%-2}!3gTyQkuP}8 z)Lg#W+J3^E*4V|)e($6{m3C*%dQ2Nusj-|jg1X^Q2d*t*ogQ4os>8(?&!UDe^lMYR zc5~Q;Ql;Z)NG-}pbW{BEnVFL^D_Q~!m@a}=gK)RZ9l@)Rx`Y|{vNRY7B%v9F4T6X4w`D8ZEO8 zVZaf|dP%U62*>fmXv7TY7u^;K9rz9m2ef>ctX}?nrAdu(qjr8wpj@2i8t@UIY^*TgKT<;Igva5o*K53% zMeMTv$@qGI&egI-rGYe{8L%2bC=8o;dE;6=SRJ3|v>It>pOY!jvVz~{Gy9E6HNKcQ z>QCyNfyC;5di>UE5M(~HhcTL8TayQGYN{SMaHF0qCE;FBP&<=U%D~aAQtfHP$8VF| z%jCzot>wIg4{i0lERMwKD3yGLGn@-O%LnX;K5tE^HRn22N+OSVQA#4w(8`x6CD!lr zQ9kZ}MtHHDy_@i-HIrJMpTTnM10DZgBX|DIX1)h-eC&-1!=$A(Ev?#$AT<A6It33d zY?$t6`{l`k)AYM-E4K*9(t;Tg5Q;gW;*k<1@z364^ucJTFUr**M-GG$mZo@Qq`O-b zTm5lmD{dh2dCcI7p{epvJ3XGXWd7*5A1j=y3KB$;LBe{l<$(A9k}$_NzCnsCG@pWs z$-|%J10^J}g#v0xhP15rVeqI3j?0S|j6ZZ%&3mn;p13N-s4x&D^4L6VR7k4>$n}8d*~p=A@{nkVs9{!GZ0r<8uvU0 z@{)RidM%i$b=xmUe|GKbeE?w#?C(b8bEG6`d`U|ct+cKNo&7+cqy{fG*l`MtAVK}2YwSe0_ej^vv$pGl5>2m&L(?;L;0-~)uD)& z>p!2v2#$h#B)cVLe43AZK64JKZ3`8hb(4DJEp_6Sb$4U_ngVWqv)Uz8OToU_V8uuL zWKnW;CO7`fW~hcVCE}~$==IFpz~S2&{3G`H!-dOI@?;}XltKsUDC(iI_f9PS#~ayu z-`2ISqy)))%<2tCGevj!`{sK?GN$0;%L{X9I78IZM7<&+**58kL+R1O03#7^RL{GR3uiu;%rxh&=b|SB9E-4AP8m{pn<7=;iMdH)MD~7oZ zJ269sU#8|aR_8R!eOmh@Pthk3Z+tCe6~Yq|1WV_7GMkHHCMhAEe!0dpc$0=yThn`| zLQ)Hj11r@-W?lqlJ~n%UFR$bz)>Zkb29FaXHyl-NUNt5)7wE1Cd;!77J9=WdXi!xD zF5Lm~wi>iUECx(sF zCDbiuiP9AS01j*5;LMV69H)I6SGH>_kRoRGBaE@9EadO#WkH z^?uIku^Z*XZgzM0z)5rF$Ae#6YIeeIJ@;=Q*Ki1kehB3r5FeGV8-IGGURaP=(we&F zFPmtQ*_G-M&Zg9M7Mf9q_oxk6{2B&S{NWe(0{~$0TsZy zcM3%8C~vR5!-DSiRl#b5T6N!%ddlMXcJ##2RrdFvB#}dmBGpujGaw(!R|f~Cw))Y7 z?%*19@E`yqv8h>&6GdbEy8TVA7gA|YaGIBOa%@NuZ#x5GO!fWy=%4h7w#OBIY0IE6sr1}hwOVrvco^I~p%zPx?OiyuzVgAh&FiaQyz@@HxJcfj+6^sLLq30<*B z5oA`-f8PRWLk zLkl-dUEkW7`SQJa^6`TN4&RuwU!VSb=n>yve`9|RFUUKs^B4ES5A=wE{f#__f&VkR z!wd4xP8@&_l@160J4wN-@mAgg4F)+}`>Xl#TD*1g!0NkjxbPA+qUf;+t%H4@B8N5|1UWww=11acPCG( zQ^4BKiB&$kEZ%%GrgEiJtXuF|~35 z&{^4=J1_{TsY)s+tIz{H0A}fOu_O}Cq1Uf8XRY2RebV){vr`ueZVhX;Y&tACZJ1-f zP1W3dNjVx4vi^+0cssDe62QF>Yhv^<8k!gl1kf31gZSWng1x7{{GzS5SniHPQW~lp zfAQFlJ|JLlZ=R_z@GT+tf7_L2n`^o{Q#`d*_Uc-Q&Zwl`IJIkDEPk?f=JtJ`dOfgn z`)2ga+O(KB@2DuBuedq1$n}3L&Nw(42Xxs*WuUfCO;g)-d{PR82HnEBUnJ9OZy4Py z1J*V@adb-o#Sk?dB?PQ1)Eltca<&+5)6Yw?a@KgiZBH-N!}J~6mQU!tZ8Tf8uy!nB z>!R|RH-h|}(X=Ee(!1D7;Mc4!4%(tmX$l)AhA*QK3VLR$A7;7y<38_u+>&k9mAYK% zSocGOqv}C$`mg4q~TzET*yKHC`)PIYj4Swk1JM-Kfb!6lRUcI7)y~dz0&}vbBrx zlMfHO5qJ}panKk`X}t-Z0s()5dY6StyHr0e)6{LuES;$J%3sCtYPRg3tisukb(Eti zDtLpS*<}2&?RrS@G0$1z-S6YBBF%u$Gz`6KTZ?*6*gmqV3G|IDQWO7EyFup~Z~yS3 zlV!6+^9rZ@iIQRWKS!S)R-^WE+D$F3L&(gV>qBZ{)AbSYpTqr6Yg=i(dOqXTy7^={ zJ>5D!F6?AE$@V$}`dvBJYpE?;Y2EbbY7c{3iB)Ss=i$wq{m-G3kZ4>&l?QyH8)JO! zOGc$S6##~r6VUhCwSw8=$6$aA+g?%nQ}UI^lAT0Ox3{)$IHiLV3<{&wtF8+ z1AC+@K{q12jl;E>@-y!GmS_8#F8L;7{EzDr6`3o23x`}nsr^af&8{%xsh9mAQBb&o z_LG}~7qd)`XJhB`*3j|`Aa>yA^RmaxKy;1gp?8E-YJuxI#>n-BQ=BumB|VRCi1&v> z0hV3zCbNHXS6vBXQ3vl-BD$&C3=T3&=hr$qC{AT1x2suSGdj-Jp_*wf2+H+#mrALr zu-l%Uekq4|qM+=sg?D`rYP)YTA0`fbXpWCUKF?#x^)F;#^lOjX4XlYL(K%ee=3=qV zR<-v7)A1O;8@&#zn@!~k#A6@e>DAj6+sh!h`3PcD+L^87uu6UI-W#9cm%Q_S16N07 zB|P=_hl{H?sm7n|9Ou5k=Xp%$D6GSC6hodY#qnQ>c?ExQgXbDEs)h+NG`%{taiP za*DDvipK^ZJHv-vGTeNmGC+);Kv39cM-3(I?^BPt+COqk06Sq1bgcT7^!*lT;Ggdi zQPZHp5g=Kh=<=$CA~npS0ecGSgN3Z0&6SndmH!eBTnkfR5n1c3&)Q<-bVH1L7`9jD zg*XSWvB@xA-1g8>?@U=~o-{XAS1A26y+52nN`mIb7+#0~GW+x~6B8~j3{%b)oy@dHb+g(gD0PumyQe38@EErwA+5E(L@H zS&-CW z#If^5@-uxuXj{=B3~h7y$YUriy4viydnw{$z1WnWqwk>((Z~iY-9+Y+ww%$=Snl+o z=>fXYvGD7cbX@|KMl^kqYjy{ERCZhLmx`NAjV1JpkZz6l+&Eq_k*l{nAKSy}2z0&E z6+?7r1d#5r(mX}Sm7#tW_fDTUZ1fWJbt`4CE9qFE>RM4;Uglex_k(o;Q);U&E4$9o z5u^M)YQYs*MGkDWC2@;8q z^hDlP71cM((cm;$!4;>=l|fr5eeUhIWU+zObqFdu@{V(*n@|nS{<2NJ^~5ylkmXG= zu&1e3Je^#7{2~oa`6EroRpy{jPUBKC^<}rK87{wynO>`|UK`xlyvCZY9vwbL{~=-8 z@6FYWmViZNR>McMM{TJk7-q|WyeMBxuX!3sXM>@iahGsZz-1}k?e~9wP5F>dDx{xw zktbD-{BksyJ8;>i($aLQ`3 z4QU&#En7=RFD6{U4M4X#(-8%shwqDlkL7!TNud%&+`(Dw^nP!Bx4}{&8JAbfXb;m~ zQC%tSZ4@zVjh8O_(~&?R$R3|%|4jrEsb{XTa< zcvAJ>JFIU{>Dub>HPSp1KekW)cqy_ux1lP<(Hlwb^oWx(S=2}9TN)7hi5lLOtcC+k z_}H)1(|E8Z#80{==cOz6k>igT;uqv@E0pR964X)9Ck<_mP;(P+qXCSUXJSo+%^~hi zL9oGwkawZyez#kuR9(ID2ZbtuG}k7afxeANPG+K5mFL*+qsuFhzw7&hG}ZPq1OTFgVk$FfGMI)+s3e z;)y6`ZtbICNIXFtW5BvLv{2H$Dl*5*H_{RnEYydCH_}d^((#;= zGENZ)S)BXKIF==)*yi}~ia#r&w<|V|9Xy|pcS=)d4i0mB9-%eIP>^i4fP4bQI#v16!{#63}E*3q~;?p zKq&w-$#ym+T&iptasqM^ji`Cu6)UOq!A)pxp#vSPm`QpqvvQaXwRyuBFJg@OoS0CX z^-k4kB@1O6jf6~zpbIiwe0md&Cnr=Hg$5k@E(kUAx!5oSDYi}(T+>Cn^h#m}aXbl0 zbsa>|C1r~~R#5LyHEZXCn`}8hk$qHlH&)%w1g=~q{8`?0^JvGpLN@@1!&(fv5ruyB z%G)aewh)+vFtqBF9Tze)-cNAmjB+P?8gJ4H7a6-Th~7a|$^j zecWH~JN^*TTG?9~fj;h?h&IW|sAkG3pJ{Z3PnH{Aq-SOFkatu8Jk+*SzyjKOV{BbHQ*+{zz35D*Cn%roww1%eo{kDDb|Uf^JoGkNWHb!w4Ka@bpngJ5~_= z7MA44`qDk_d8<2d^i|L5Q}S=icFwX7HqBMNHE_6_uoz$nZ3*8j<9*nYEgYnB77QmT zw@-In1;!(53$>!^0cNM2Kt@KxWMHnN#+;_iwqv+8`6)cWMidkscR4&#v?p>Dc=y|j zO(m*1J@-X|+!@A0Hy@WuMy)8L>uKA$54|&dduG6MuNx;T~37n zg(E39vO_sC0M*ze7{|K+!ZLl}ZaS4uF{_uTWVoMP; zWIeeNJKM(55hN12%Oh(mKjf>P__wHojH~QEB{k1BVhGjQl=+7clc?2u z2-v2LR*66fw-uq zXMJf|@hon_76f^y&dSo);#Y(EQ4$OY>@y2vd%CG{MNdC74Vr}Aya5CQS$$3$^I;|~Dxxh)hy#;Cf5-ku`^L`S zHX)&0;2;`tr9qknQLoN~l=RNdlFmKkYzMqM=*D-atDWGRJZiaBDb;o zDJTvoZ?=9SF|3*c1*i7E9b_-`uv06>CXw@r(p3yc`@5-*%GU~ionS5|R7b+-Zvc3^ zP>ly2gInP5`1WF%*H!3V_){H#2ZVkQ9r~IIN*z0`G2%?$BLRH+%wqtS3|C@9D|;B zb9PS_rO$|vGUi9kHHst0G6x(lbic|nU~}n(%gn-lO-bVVg+hF(xuZfq611f7yFNyn zKeeA8zN9D*-xnWC6ysCGr^a~FMip?xXOzRL zG@jHPCQ8WprcU^q6*k`peTj+2e;ZO;OSjakQVjX8_E26^UrHi6-p0=(F5Eg_V}kqg z9C#&Kzr|C6FB_r;{V{Spt(ny_>^ zF%|`loPtFw|7YA!q0KP=-Gdg>#T+=$+_5F)(MdeRk}Mosg%)#EXRWB0_8$$Q$un*&rmwjG?VGakUCoZ0cEau+oV{xa#=qI?~0467}YL= zM}YHGy=_AKx74Tsaby?rj18PkdND3TD(^U$j`;_9NPa@pFF9DMjam!-eA0T#ytcs;$|O;*-zZ4V#6r5$4z#LlKI@P% zvz|J4?hI5GSkB2{U!1(LU;pUA^;&bD9WX#ZXn%zz;eT4NqC%=dQ`&Ye8|=tm z(*{4C1YXQYshjWT&yb%1PsPWJb!>Gmm$HX-gvbesiC{1R>JP;|pE*AyBN`7mrM*~| zWXX|%FX-KJeT#QsCQR%-pL>LH%Io=gAfJO=aw7QmJ@IAi0==vReDL`Z=p$JVz1A#1 z&6RUVZCe{%lIv85#E4f_t8Tw+ZX-z|q1=?GlK#?9s}Qqbr9r%y1HptfDowLVZdALV6BFMpVo>a1 z0YV^I;XLtWykvW)#vw+Z{N8=-wq^NS;g-*}j8dZKn^xvx=#gn~5tx@cpKz zl=+32$O#p8!u!oV%bl%KZF{^nAf!#0;Z9v_8fAZUU6Xi}oyq2Ak>&IwD`|*n4|WaTLj(fH-md6@4y#w3Z1JjgA>sTwm#Q4?{ErPC7#5PPWWy1cC8=g#3O!n zV#m^lj-IsozsvO;>9hl`QP?RmY^Y>|-n=o?Wf8%QMop#rdL=-E91TTPEs?aRu8U5^ znN_`-=^2AP*S0)^t?LLw4WHalT((}&4d5T^=*n~}klVM$4J%du*=knF0nmNouGNp>;(Aas` z+{XQRR6-1(MfZ!>szeXH6l@oDG+FCu&?277QeUkZ&@-31Nth`zciAM!E-NF{!5nT# z(}R|gcMz`;5Pm3BN_>a9V&YaoQo!D*?UUFjR1%>sBh={aCDrodtB|lv^c&H3f{??s zq6S8LYG=I?U1!vK^3x;_OH7s6$6=?c?CB(JhE91r(h3!Fj0g79x`pxz67;(?3AMD8 zGzx^>GUAOuy!e%_c6Iu)l9&rJZqBA+;*>)|60AZeN;_Gl)+VwNi~~$f|JvjSh(`^s z+uJOG8oUtfOuiflZro&Xd68LI?eowT2JluF&Gn0hSQa#XLIqZERr}GLhN|G^XYTd| z0{&Dlag+0DkLT$Ar1r5flQ&RO84FoMcsBLcr?_waN@3s=N*rC=B$o;8P4B~~ z#ZHV&^`He+02jneV258zS8ky{v(hlxa#d*N@ziqI z!YIjE2KZF8jb`sJ+!0C-S(k^DWG6^lxEilqZeA(LGVvL_`Ld^|Z?@Q=)4lkF4wzlq2b+$UAA8Ke_$0)mUjLo)wy=EariyLLj!T1wB5L|j@|5Y zw!uTT0g-lZs zF1ZvAZPE2QOgwU3V8v!O{)a?RB(X0s2=?}@25UfoF>QOIS?brdqFQR(7L~yp3fZMS zUAhSR6Bg3!(6{pmfI7vY`Dwu78-w&w@P$Em0bAK1x@^SKE`nMCB6l2h#3g46Y?N1Y z$vQE&(k+t!0Mr8~Ph_P|`+Mr1nD&Hcnny zK8P0^+pF!=D9jw*F<=hg3MoucKG50-ngHY^3kjgKW*H$S{>_-W<7l^EPb$U5Gc4^^=H=(pSdx z?r_hJ2LHMyx%S~)y3`C0sW}Ah`h8gF@o>pCyOYvGblV_nmsP?w%?f@o-+A+(2B(sH zOn3G6uJa~-4?n}*Egw@Lr3Ri5)aH=l&9Up!q?%%M^f4HfDr_hD7VJ`2c03x(6mhHviH==X_LMmNb&u7Sdh6P@3s_$q6w)%fGtqCwGBkaw`>ip- zkwe4>)tDR)zvq|uTkK)F4#q!op%sU&I(g$!RC5?X*Rs7P1JpkPGtCfV%0fIo4|X(X ze@PXPcO?xJv_Ho|Le+}Y5F-`_-a2ym7|6&e-TqvCWmfP8g#V5(4?^;}s{eAoV*hhP zpPtK&EkYGMkDoMI-Y)2z3El)R?b5!&jzIbxY5KA2|39a$OAZ@|YQR81nbD`1&oj_i5-YsYWm9jkqtXZ&;^5v<`R4KbEXIK3 z(hj>|G_}5Qlxh#$gZRs|jF|hFj_e<%X=&CRQ~8(Ehqq=DfbveOc@piEUQ*mMNUiVR zp<B*S}WyVF8U1xFh*U@kgU8<8efcY15loSC@loXG!SGJTukZ{#2FttM&}fTWMp$Yb zTN{_iHlrCB@ORo@?>Yjzc&+}ZF&6P0n8TGv%WGFpPYYFBm)Ul1C&Sxt4ny*jS~M3U zC=`D#XdN#Tn0UM|idHh~Wbh@nzrPeP)u>ar6XOQj4?;{Kh0fshX#slI`+!aO-i8#>h5LaR&IUzvhqfd z_h4J2T|g5@K0>p@m@wX3y`D;3eWv>Z3hp+hR_9R9J%X@Un4w)QR8|DPKazq#j8Rvle+sboAPp#%55r@$8Syg~sB?Dj$|F!#$?BE1)<;|c zBiI!_8;pMI>kK%QTm!ivs@7^&tI?oFa|m{}FeZO6qohurFnA82-)y{3^xga#goj_n zk2+&HsW$-rQBQi)yUg_zOJd#cWTFYp$W$)`t3*p~sMmCcaXehUe8|X_c_r~IJO`D9 zlpr0pk7(Mh{@wZvg&Ak^-d-W}#dkuU1)28Kj#1{*n1H@Y{OKI)W0%PTUBy3e5n4r^ zLcg{}rx^T-Aq^x-Bz`5ODGi^JK+-xeaG`cZKTbA2UmaPu@#YU|<^IUBQ~Wfz%`K-m zLQGhWAVs|oZifxi3s!L63cmXX_&IrALvJoqm#88iV=77T+@RB3QhqAW!4=zed`KR_ zh{!ZCBRBffsTb-KaxM%15AP_km~nIcs?59#EC6USXk>xyYr=+gNQyqw`dv~lIL+=c zqJqa_-^nbnL)lN4f(wM{fdCFhM^320Wyw!<@p3=0e9$_3N5`{X+3|Mba2W^BEK%Td zitd?Vd0tVhKhRDkx|D+fU@8fMl8bHOP)y1UlghO5FY&Ni)R0pr)6V`DzT{XR2>~8X z;mAOf;Pr5YSP2o~GTRN&=?Bhq>LgPjBYaV%(gTmgFphSUS;&GqC!S@bwaAUd_K@X; zfZ_{l_D~x}q@W~>^Ra%YLlnp~6NuEFj`y^@0glodbKfM`8v7jk-3-wE+#{TA#k$UUnCNwoIK3% z^87*S?E--3|t7>pj~{eZ<`zjaEG^zy!>6bwP)6hP?=P-if4F^(po6kb6vRCIV+w}tvbrQAqK%+@_c*AGSJ>q1XWz6%YX3Z z1kbTe=R{crlnBHK3;$5I6qRT{8U%g5%!oj1=&eeSc-iX(-S|Oh0+`JsKe|FZqV0ti zMwHt*7nf(XX}@Z??(x4HxL1xoUsJ)%f6VFGEUXlY#C)5n05bY0%Kp1y**0o_G zA`ZIg$eo`6`t|yJePlBo#xBc8^C{@>xmQ?2A% z31oCd@9Ix_g6WdE$iojMaO``A$=w9SDAlMrwG%Qd3*u zVWu>;ynLMiX>3KJlpMG~&J9#gBD{EeVpS}=P7p7b0kd8}=)3v15)-QkE2` z5>xhMD*jMid7&Cy5A(B$i_vo*PY=w*!Ky69ma}a=lB5CWg7ucZO=ov$DtdG|O`eks zj5uJ@KkZzqtTC;dl!k5kgsa#9E#xk1j?7%ipBUo|65_7Orle7Y+t9Pn3`g#ujmQx| z#X7>;NwU{Sv-}|I4v@1Y-Ha67btrvhn1~u_34ljpb|RUKD0n{i@N?n&UFf<3v|fN= z*W~j7x~6xmp|PY5jo{2;`&z8kmn~vGKPXm~UU;$6<;#U#B-%mA80&0ag{l~> zTCaA^5!Q9wJU07 zlgh~bH~5KBk1tjTXe}-&p#dW5?gt4!vLatPXU%` zl{xZH`%!r_Ak&!(;`YSus18D{?>#QYFzXTFtm^3Tx@&};oZRg1#+euq=5SVGQ=t?$ zDbc8u#t`Jb?vvL&xKcuHtZ97s+bWo4)B~P&kNcxPyhA?U*K-@pxu0FN8{l?q56!@I z!>p6K642wQC{{t~!%nJTR7QA$;jA!3vo9)}F#IVnFPs?C!1C%1gsPuOEI7DQM&ALx zv`9CLF^CpXHnZR;i)Ko`5jd7-)aNHy5RVGymQhP-oQUqTr`g&1Ima!X8NhEX|EJnVdTu_pDw(LhjME| zb-@HDP+~;Y8Acys#&zr$VMJY7r3AlUw~_S({>q$2@0%`~g4$!B$mA-`Ed6x2RL!-V zwhea7`F`R%?kbpi03ZG_d<%@@DRk=BELq4JOK%&E#+IvvT!myb*$*_wDft|Im^PM{LMzRVoBE^r5%D#V1L z*P!*g-FFD2)JIf0R`PU1P!(}nXq~=!i8&-*tiE5vHWm8+B2`|4fV=~pv@X(p;+-S z20@1^0?mrxbYbS8$daBI3$~T8*)YT-Q(xvJq&jXIwk#DM8c}dwd6jVS1h&JU-gEJ! zL8~GmZd4?ZBAZ$S>hGBB^6giK5ewTzeqwiww`RqQEh;L%OruH*7Oke~wlLU;RHYom zScK!?VF!99)Qdr*lrC&1jw5Ooa%L}oKE}R^1#3wQLnF2AhJ6o||Gm$SRc`;Ew>?xM z613@chDEh>c&FWbo=n6k7{DNN?C`A@~Igxd`@7NN_*dcTe_Tu|7ZJk1ec3wSG0M@H0*1 zNS0ujO+j=!ADdQH3{)gG#f;heGJ|t-9qA!NL9nvH|ENp}rWG7Vxn6JZUX*6Y2B8t? z|2ovnl$QCS1I>!l2u@{K%f}zx=EdfCJEzl3Pj{2dfRPsXwvf|fMx*n}$X$I>;|MNM z57OhaT8}LIk~T!p@X``LbX`^Uz>ORJXe|x*ijLYEuT}zvZIfcpBr$rQ==xh>T);ua zTlmO9&(r#kC^L<+uW+_Yk$3Ts1L4<|8I|r#mwIvdE+2YvI4WAnGL7`o4G-@7MP-C1 z>(Ps~Kw1m6&FL8e_ZHZ3|2R?}*I02-2>FBIuPQ++5UTTrUbRQufohpoQsz5UR*S=; zxg_c7RT#4Q$zK0dueg4!iNq?bwv-eCMcgH?!Zbc~{trHlIBlGxNxYC#4?jgtEM3(M zE#(xVV)~!*hZO1v!}!`0*O1w|1c}t`T^PT#S3g1YOB4|?=aeuvZ+iEC!tkT!|B%7K zD?@NUU<~;96T{9cYMKpS$$AB_4t)Pa1+NYo8*dJrpTyu}2=V8P&c^$VexBOSWw4v{ zcY$Bl{cPNJnP=pIPrreSr-^@5GkNYXw>4x>iC2cq6q`S0hEC$tsyjA2Bd@K9%mL}Z z_KvV;v@$B$K*txU=LqG;;m7oIn}#3DW9A?IQI}hyS2AV#hjx;kXNuEg-PFf77D*ns zl!;(FKzl{y#H#+ZuKJ~3f7aURUfRO@3R&f0$7Xch4_h_%=3ND0>P_ZT@96MeH27Yph}FET4`{*z?KeXauzb zJ8tJo3cM*3ZG-o-m*D**6fu1g3;AtOIIv!}GSwWbXsc`&Kg6e-sA)J)kB=b50Bz^H zp~Z|a7p1L=q$dmX)WT)?XN6|YGXx85TE=y_7bEbF`5>&gs^gaDGb- z3CrL-@DzQ7&R%!#VIptKc=hBku)gd7drlm$AfuJYbRIxKKME<1Raa*wZ1CkQ2NuBdZM&*V6ohy)sC z4e$loB8dqTx{Yau%x0PaFI70TUCr`zv|fDS+5orikRPt}+6tGtK8mob z@{vKpL()#6gercYX#Arp;rv7Xck?XIWmAqy+ew4*cIhItSpzHXnuI^3g_O_cr=P3g zrgu9t>eW{*5!W%j%jRViT&vYy%!j@7Rd7<>(^wJ9do3X7nN%!0Z}#o3Lr-lU>+B}!~a10KxVb}BFpd8 zx;#3@j;7Z3w27%}*T?W9+5o|tcf#pjddfD`(LsNw|MtBY>aqc}#^GnEFU47JNt>{a z%V|WWCiNp!;(6;t_bY}Imp&^gK5!LLdA`VBfR>J$!||BD{-Cg(&GXta?ZBI4!vAAY za6SD_FlIYG2<=9YGIB9%We0vA;;WV0V-WL=peO?jf(rVdw`u*AQ2+ZV`uVTR|HG!O ze**uR0{TBVAfTe3cYk+-{U_l6l?nPM@SmZKe*+u;e#UA$x3c^v>YrBe->B99g8Cnh@t??ly2XDZ$^OP${%sl+WqyGF S>m9`3g8bKi7qk8A?tcNUW84D( literal 0 HcmV?d00001 diff --git a/venv/share/python-wheels/certifi-2019.11.28-py2.py3-none-any.whl b/venv/share/python-wheels/certifi-2019.11.28-py2.py3-none-any.whl deleted file mode 100644 index e38d6a40c6b625d84ae5787dda3995f78b9b4fec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164552 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 K`CUIVu>S+j^@rjB literal 0 HcmV?d00001 diff --git a/venv/share/python-wheels/chardet-3.0.4-py2.py3-none-any.whl b/venv/share/python-wheels/chardet-4.0.0-py2.py3-none-any.whl similarity index 50% rename from venv/share/python-wheels/chardet-3.0.4-py2.py3-none-any.whl rename to venv/share/python-wheels/chardet-4.0.0-py2.py3-none-any.whl index 60a9bba9fe95e266632af93179051dacab8d5f3d..4b26007284a526009c73d6b3ed43141b1ad64e59 100644 GIT binary patch delta 79480 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

    CWyJMPzQMc-UhrO_ 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

    %cGW>Imu|t?Kv!CPRtY$8mcVlwbnK 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 LW<=022k`#@GEN|M diff --git a/venv/share/python-wheels/colorama-0.4.3-py2.py3-none-any.whl b/venv/share/python-wheels/colorama-0.4.3-py2.py3-none-any.whl deleted file mode 100644 index 4d28c536ce316201dbad67787a3389699c6ac6f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25094 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 diff --git a/venv/share/python-wheels/colorama-0.4.4-py2.py3-none-any.whl b/venv/share/python-wheels/colorama-0.4.4-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..aca3e262e2f8ce6654f49f10d6dd78a4eead45e6 GIT binary patch literal 20722 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 F_dowq;5YyP literal 0 HcmV?d00001 diff --git a/venv/share/python-wheels/contextlib2-0.6.0-py2.py3-none-any.whl b/venv/share/python-wheels/contextlib2-0.6.0-py2.py3-none-any.whl deleted file mode 100644 index 1b46930aa18b658a87d977be24024750c3094040..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17188 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 literal 0 HcmV?d00001 diff --git a/venv/share/python-wheels/distlib-0.3.0-py2.py3-none-any.whl b/venv/share/python-wheels/distlib-0.3.1-py2.py3-none-any.whl similarity index 59% rename from venv/share/python-wheels/distlib-0.3.0-py2.py3-none-any.whl rename to venv/share/python-wheels/distlib-0.3.1-py2.py3-none-any.whl index 0bb830e535ab22d57cd65823a9254d6f82611dcf..f2f03d2541083bda123e32236c0a56a33bbf469e 100644 GIT binary patch delta 54591 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 m+oycI6x*EJ(3IinjihvX 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 delta 58824 zcmZU(Q*bU!6Sf=Mwr$(Vif!ArlP9+A6>G(|ZQHiZ{qBQZwZH#An3|fSsp_8TySwhI zJ`j4d2%1(=1{4ep2nYxYC=RMxxx!>1B83zP2tgGH=)Vof)XK%x*2SrAX>~T*{n27fN@J&(?Ex5J8 z$D@&1d011|{7~Q6?!LnzrBACeTu}}9%m%=!RhB-5Mlm>-saHnL#K#lz`#XC(fAmrB zZj2O5-QMeNX_jqTismdbiyQ-rvBpp<>Lm0NnQQv90eq= zNN+E8#GJmt$>6q z)K}bw)m(ejw>>C#$!*j$C&La3!SYpmB5rcDXm%^eFOB1N&2t2}-~Cy((0QJVPTJIL zVgqITFfL<)^$JY%o_c0|49>`brzAUwN!@kk=KtyI%SCWO-XFQLfG8&r3ITLgJD%nj zd-mtT&!rXTUQYaB``9YZ%*-@0HqN@#+xx|iM%1M2?ex#-?*zO{Rx*5A%5D#JBf3`t zoc{h=sH{~I7|pE1d%W)T~fDtOxV&5`;ze=(XJ zCGC>lh2U#<$|2|g)v}`(l3Lw4J#IxjI@Lw5JoG$ts&J;96lHBOIRK}UF7f567}w0D zQe3Vq&=TLL(%T#}ui+tmbouPFRCQ|d(wM497vkQ5>OONn_I!0I1Y=)H)2jYywHj%8 z3PM>Cvl94Ah@n%#&$ITLlTu*|g4{g*pP#3vx4=GMj0Z&cD}Q)vU-OMwx2FZGShYMU zh5i*#Xo49G8hQZoIDnv5;)y6fqNCEgyz(qZtn{xDcUv$>EA#wuZCXIAlV6(fA-`Il z3`KLMegOwNhOEJ?&_=gLd4L`SvIiMN0ToIku#D~tox8xet)R;E8xxyDW894`rfSjy zaq3gERCJ;lj|~pK-s_G@4D6V)BM2n;Ay!oO*)~h42sr1&008_|UFJG2UZGTv{6XB! zKBe?J;|Ipv)>VlfJ*_d8q1k3^Y))Ozgm=vG72O}d8yR>Og)g!fCe7clH;N_Jq;%+FI_ZyV(_?h9en1EzD~#+ z@U>t%Bs2sVi9kZP!=;ojmwA?*+7^Kj&bTJ;0Wi)AV1O8|JCYYbBBj2ws`mJ?`^O#l zblUjE0F_0pGzK!@)TKce#(spW1<#=*g4+RtIcpw`#I#ncDY(K54o-xsk08+ks%f5} zc@u^N4x0_7(e^R!@~|MLTQJ<$$+Yu_xEUfelyUzZ+rw>Af*n0^f*H5V^nHY7D5lbC zt?h`K8qRp)1aQh7>lk+}*h^8FvIroyg@Hr>+8!)bWCtK(EE@JTymY&YMboUZJDuw6 zR`V`Ny_E8}h>D?hPbqR~>A0Una8 zeOZZ5CVe}nA+Ib+M!!_{^FWot@I(X9f5*|)#3CPKZX|ec*O5_>H)PGp!SlSgK+<5Y30HpC!;%u{tkFq(N@~_aQ`-H9EvI+%`X4qL1 zm9Cjd2)-#3P3JGwF$WVRmAj%XEuC`4iW~!w&ODH`Ix#Fq&n@i}<1PopJz6(_acPZU zOpWsBrkqbj7mE5vBx~*>0}X?XyI@F0GV%I7)gq}0>)cLC^}ACDm`PxughIqoqQb zBli6I@8@dcXvUq*d9~b0xum?X;+M)reZs_jaK`}0oXqbTpGlYDtMZDQI(Cb2mx8)% zmeWic`Wi{8vCddmc~`_hIl`_D-$I?oBr(XeR%8Q7@9r^(->?qQvG;L{NZmRYe ztFU&*FQ+c)51OAdmS#HCE!=^PZ(}3dY4N;p>hho|L97NG=WZ1(Rt*jH7vbGxw!@+^nWHrrSW8H zxi-7GL*C;wxX=Og_h+{{vhX86m60f-86I|2;o^Y6ylatx#D6l$*Y9n8VX5mF7HuMT zO{W5=a9Dbj#tAsqEnR=0;tm<2KAgc!m(uEAOxB}INDlM+`bWjRU;8;#IjKTwiTNue z0o$-+e6{ zeF@3WWnuhhU7zjeO!MLa?y>to0_oTpdPuox!&&E}jKsL7Ln$%!zFrL2PbiWHwGx)d zKvR)XuY5{Lok6m;2Ee!AfJpJ&xY-r_Bo%C7XU*SPUW_E!t^}j$O$r0y*C?kHKVqzs z(S;F9)+|6KhuDkd)*ws6g6v;W!Olfd^L>|BW!eZNZ%pIBiVyU|h!3lHL4O_%{uNKu z@42J6FkSPcsUfzdF+bX7d)Fs4!>|}u;$#GZuv%5h29}-j-Jg>`BjxpmGXw;H-@Bv0 z8S8Pbx$)faC!m^Zh;DqoX-o)zG1tUM*{Xb1-$Fp&l08<`jnxy4<^lNWw+v5arm}-Jt~pH`1!}3 z>9KmjFQ7FVRO^jYpcnvnl5owcp@qVselkE8%sO7e8>a3o*nI=jupmc=*SmeoWo`e~ zsEZh~3waihzBSyvl-eHePo^`I*#xi4-a9Mn0_t-**1Bi2*MkJPvLvIDi9u4)wDa}6 z`>}8*Y&u+G%08C)RMc<~9W8+nj9k;=?m~B~8qd5u;BIi}K&C1JO^J9bo~xG&a#`N6EN zCh&#Sp^?vg!vM)T7U%6EgYWw)Mlaw57r7SWWZI-Ea#nVuU1Fd?42x+4LMrH3x#zG@ z&Te_+ZdKknJ9zwyZAZY8B#n8O84PgVF1*3XWquK56?`S*IyI5Q!q(iv3(<`@x`LZ1 zx_x385+hV4=aChnxH%{>mF+M)(IZdX31z9wf2PK+pQPNLoi1(h>J^|cmXx2EoGRT) z2l)EFoE<#{&OvfLr`i#>8qMiToW{oy=H~A02J=YV+$U2aBJ#i8eDmJ)mjmK>!3v@BrCag8POiB_ zCIwCfkbf8u|LlUjK;%)`qBX0=xf?0DA>AZ1AcJqB$B~m2qIBNeF5?09mcrVM$mQqL zHlsv$-$i!EFMj^_9U&(;lha68h?v_j5i`M6=ybxvBLj4DsF77Q2LX@m7eEJNvY4=m z4g8^C{_(T&aj((0Jj?1?o3y<>6Y+PIe|{E%^}tEW1FX&!ho)yl;QN;doi#%>z9G~r z8QWH5O63HQy+AsG5itjfsNA4`--vC5?z=`*j#rFS95{+8(7U@m{gJ!X(z3uo7+PIY zCw?v%##oT*V&Qauj{&U&ACUU`rJ_v`~9Cj{IxppHuBZ2Ryk;GB@q@*|Lp3 zM7AWM%~rhY5&qT6ys*)*%BU~5LD(e~gO9LkI2uvSjdC|DzuKwaF{o$90iaOeo3iD# zMuaOnX*Lzm+9*2)kxE-JB}^SkgT|qM#eN`6E}9E3KdTPLK>?Wy;H(RYc`Xf)ZZxcl z`)X^u@58A`c|KNnCg7oAKFN}#5-#S~#^S>*mf-c!m3Cr|#WGNBv%exCWUHtnpdkgx zoExUvFQ}3t>4`CNtgU#C7THxv>sSkiT#9--BbuZwd0qn7OlneZ*q7m`5LVSCSmwqR z=8f}rfNC|DCjfau#B1oYb#{@CjL)qvGD!Jj!e!EeE7R)p+m)|82j-(0bMnv*Hbx+y z1_VcW0VHjt=^H+=S}cqqGRMl#@n5B6Q?h*tV>sCDj89Z5S*}nQ3rgc3cDiwIIddCR zloP+?Y}4)2_F+1BdZ;5xc1*pxHOYgyCEVj^fV*OJcENGA)9F3V7eVo^>Zf#~BSe z#{kAy3_q(0yXg%AbTn_qig!TRQ>_pl7Bbr>n!u87OepxqAfTWpMex?hp}#NbfeW{M zTzA|E5&);tM^*|Povp<_1fv9Z`&DfgQH&b$AeaAQt;F|%9NY2kYj0P7@|Ri`P8UJ| zeGn$v6L}SseRv+i*T$7YB^B#qnuCAXYa2sxRuvFkl?8#Iq}}(?Dwjc|Ig+&XFFzmj zY_R+jgw_dM9G5##;%T99UOWv|Qr3xxviYgb7eGg0^7tNK1$k-D3cuQOL+kXX4HH6) z2vsuR8B&wZAH=()ljQ1)fsAw}9IobRPa0+1&O=WpOb$bYB3kw=FjxJZ+JJ}N#L|*$ ztq4H(@0C5r8Fl+9CU4FZB#ArH!Or3&IHyaQZADX)CYi*^_rdYCq(-%xCW82aY=qyBCI3=1khf z;=ziMIT3{-+{&D61V@wS3b7%hz@q@A91yMSd!R?=JJhkF#%X*Cnp^c0v*VcjsrN=t zzV69F!naSgD1y~o3Hfrb@C@=P`YLUxEAJBQ2=Wqop%We|L2@ELUZmU;V#6ne*`lk| z>^vfCBtC_mIXlBY6l>U_9hdA1MEqywXnK1T+p<-D&%%uk#dv-`-_BVFX^?3aKxei4 z`aA`#TAIuDrfeaZM8eXG-?vQryzcJNH^yvmzI8KSma@O-x?;dRQN> z@b8-nQ4f*M{cbpeXR8(E7UkvK+Fm$agsi$Tmm`+bjhA2t;|j^|75G{mw0$)YdZrp> zd#%P{s;n;uY!9BnsMy2V6ku+j#mwg+NZWvXj6NOE!RPbv)>*9e8u*)N5TxX#KYXXD zSYgJC0E+W4Xsh>6p0Q1@ABs#jeIxuR2aN zp3{M642>U?4JqQkkskTNeuI(@=}zV{7_;)j2pI1mZm*vk8tI;RB{hd;*|Y@q-b1rQ zLk-;n_p&_J;N`Yn1KtaBStS6c<;ah+xHN1|HVgjoe{T1=b%k>?_u;tC+VIY56L20E zYL9*MVWAr?o4T8C%vRof4EvYsEPZZnbMo>8yuOY;B@n}ML}%}S#9jTrzSon(M-lJA z&P6@fLi9Ck8oo1fx=`tO$#uSnom{C<*n=1ap4r%!UZ~kk0lxoEFr8dWbpM&jxb=-5 zCp=a|*3hi$pj)Pf{7v#wS))=5(U7f3o}QR#iJP25nx<^EQ!nqPka>RZRcm^nM{D;q zXx>GUTHLkaHGa&yy-`IpAvA}YEnZH-rX4S4FXUYO=)a!Ff6Y5O6OAbdjau@gMe{s~ z7t#**jRol_1$gkbr+17Wbse`(813u%aX(zVl(ulIp4qxW$Dc9&_9t-)QGk!7bc!&Y z)p(i3A~*IGkeb|__h)_LxOgu?wy?Lo*N0K)Xt=6dU$TtpW#mP@CPSQmVvuAB|M>&u zE0sHSbGU+N{8P=9?hHdlkgC^sCuL*d-sb+K9xPM13YeGJQkD6r324mi}wl@;V zj;vq213IKrj4z#^X~lAUqGTK*8!nf;pdHe~bPdUwpi5RWDyN#nAM#O2A2b4ny3O(^ z@&-Jd+1Aob%H5Tv&2LjED$*RIsbXC5&EnLxh+D?A&8d)0O$CJ;5g`EQcuC1|e(z{I zRovuz13Yt@ky-9V!qA^uR8swiud`fKQ!^XRUpO$b%*4IMub&vQN0fJ`-L!1-EJl4d z7>5`}X1v0zt)LC9ANb-sc`QxnnOSH}yO3DwD<-bMUI`X@g;;Ijdgi81cms)z%PI7+ zM_pDErgr{iUSEDgfDb83qHBY}pJuYfV7yfs0d#kSuY{nV_=1>jE9j~>QIctD+p|G2 zoq*%$;%)7CvzOw-1~#gT2+`v${^}GbzZ044&J*>fklHs*!{+7-u;LDM-SXY?+9@>t z)mgYF*&*=WwF97bga1b2nsPdgF4@1scRi)rOWU*O=H%t%3Fq2AB3J_N#1h*G-dfBA z0eClLQ5Gvf!B$kMM+Y_%5p88-jk~LR8oI-xcyz4! zPl2<$V|rH|wA<{)l^kTGWMlepcThVQ9Cz_;ZvJ6aN{^jy0=wDK+XZmsjmC7G)dD%B zdcaJra3sA|e&rh6qs6kBkbk3xAj=RC1N;Wdby;qgvEO9FKx61mXmQWuK91+r|-l~H-Z@UJov0_61-9Np=lvYcqmjJYEVmauW$KU3S5 z(30oyWW8gTKu}A_Ufz&T^>c+n5$l`uX53W^tABq}RNBs}V3|BYTx`6mh^HI^^akrw zn!}__F7`I>Bh@8tFR(pz*x`O#0PZrfJVu`M_02JBEzxvjWk5TA+#iX`|4mja4vgPC z$_HmnY&Dy1|Kh};$INJ}?t1Vw*y9UR8_sF#39h@ZuG0XPt>n9WiT#k#!yE2wDTSRo z^s<~-DjpoPV_wE0UMQcXk$hV&k8;h`Q-P*S_pghv(|u-_c}5yLx};IXfZ123qiUNv zdeYiOQ7}qTrKzDRkY>^|+Lx+d+(70K1G0NKxwn7IS7kio4kE}4=V@eb% z&H*vI9H$eCgBp9;QIPN|vc@!O?}&2wGyh0rS+K*hxk+KPmIGg~PTbMDDR#T}pPbxUTtT(feT(CQQeM3Gj>X`-i$t~!NwtFdd$c2venEH=Y<#HFMdw)wj_L{Ub$q1Be5)tv8gQWG5aMk&V|sNN_iQ? zb9ITTXEhgmMdP|LfM&l}&DU_oW3G@LpA~~|ZD!cRW<9x#2~`Qz6{9^<>;6hcec&)) zC*B~tkCgwJol)DVpiPL<3Ru)>Q-T1bH&b-#;i9WRHoeP}6Vbtquq}HPy=Kv(Vf|2u zte;FoV!;jRw+nY1HB^tXc7QhNo-Pj_yYv22r#w7fdxl#XQ1#Udcs1}!q`LP04KJK^ z@zmv|BNzIAi(iR4-(PvB$(~Br;ba>Oq!z9Hl4$tu<=B{Vj|M_#oIJ?a((C^7a&rzDBHTyF~3rBb4#3PV!Y4)@rS-h0Y z<;B(h;8#Yxe_M5oZhMxpQdJNnpM+tuK7F`=42H|rRI zs<@CI1w*d}d@G|sV!Y920tFr$!IVi*P_* z;{oYx8WQp?>*0gLLMP|+?D#|fuG-{> zpcGDPecs$X(gk&Y?-p-s83gp}T1z>ydsP2HuX?a{A#A@qGN+zFknZi92(Q5fe!hlk zy`6QlcD&@`Ee*Cg@-`~7I?3-&o;DW((mU1-_rl}trlsV(F%)Y(O=JY@7b+TG*dMZ)g-BpeJTEX?yzP+hap>tCL<80_D zX&{!6a-P1!-Kd07A(xJ z*)y^E(x7C;{r#e6tg8c8LFj!$ zWFnwof+b3Qb&76`vyWR_LJB^B&AAgiE!3s4+!dn=`*;SZn=%n6R7Cd)pGt>9)SrGB zWc)vKEj9QD0cjUib}9c>E3AX>Thf`)3vTJv(~mjOFjxeo7No>k!W}~(FRw((2Gs^% z5z>$};jb@sUoabU4{fo-=GZJoMVqsK%1hp#tIn)K3O-6-7a47R757O1G#S#9^sC1S z$e2m>%^HFkO@~@KXpz7TXgn{0JJl>HbmUF!2O#WLYbnaR5J4#hS*R@cxJ=S>@r1H! z=Vvv#9^0pa$UrPFWXl{ePyK9;;zbS5<@{p;Z{%9-Xic^ z$u&N+E-+YLZ_5^C3i1SiJbq0C@a7}Jj2FaG6?80x=`%Gti!Z;g?c!KzGo<1;X4Bb4 z33-3SrFZ7Ay(JlfFboy%VbEQvlPCTvz&i1}Wo2JGZARvor#c505+S)`>YsE!eK^d2 z8pJj!x`P7RuHO{iMf@h4r-SnTy3qI@+hjN_0{@`|nC{lR=Q_%OGdD>)Bf9PuWx}LK zGiToiJt|#cu|72W;?V>rS^15+WxmsPKh1d4=4GKpf3SbkvJtqWekO5uEaoes-H8&v zsYy&flZ*x?9U3y_iGf>ohuMlFU%mM{I@Ry=koIWIOKuJomcS{ypseokiF@3aGh8=r z1Fk!E@1xO|uVY4itC$8tKLY=>ee8)r37npH@VT}vOt%z&r3ldKtLj3|9=(;^8bT@6nXxGf%H@q z95$HHdQVmOoUBV?-1zM}Gl$S@h~w~7MwrRMJYk&BvK#zAyD`r;Ndg@AoG;=c)ty5#};57u)+|2yVKV`#8MG)wmIRLGf%YZi>p84#&M6 z^bl7>ZNwV^p@*8!{cOy5;$rQffF(P20y(&T;pJWsW|F>ZQ8S-S!Xg;!CXwWVKRCAt z`^vEp;ke~p9?jJWh&UR56-p7+i1?iYMnr51wY)^9ZYUE+RPomc*5SJN`-j6;azSH8 z!sl0pkPj8Nb8#Q;{%ewxyQz_UFGf+%*G)hkum{K4Uxaqequ6s^bD!<-0PJbyucra& zc?>p-s4yYCtxDSvXtU7( znLJ3av4py-?Xcpa<305$V}N*)|9BJ+M)L`0J-{u9cDHsuINYsHH~)K!$gK~m9;~Qd zRqF?m1(_G2<2^PgME8PT1y2k*G-;OPn0iVx@>B~>Cs43479vNH zZk0Dd#_%1%KY}lo^rum=i%ysZ>5>GMFIMWg^O3f-Uo(7r`c{s?9GaVOg=ul_p~g+^AB zPbp$!9mf2j`YkMsMv!F2 z<)NNtvRZz#hg&g;p{WEw$d^_-j_J42so0;~!X*?d*i2{wj=iJ@J{rR}8nXqi9O^8Q z6w7K{joXkoX$x_pbEdyyd@kSOQXWOPyZU=rpjt%KBOdiAf6VyOaL#nC%Y>efKjatA ze347x-c?NMHiO#$eGyU-uc+n-3vL^v;+MRs%u;uKCjB~2;N}Q;sWR#BZk+!X)mj%* zPYn7~%eEfI;#4&{*me-7Hx?7_4Gwz?$|-sLyq3Oky#Ni`Z?URF;7+hw-ZAmi*N)vx zza%Pas;}ID{YPN4{yb`?(-ssb8QiAHZkF^{#SMi0cbekiRON9JQH6GFJnu+V!{yz+ z;lRD&;M;WgN#D=3OPPx*h_Mfypf$Bx&3Bd;j>YWKJqUHfW3P zJ-p$rIX2;Wvb@jQrMrUB5+lbyC|~~mJ>t#Iu>ht9bn1{d`2WrRMUr23(tnxnN}k6+ z1u!xEzX&6}mA$zGqw*h71!Xb6C7DJWOEieR_jmfMLl@4oKq4nh6cP#;C(I!|e?JS2 z=kXOipVz*=ql(s@<`s|0&w`1;-JZXz?|Yww*D%jo0VqcX=Zzp*Mx7o%bNp4yrF_k6 z(+`2MO<(q5x#5L3^Ux`MC`3UJz4pI~03{cPU?Wg^&h1XY7armnA2?*#e-vzZNOnU7 zW*6GLt)-II-1Dea!d!jGUvk?)#8ANkJBCuFg5ds8PV?6rf3&8lUGlncvDgn-I`*9`Tre`&GC z#Wjb>KXVO-Wf*c8lJ<90xGYOZ0eS^agk&G%!)SJ)R#2ms7tvASdyT)bW~RhtTd0K> z7J&qplQmW)t5J%<%Te?mf`CNqK5mN`9Kx&3>PnaxSIGGF*0{+t0ZeeE`C~p3 zW==Hlj1h@hHMY+wMj`>GSRZz=qWX5Lu=IR4Ykz1s6RcHTB&}=j{I4WU9lbiDwJL{r zd(hea!=S=;s#c#a_#G}{k5`xS=tjnUbEj;EvHJxhfm5-RM4;5kxi0lyLJusb!?8t} zW8QHNbB6CZ)GXmKkT22%0UuwwGspSCO#d+=ZgB5#+JFV}&$bI!YKhtdClEgwe=ISx zP1ivWOacMa@_;T z1&4io&a`AFuyG@W1t`i@V2QjtQ;U)TB;8roq%tJYK!-ko&sm`y04!GB{YPDNG^KJV zXtH_U?s8R)eXMAVGVQ@Y#$VyYE*2CrdB5-)zojLqJby8%56Bw}1ucRYH*(|B!8nFh zwPdfQkMXu+Oa~7Pwf$wp>WNDD0eWPF=w~Hr zI6-{N7{A_=ND%MyDk{X>78^mP<1}0M-3X`a2+ii&7yp?o679LMTh4b z06_n@koA=VO!if5#-+qe^`e5O%DZwkw_259fZZ>m&G7d}bFT z$fCzlA~Ce7WV@2pO_C@XgPu5Bkc;)oRwbJld2*Af>k^}A*)w6UnC}H3TCsI0#yq); zIl6v{VFimHifXk7r6S5}>4Ocukr8;IOhI9;N|#7g$@fEYjBXr`YFF?b{kjQ=2py?L z2xjr#^y=^QNTqQsf_$HyrABsd2FlXq*cuGq7ZoDsarr1hJC@gUG|TOYgqa2-@GwVe z@m^BKZn07ah{Zw{>t+#`fxZUcApet>WEg_4|03TAMFz4rRfs}TlGacHQ7 zA_Gh!v${_?2XDJpuf>fHPB==BBjxEW8GS0)k27cVbc1k0^XI)|%`E&WZD zrz|)joj{oEsjZ{@=j9PqAD!e(=195L3Y;ix*$IvOVEBF-TE#j0_#lWoLq~HQ@nGAC zscAS#e7@aNA70W>%mr5;!U$^!%`11yG<7wNDywI~5_XI}*E)Zo_uT1~UKnTUmDwyc zb(k%j05K*f&dcCFa&pigJkjQ~ePBulmpXk*{M?d~3P~hbF#C|H$$p?@Au?Vh8~Kwg zTX=at-6PHwAfUSHmbC~eF%Z2`F55AIo&I%kVr0MRG4 zfiO~9X(JSZBSxeoV3$$97x4VCoDHU0WQBRwXmKBvHw)^}PdA%ArcL@ck-ci%vZpUA zb?V)!J7-3AC4uJC?2D>_eo+S>+`zyu{EZzf*JDe9(Clt>Z;G&czvdGN7Pw9%T@8Fl? zPm7)TC>0*%9`V?#*W$i2u>%mz_ejdPZ@*l?e)>9B8}PqTEOvoJD)B(z$aFQ4sTP*3vm`6ysBgn*$*P6vSJBk-Y*5b~FUK{Jq|w8^x? z4EMI=cZx|R;Ox(d{J$u?dy&7g>OLsYDdAcZFi}?P8yt4}&RzAB2w0=00@2BVfpO){ zv$$9(Ll|DwDB`3)>c@qPACo9s;2SXRbd&}1uXy{4+5F2EuSwe~m}KAgy*SVH+=drE z%z%ej|A!b)axIQF!F)nv6|#y!Ce$PKeG+xf z1gwB1RWs6PP^_3Snjp~rC=^iv*uW+?i%7FcK;@W57~u)kSXwvcYIp)c6^0vltY&oJde3 zz}hPMP(TO#e}j%Gy3oMkHy4F%mtY^%79m?;c;(?41Fg-h+gpUo+=~OV?uo|2wMDMJ~@=!X#*e_Al0(?8srrt9vj7#x@~WK{fdoBWQ`>}lq@PL}6S0Bh4x z(qu2wL+nZ#G#+wy6?7X=rI1SLwadC5-H7Uf3ugQ3jr_TqyTOry`QnpTNLN?vjM8>7 znkMjwp)ERIy4FTII}%3vgPpgO=D_Lcfch0ORf+;bMCJRwzpuuq&uM{3?NEZNW59{R z6h)vsH;(T{&rX0FpSJ%7cgwsG=IXI9+Av44aO|?rRYh^?FMSnzm!e(?xK8^1t_I)53II z_mAHjd4Xl|%wSLMB4Pm{t56yoUoqR0kWXrDh!QMR?4}AZ{NiK5W+Xr=X_&yDwD$^=s zk3D6xfsJyAH)F5mWY#rh@GNTYz=K;Jj`uya8_$vTI)@LPIe-%e0b$x*trG;-NVcjo z<-T~53#uH7#6^WJtn2Fl&GX$C<`kd|zTkVz;RhjbnK>`V?YZ82y~RU|CD4mljPkbg zKIbRj=H?%b{Y5ANNP#ES?d_Fczl6pHO`indPMaiY@t78|ggTR>DDPwZjA7fR479O1 zYO+P{K|G^ex)Z%auy;_N%WJPAjQ$hEgIk?~h~j%Xdh^P+Wq==0u8bfgXf99$YE6hRIu`Ol4>q*B(K?(3ekXd;fXvG(GbCQ&m*6)|fEE0pV|N*aUfm zWU}1jX>2S50ALb#=PHRFC*p19K*6(H_9{bI&M-qKfa++7!8biG@p0a~X1=E^bFWZv zA?^y{1jz}z^;l$Y1c^KE>6m(Uz-~6x(ody%uTmf7=miJLs&AQxLu?vyrOx6kpxKVlf${`f&@-}SUeIXsv87h znSlQrU*)K&D-J#&Yw!2hTfm%)E5b@;!j=)|w1djoWBI$eUsLFxPCK&KbAnGz=_(C)Q(oC*>5M*z7_blwb=CkmdxfzDlj2D4n z62Z9(AC&tJcDA~!>)WWLV7(%$_yW|+=7oC42i@Un2Ybjc6L_kK=)`Bdyr&YXwEAPf z={8pH{0zuTO zakz6+BN(_J#MiHOA%=&bnB=rvZv8WpJK{I419}YXT&6LZ=#EXa%{fKYViH<`AHMbj zc{nxXNnasytd*=wWE!=~bt3TQxQPI$4`iSlhi&Dqvht7wnHbgp0*5m4kts)W%z3lJbMYen9fY# z41U+pC=baxpea1hvQrAdyvK=B+5}u#I51o{M=$T`{=xPL6_AULe+2u=PKkugJwQ+l*mCN{{%(>&UQ zibu8_nW2B;)?@<&wE@cE6S1sw=?=1uxBT}^g+;2> zAj2%#_5FCN*}h!4nSgX?q?M~uzW*Z{>81VMD{7O~4`S*PBrQ5 z8nzCF-_xFK3J@sOq)iZhp6Bl~AZ|yfzf6DoNkY%%0AgrlC)2shb$rSa!o?_@^1A}_ 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

  • uuDqj&81#TiA(_3PyIZ1K6M0F`2zs_(_JG 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 J3>_G<{uhAnTSfo? diff --git a/venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/utils.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/network/__pycache__/utils.cpython-38.pyc deleted file mode 100644 index 5222f9a4f776cd8287ea744389ad7e31c6ff6671..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 706 zcmYjO%Wl&^6rCA6jLIpt-_8i z{{Sn*$M6HQWdl3bthkdVQm=HceC`~d`xD}N8n-~0!0*O zD90hrNl389Br|d|G%;c(-vex9job(8W%Kn?l(UkIM0&+kWA*(5 z@ivV6?_p2oRj*2`Ze3JyGGny6m@<}i#p#*k)#AQ>>qRM4=0%+K3MLmNpY>{)X2P#7 z)%K=HblvtXy~*1UkV%Mz$sO|B*=^yr(ZVJsnD4+#;MwXf==u>Xg_hjkY{k!E&P;H9 zBCc$qB>(P^1+L2NXqY&}RGMblOg)C;eL6lgFrs z1MCql{DPSyKZZZxD<^K8IRI5XlT`$<#x+&tvi;hzX3}nm>;}_X+tOjoX8P zu?JHhfDj}hf(oag359>Ra7s6EDf(E!N-yy`-7EYuNJ2^^T}Coq(WLhk5xxkX5fMml z+W*l_2EutnM&bP3tFll{R^%t+LzPy#sg)V#WmCvfRwgxhUB!RE)ntD}ZK&kanbbyu zK3H$$uoVKq;Weq!GQ-&0!v$jxrhX5EBmkTwj-ZJvLg5Pbj3!J(!V^Ado(KR`Y_|{c z=BUH<9Mk;U165z-LJrg6@g10t{{wn>k*636Cq0r{!!wTKA&mNDDl;?g^oJR;dow&x z(0%|@e+a^mDP1}(Y2B4WiE)>#r7OB%Et`5R;eHEiJP-sR)BRDX@TE3-j@X8r=T&Yv zxBZzafMMP-WJ9plny<47@N5IVQ9`cQU`L*1S{A1^$}1tSIBc=OW(|(hl8e+xlb15- zts~$>qkkppML_Y_-mWQ|-6n5#W>u4B=ThukPNXb$^vS7F&E+S!whQo#R8?B+R?=M7 z>U?)i?6|pB0UYxROdWzCbc@C`r1LlapP2E@D>EeUW?)g{?8y8Dl$K0MOIt@k5esta zFFb?fdO)Z@{}hWlr;7lh+$n4Q)@=icMLjvSwq*8uAZqq59}xO|6Z+r_vk}cv>s2p~Gg{1{YGD)LPoDE|@C`eOQ6* zs`OGhxHZCizr<^;U({!3QrR$5xyiG%z`opU=&euWSuNx!R)g-=3Emn^(n=Jtt-onv zeo~8T^%_QC>l$rcz^h&Yhk6ISuDr^+a$1XR^aY#EZ-LQuG@;v28V(c(NaFnCJ0bO< zT(&6#uTPx68JoX;N7-x+g3roB{Q1}}Ra#1DmzeXi7PA8NKIczoX|Y)eI2U!sc~_q5 zK0?KMza;&8_g;vCex0_3%xXBlQ6~kt~H!IuN(OcGx>!!_U?){(?f7#$sW9 M==9w_?K`piFGRzxBLDyZ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/network/utils.py b/venv/lib/python3.8/site-packages/pip/_internal/network/utils.py deleted file mode 100644 index a19050b..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/network/utils.py +++ /dev/null @@ -1,48 +0,0 @@ -from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response - -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Iterator - - -def response_chunks(response, chunk_size=CONTENT_CHUNK_SIZE): - # type: (Response, int) -> Iterator[bytes] - """Given a requests Response, provide the data chunks. - """ - try: - # Special case for urllib3. - for chunk in response.raw.stream( - chunk_size, - # We use decode_content=False here because we don't - # want urllib3 to mess with the raw bytes we get - # from the server. If we decompress inside of - # urllib3 then we cannot verify the checksum - # because the checksum will be of the compressed - # file. This breakage will only occur if the - # server adds a Content-Encoding header, which - # depends on how the server was configured: - # - Some servers will notice that the file isn't a - # compressible file and will leave the file alone - # and with an empty Content-Encoding - # - Some servers will notice that the file is - # already compressed and will leave the file - # alone and will add a Content-Encoding: gzip - # header - # - Some servers won't notice anything at all and - # will take a file that's already been compressed - # and compress it again and set the - # Content-Encoding: gzip header - # - # By setting this not to decode automatically we - # hope to eliminate problems with the second case. - decode_content=False, - ): - yield chunk - except AttributeError: - # Standard file-like object. - while True: - chunk = response.raw.read(chunk_size) - if not chunk: - break - yield chunk diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 0dbdda8b44405d26de433a9365150f323518d99e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-38.pyc deleted file mode 100644 index 0b6f3017ffa3db6fa00b75e64cda9020e87d8b64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11162 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 Re&--^zbjwi=QDUd@_$SL`sx4x diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 8dad0f76b20887925078785433060fe47228f21e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166 zcmWIL<>g`kg0lr552KczG$)edCIXCP((05h;EmH+?% diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-38.pyc deleted file mode 100644 index e8699a4bf6146fe876278f39bf471699f7a87903..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1208 zcmZux!EW3(5G5(CR^F~_J7^N4E(%@uU@ZzX$t4JixJDABF*dG)Cb}?Mk=~^(kpfBC zu(3Wh*C4-OAM-K&0bYCRt><2nq1L-jfe;YM;hW*iycz1%>S_ zv2OWI)zA8X;mcM2?G?_}Sj<-5p=_Oz-_f9V{__iNbC%mYnQ+N*H2e>URvy`LUDRqA*rFH5cq;+zTd|jj(sg? zd!Hl9xbR2`If&fK9N_ZAb;o&e%ps(;rKPQE$i(%R2VRP<9rbd=)}r2SWbN-`+pW`WGd{GsKE3a;Ar;aB9eFua^>ufeVH?SC;VP}q+{ShD-sEx% ze3(s`P((06}u)&7wQp!|8sp~@5Pk>9^2f+OZ-qWS`6gs~& z=?#Z-Qh)fGl7*i4iOx&#{a01a;HgY>=pEhtzrvDb4gU$`wp#QA$W}V7+b5Bp>bwRr zjP|d9)6uA3~osC4YoLGQJ>T5aXEifuBAJ I+qoBf26HBBIsgCw diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-38.pyc deleted file mode 100644 index 2c913faff7e276c8296c8c52cf2fa901309917c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3268 zcmbtX&2JmW6`z^?;F6|fNmgXpZH;XZ17Q$RMv4?@A_zro#|@gOiHtM}(O|XO8B#0l zS7wHm#V#+A(Iy9@=(Q&i=*53b|AD#olv~dM8uz_jk@~1|2)e?~&c~bKyx;r14}CH> z*CO!zv-tPU@H!#?!om5+g2AuhRey(ulOExevxN3&^<_Nbg{Qst+$e;^hWOn ztkaWa@ydkuR`@mEenxsX`5d2z?TJ zF$kk0U*$s?37^MG%XoK)LaN*P7L+4f9cmWe&y)_6q}u&Z%3Q)^OJr&&MZjYm{VWX+ zM4*Ho7CO%p6^Owgh_ikkgmR!j;CciH1Zucj$UG7Xrq(?K%-A2mWsLXx0xuILu(0r(VVv-X*^^l2St>FeF}&dELi%6~Za?$Jj62+YM#ff2#&$_%w`8S#Ovg^Ps>wb*fe~*^*x1(O#47Cxtdx%W zOxxT$ad3Q0zoObLontV`fh~*D*>98f;C{cpX0uI)S(i5gS;T}27JETUe{@{Uc|-PFe}37K=8H0Jt2}cwcFRS zIQ%89tpg{tkYLdDyf~$!THi&(uBWF=4Qf($izBm=@72^(9+)&d;F!B$<+2)zQe`UPtAQ)o)^ z#WL!I42L_>3Ht+qJ2MU(>d>u@CFen^GNxRF9(W(?-ZM7PGk8IbE%RJgHkQk z8`T&!XD$Y@!V?)+hq2!4Fu97Cru|w2G;^&+Ya;zt01Bf2*PZ-Ok32WZM#jEXqzq2HoZ+p_kOI-7fgjg z35igd>UHRpat_}l98khKoPQLTt~ra|RR5Iw=haD+t1G%lpwG}OjQL}qN2OWkqJ z!sUcuuAR#Q@(tK1yV%^tBbrEoibpjZ9bBngbN-^HE3lyMKtmj_(Z1m|Y--aMn}^q? zjCwEaMjIF)e+3dz6;DwX9)zz6?|pdHE;JYrIrv@aOf0BC*w`&C^(KZy2!V`SkThKg zf$lLTLKoy*2ygatYuqTwUzcI7Q8qvh((iNF|0#K!d`z~F%Aos^d?~m#Rv_bQTVTe^+hEbwC3GWP2)r#540*9t@R`L6m3x zcraS6GwbZ)v*Tc=6&-TZhPac0YX@AYsM9nqlw<=Tjl;$6aBzu15^EZX?jIv|JRy z6uyr^Rv{C~9Fm6-_Py=cwoT`m$6$T{As>Ns=ay*%0nei#09ODt0r5IA zu7a<1X9WRN9T7M)mY%hzTv~>zG*R6&R#AnAdF|rvdih)dTA@>+X6{@mIx9shRL$+H zg!EB?*G1njix&l;Os%83dn$xZBhhQj&5M#VJ4yVn!ZZg$e^8s-3j*}xAds858U3)r n?3^{u5|+1-=6sllO$<3zVz(`idJJ56`Uh^kz}l>3dGG!g=YoNP diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-38.pyc deleted file mode 100644 index 7b4e432fa26b7d17bb911249d2dcda957cd584d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1306 zcmZuxO^+Kj7`Ep-v)N^-Dx`K1ScpoEL?+@;kPt%9uw^Ssx-6>Nodd%p<78)d#xvL+ z!iL!kaNtsL<(M4#5&Q)HfUlgmappjI?S$=C!jYZ4e!rgQv7JZT+aZGSd;Ql}zqttg zp^dA<2IE7R;!9XEl;Hx!>u(%mu&u%>?byb8&n}$Oja`hW%MZYI3a|8IzYOBQ_}!vY zhH(gfwA`ZI6^^$vFY|vy@lJ-nK)v8k=z&H(toC@r80E=4mnVs+b7PcLh;&B5eeJX3 z!{cOlus{4XIeIi2-5-6@vy}577g7ZeYnfLpEg)|9kk)tJe)piN&W34GP(A^Qm&1o& z9hgIy;ulz2E5m0U(Us_X+}iw2iI-MpwP=c8K`RUt0OaB>?An>#Ix7n!>158*ZNd8k zzHnQ-^jdd?f4+`Ui%%x1C?x4@n5qg3iBld=aWN;SppD@xN)5U`tQ196E zc!Ff-G+b^$zPGYK7=Q8fZj%=osTd{qnUFx{h<@GVoR*YH(ukbRh&-X>aQ~11V=^}3 zHLoThS`>x^#u1ebXM)tJJR!0o^Ak!7l23_fCOT}|6ves8lo5Fd)%ZLY^ew_Sc_Zi^ znM$L@y|_xS4Sau7mP`QJG5hvS`K|DU?KeS;)tl5)8EgQ}+7XetJ#)xbnY^|`us1$a`M=dlAF z#BEqmw~HOi!_G6$a3$}UPiIor*;k7^_L=lQm9OnVX2Ahy%5lqI@z3YkRvFh%L zJE^buUY^nbfM zH;K@%YV!PL!sKJP`FAi7L~x2a^%Hjtm>a2?Sse>2nVH&|({VDl<7QsR(=sb}>l_0)Iyg>e4squMaf$Z`b!JI}`0$(~6Ql{x zd4e}lYw`)~1+BHP46uHnab;yg zPRCK2hP>SBvm&OP%M;y#WswNuBFmzj)J9m&e0JyaJK^&6mE}*vjhkz0H`cDfa?PSo z^N{zGJf{p?TdS~|^w#?#De@?l)|d2whz+&7(PhEYhI<)q{w)jwRp=oe8U!EU$~eSB zv%);6Ok#Y9hGu?I7zgGd64pI?$6^;iZff~Lg%2EJ9b*1Tg^2|+4Bu?ZF zBBz6MFG{~IISm#U?^Cu_z?&!nzFq8oBk{jI`1`~CVasDG5z?u*BOSF7%H;7L6)W8? zjYV>wuG0H7mF{Sd(!R2C`Q|n0(VXzzL~JvK#+D_Uqu_M4Lh@19rRmck?#ltDq4px!J}#pO#|Ws;Jm z8d)jrMe$y{zbEJFXvXkil$WWPgSGf949M}YZ&=vJQ}Fb$hmRTT6_Cd&7e|)^FJq7h zn2bOIP~q>7fnry-Feh@2wVGuJK2}**z2)ap1dD~xmf+5^N=YJYz1p}mQM|l8{)IQq&Rq&KY z8Rfy-@pe&gz&3ngT(mTtnOdOLkPa^xtj(G*)fHgCc1XIr5zE0un&3qm1(%kJTw3>v zByTy=)~=nQpsKeNQX5>LY<@$At}%AfC4`Q1M)p= z8OGm+Vfu^f3ga&>Eb&^33E}gIolymLbh}mq>SXh)A0OiC#sF+hFm>KAR}C7{HlbT(kExSKHdY?QREGt;o8$@KW(t7p4fWAY;q-!l zG|E~{?O0CgD8l|;sQbX@Mag2S;$~-+Z)G{dwu~1G-=?`?@!0|p-Z4gjwDZgTlGy7&j7WKrP%nxaoKsW zZJlJ(@Q`l7+j?Og_8Fk~_L$<^rASiVe*Q0nLZ?oueDkHM<3A7jIMRu(kG5A|rY`m% zF+HZ5SkAvpp-gn~q%+d=K$A7ppc-8^fJ|2FqtXjQ#Xe!E3th9AVhA1Vb6HhK9n(zY heUufXOz9=Xf?UZx>={jS)^0)~Ej(-ZrZ?xk`4686)TICb diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/build/metadata_legacy.py b/venv/lib/python3.8/site-packages/pip/_internal/operations/build/metadata_legacy.py deleted file mode 100644 index b6813f8..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/operations/build/metadata_legacy.py +++ /dev/null @@ -1,122 +0,0 @@ -"""Metadata generation logic for legacy source distributions. -""" - -import logging -import os - -from pip._internal.exceptions import InstallationError -from pip._internal.utils.misc import ensure_dir -from pip._internal.utils.setuptools_build import make_setuptools_egg_info_args -from pip._internal.utils.subprocess import call_subprocess -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.vcs import vcs - -if MYPY_CHECK_RUNNING: - from typing import List, Optional - - from pip._internal.build_env import BuildEnvironment - -logger = logging.getLogger(__name__) - - -def _find_egg_info(source_directory, is_editable): - # type: (str, bool) -> str - """Find an .egg-info in `source_directory`, based on `is_editable`. - """ - - def looks_like_virtual_env(path): - # type: (str) -> bool - return ( - os.path.lexists(os.path.join(path, 'bin', 'python')) or - os.path.exists(os.path.join(path, 'Scripts', 'Python.exe')) - ) - - def locate_editable_egg_info(base): - # type: (str) -> List[str] - candidates = [] # type: List[str] - for root, dirs, files in os.walk(base): - for dir_ in vcs.dirnames: - if dir_ in dirs: - dirs.remove(dir_) - # Iterate over a copy of ``dirs``, since mutating - # a list while iterating over it can cause trouble. - # (See https://github.com/pypa/pip/pull/462.) - for dir_ in list(dirs): - if looks_like_virtual_env(os.path.join(root, dir_)): - dirs.remove(dir_) - # Also don't search through tests - elif dir_ == 'test' or dir_ == 'tests': - dirs.remove(dir_) - candidates.extend(os.path.join(root, dir_) for dir_ in dirs) - return [f for f in candidates if f.endswith('.egg-info')] - - def depth_of_directory(dir_): - # type: (str) -> int - return ( - dir_.count(os.path.sep) + - (os.path.altsep and dir_.count(os.path.altsep) or 0) - ) - - base = source_directory - if is_editable: - filenames = locate_editable_egg_info(base) - else: - base = os.path.join(base, 'pip-egg-info') - filenames = os.listdir(base) - - if not filenames: - raise InstallationError( - "Files/directories not found in {}".format(base) - ) - - # If we have more than one match, we pick the toplevel one. This - # can easily be the case if there is a dist folder which contains - # an extracted tarball for testing purposes. - if len(filenames) > 1: - filenames.sort(key=depth_of_directory) - - return os.path.join(base, filenames[0]) - - -def generate_metadata( - build_env, # type: BuildEnvironment - setup_py_path, # type: str - source_dir, # type: str - editable, # type: bool - isolated, # type: bool - details, # type: str -): - # type: (...) -> str - """Generate metadata using setup.py-based defacto mechanisms. - - Returns the generated metadata directory. - """ - logger.debug( - 'Running setup.py (path:%s) egg_info for package %s', - setup_py_path, details, - ) - - egg_info_dir = None # type: Optional[str] - # For non-editable installs, don't put the .egg-info files at the root, - # to avoid confusion due to the source code being considered an installed - # egg. - if not editable: - egg_info_dir = os.path.join(source_dir, 'pip-egg-info') - # setuptools complains if the target directory does not exist. - ensure_dir(egg_info_dir) - - args = make_setuptools_egg_info_args( - setup_py_path, - egg_info_dir=egg_info_dir, - no_user_config=isolated, - ) - - with build_env: - call_subprocess( - args, - cwd=source_dir, - command_desc='python setup.py egg_info', - ) - - # Return the .egg-info directory. - return _find_egg_info(source_dir, editable) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 744d599d981239aea0e3b1017b3c7d28fd6990eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 224 zcmYjLu?oU46imBV3jRaZf^7!DNyN!b7jbckv3b^DnuH{!=pXqp{y+c2yUlQzqJW!u?8afE2L}*Bbr?fEVE}4EC&HC2QK=cNSfk2o5 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-38.pyc deleted file mode 100644 index 854539fbf36cc89beecae48a7620c972e6fe2a7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3048 zcmZuz&2J;O6(>id(MTG7TC%l8rT;?zfZlp73SN8attik-kY@Wxebh-kBfcRYpB~@i`@Khg zQma)EJb%gl`S`Cbg#NAuH=hCw-i5~h1caagBA6Hv9$@`71_pc!Q6V-5CRTH1RE({G zrTfLG6x#z^_pPWLR|XZ`FGbbZ892IcN42;F{fgZ^|Ou8<9_8I;5Rz%VOb5velnsSOH%>E z3ZWUJfiEagqc9;f5nhyz)QBd0!l*|=2BW*Ne@;EETBK>jy_E%?&qf^P_t_*#DDy5t zG4^;C>Ol-v`6CL`wU23>y&u9_B4wArX#e!HpMB=N_mdyK_n~+4$?@?A$3N~Br1>!9 zLfRi?$}c~X_9OaaLX$wLupR|t8mnIWgQfQ;FbOJSusJ9z4_D6)eCyCu*!kBOA%Sw^ z3g_qy&mq(!v@mwi%m6OlaE%og=k{4)Ru(2H5c37T{`0INif7imlvmCyQd}6bs<1&* zIX7~gS3gI2F)!z4ZUL{7mx%SEI&(yol;#d_Y71ClRulCrbp1L;z-e4};9JYpY?Ih8 z42*t(zK4E}PS7uJ^z@poyt=^rZ=yZlB4y~`ko`Tt_z@zN9C;nl&8t`Vx;?As_4)P! z&36`P*0@dUZ_yAyNSx>PteH37N56Vw*3v8O=B)*uwe$A;4gs6Lz-%{f=54Tj3!^Xa zlQFbiu}A94s|6;FwRfaRTBQ9#r486KLbHz6`|hljx90m`M_22=n|HO=-{pFIcJO_e z$vg9VdiFl7)rClGEsO=$>t!(KE)YiIm3-?8cv`NMZxN80ZG*?#q;q9l?`fZ3C0&S5 z2kh$ZfOR)_R9V&AK9==Sl%D#Lmuh5j*;vDO&9DHPDN|Wsof zlVLcL`a>hk|7n57gWd)D1xy z_NO6Q8PFWeA*%PK;N>nHB!KOhgGRaL6*ew0L)|BC{Y z*)y2o?ubIA1JfZy|Npm;a@S|n<&!K+85Gw3^h(7o_Q7*#l<^<9lZ-6?FUBCbuGi_% zefH+8@BRqH6;ePD&>{RlfX(!#26rjyiqws$o{in}B)w1!ty_6XL$=Y~pPFyI*?%ki zbRQyTNL#Wt+A_^kXJWIobsQ}8FcGk--J&h+jDwyg%XfYVad4yN)|I%{3( ztcBR=lUCxPbXG-3yTD#kvJjVq%JK%p(t%`vpbk@Ai^>VT@RlCio6@C=p{`_HhlRZY znwYD|t4e2SwZ1Zx{{{$ZS=f1L8k!a?!@*5#U=!LmU*P=PsvEfS(kv(mkokJA=wJue zu~n>K*KkTUj2vv^iUH3{!!*7!EVE$#$FM;DUslTmy*9jckTP-erCnH$*a=wDyDv+g zN7BIaWJyIIvQk4&)(JpjBEpFG71c#c-iI30-_#&I!Tak=5ZpPILEpbkYOP$ua`!fg zIOM?+2H&}D`o`r+gL;_}_ih!PoUSf)%fz^Qo6rU%D&6GXts<9j6B{vgIg*xG4%Ahd zRTXg*`&+)oDWR}qD>T-W#KAW;1EBlRU=#Hfl&PDREJOZ3T;`tbc`A`Sk3CR}s30u? lrBS7cMwR_GtTl<~JL+uWE)Y|P)&V%(cnuSG6sJ%r{1@_mk&yrZ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-38.pyc deleted file mode 100644 index 38749ad5176a1e267dce5cd41b311e8148fd25ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14582 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 IBZvHd1CEC=mjD0& diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/install/legacy.py b/venv/lib/python3.8/site-packages/pip/_internal/operations/install/legacy.py deleted file mode 100644 index 2d4adc4..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/operations/install/legacy.py +++ /dev/null @@ -1,129 +0,0 @@ -"""Legacy installation process, i.e. `setup.py install`. -""" - -import logging -import os -from distutils.util import change_root - -from pip._internal.utils.deprecation import deprecated -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ensure_dir -from pip._internal.utils.setuptools_build import make_setuptools_install_args -from pip._internal.utils.subprocess import runner_with_spinner_message -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import List, Optional, Sequence - - from pip._internal.models.scheme import Scheme - from pip._internal.req.req_install import InstallRequirement - - -logger = logging.getLogger(__name__) - - -def install( - install_req, # type: InstallRequirement - install_options, # type: List[str] - global_options, # type: Sequence[str] - root, # type: Optional[str] - home, # type: Optional[str] - prefix, # type: Optional[str] - use_user_site, # type: bool - pycompile, # type: bool - scheme, # type: Scheme -): - # type: (...) -> None - # Extend the list of global and install options passed on to - # the setup.py call with the ones from the requirements file. - # Options specified in requirements file override those - # specified on the command line, since the last option given - # to setup.py is the one that is used. - global_options = list(global_options) + \ - install_req.options.get('global_options', []) - install_options = list(install_options) + \ - install_req.options.get('install_options', []) - - header_dir = scheme.headers - - with TempDirectory(kind="record") as temp_dir: - record_filename = os.path.join(temp_dir.path, 'install-record.txt') - install_args = make_setuptools_install_args( - install_req.setup_py_path, - global_options=global_options, - install_options=install_options, - record_filename=record_filename, - root=root, - prefix=prefix, - header_dir=header_dir, - home=home, - use_user_site=use_user_site, - no_user_config=install_req.isolated, - pycompile=pycompile, - ) - - runner = runner_with_spinner_message( - "Running setup.py install for {}".format(install_req.name) - ) - with indent_log(), install_req.build_env: - runner( - cmd=install_args, - cwd=install_req.unpacked_source_directory, - ) - - if not os.path.exists(record_filename): - logger.debug('Record file %s not found', record_filename) - return - install_req.install_succeeded = True - - # We intentionally do not use any encoding to read the file because - # setuptools writes the file using distutils.file_util.write_file, - # which does not specify an encoding. - with open(record_filename) as f: - record_lines = f.read().splitlines() - - def prepend_root(path): - # type: (str) -> str - if root is None or not os.path.isabs(path): - return path - else: - return change_root(root, path) - - for line in record_lines: - directory = os.path.dirname(line) - if directory.endswith('.egg-info'): - egg_info_dir = prepend_root(directory) - break - else: - deprecated( - reason=( - "{} did not indicate that it installed an " - ".egg-info directory. Only setup.py projects " - "generating .egg-info directories are supported." - ).format(install_req), - replacement=( - "for maintainers: updating the setup.py of {0}. " - "For users: contact the maintainers of {0} to let " - "them know to update their setup.py.".format( - install_req.name - ) - ), - gone_in="20.2", - issue=6998, - ) - # FIXME: put the record somewhere - return - new_lines = [] - for line in record_lines: - filename = line.strip() - if os.path.isdir(filename): - filename += os.path.sep - new_lines.append( - os.path.relpath(prepend_root(filename), egg_info_dir) - ) - new_lines.sort() - ensure_dir(egg_info_dir) - inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt') - with open(inst_files_path, 'w') as f: - f.write('\n'.join(new_lines) + '\n') diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/install/wheel.py b/venv/lib/python3.8/site-packages/pip/_internal/operations/install/wheel.py deleted file mode 100644 index aac975c..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/operations/install/wheel.py +++ /dev/null @@ -1,615 +0,0 @@ -"""Support for installing and building the "wheel" binary package format. -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -from __future__ import absolute_import - -import collections -import compileall -import csv -import logging -import os.path -import re -import shutil -import stat -import sys -import warnings -from base64 import urlsafe_b64encode -from zipfile import ZipFile - -from pip._vendor import pkg_resources -from pip._vendor.distlib.scripts import ScriptMaker -from pip._vendor.distlib.util import get_export_entry -from pip._vendor.six import StringIO - -from pip._internal.exceptions import InstallationError -from pip._internal.locations import get_major_minor_version -from pip._internal.utils.misc import captured_stdout, ensure_dir, hash_file -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.unpacking import unpack_file -from pip._internal.utils.wheel import parse_wheel - -if MYPY_CHECK_RUNNING: - from email.message import Message - from typing import ( - Dict, List, Optional, Sequence, Tuple, IO, Text, Any, - Iterable, Callable, Set, - ) - - from pip._internal.models.scheme import Scheme - - InstalledCSVRow = Tuple[str, ...] - - -logger = logging.getLogger(__name__) - - -def normpath(src, p): - # type: (str, str) -> str - return os.path.relpath(src, p).replace(os.path.sep, '/') - - -def rehash(path, blocksize=1 << 20): - # type: (str, int) -> Tuple[str, str] - """Return (encoded_digest, length) for path using hashlib.sha256()""" - h, length = hash_file(path, blocksize) - digest = 'sha256=' + urlsafe_b64encode( - h.digest() - ).decode('latin1').rstrip('=') - # unicode/str python2 issues - return (digest, str(length)) # type: ignore - - -def open_for_csv(name, mode): - # type: (str, Text) -> IO[Any] - if sys.version_info[0] < 3: - nl = {} # type: Dict[str, Any] - bin = 'b' - else: - nl = {'newline': ''} # type: Dict[str, Any] - bin = '' - return open(name, mode + bin, **nl) - - -def fix_script(path): - # type: (str) -> Optional[bool] - """Replace #!python with #!/path/to/python - Return True if file was changed. - """ - # XXX RECORD hashes will need to be updated - if os.path.isfile(path): - with open(path, 'rb') as script: - firstline = script.readline() - if not firstline.startswith(b'#!python'): - return False - exename = sys.executable.encode(sys.getfilesystemencoding()) - firstline = b'#!' + exename + os.linesep.encode("ascii") - rest = script.read() - with open(path, 'wb') as script: - script.write(firstline) - script.write(rest) - return True - return None - - -def wheel_root_is_purelib(metadata): - # type: (Message) -> bool - return metadata.get("Root-Is-Purelib", "").lower() == "true" - - -def get_entrypoints(filename): - # type: (str) -> Tuple[Dict[str, str], Dict[str, str]] - if not os.path.exists(filename): - return {}, {} - - # This is done because you can pass a string to entry_points wrappers which - # means that they may or may not be valid INI files. The attempt here is to - # strip leading and trailing whitespace in order to make them valid INI - # files. - with open(filename) as fp: - data = StringIO() - for line in fp: - data.write(line.strip()) - data.write("\n") - data.seek(0) - - # get the entry points and then the script names - entry_points = pkg_resources.EntryPoint.parse_map(data) - console = entry_points.get('console_scripts', {}) - gui = entry_points.get('gui_scripts', {}) - - def _split_ep(s): - # type: (pkg_resources.EntryPoint) -> Tuple[str, str] - """get the string representation of EntryPoint, - remove space and split on '=' - """ - split_parts = str(s).replace(" ", "").split("=") - return split_parts[0], split_parts[1] - - # convert the EntryPoint objects into strings with module:function - console = dict(_split_ep(v) for v in console.values()) - gui = dict(_split_ep(v) for v in gui.values()) - return console, gui - - -def message_about_scripts_not_on_PATH(scripts): - # type: (Sequence[str]) -> Optional[str] - """Determine if any scripts are not on PATH and format a warning. - Returns a warning message if one or more scripts are not on PATH, - otherwise None. - """ - if not scripts: - return None - - # Group scripts by the path they were installed in - grouped_by_dir = collections.defaultdict(set) # type: Dict[str, Set[str]] - for destfile in scripts: - parent_dir = os.path.dirname(destfile) - script_name = os.path.basename(destfile) - grouped_by_dir[parent_dir].add(script_name) - - # We don't want to warn for directories that are on PATH. - not_warn_dirs = [ - os.path.normcase(i).rstrip(os.sep) for i in - os.environ.get("PATH", "").split(os.pathsep) - ] - # If an executable sits with sys.executable, we don't warn for it. - # This covers the case of venv invocations without activating the venv. - not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable))) - warn_for = { - parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items() - if os.path.normcase(parent_dir) not in not_warn_dirs - } # type: Dict[str, Set[str]] - if not warn_for: - return None - - # Format a message - msg_lines = [] - for parent_dir, dir_scripts in warn_for.items(): - sorted_scripts = sorted(dir_scripts) # type: List[str] - if len(sorted_scripts) == 1: - start_text = "script {} is".format(sorted_scripts[0]) - else: - start_text = "scripts {} are".format( - ", ".join(sorted_scripts[:-1]) + " and " + sorted_scripts[-1] - ) - - msg_lines.append( - "The {} installed in '{}' which is not on PATH." - .format(start_text, parent_dir) - ) - - last_line_fmt = ( - "Consider adding {} to PATH or, if you prefer " - "to suppress this warning, use --no-warn-script-location." - ) - if len(msg_lines) == 1: - msg_lines.append(last_line_fmt.format("this directory")) - else: - msg_lines.append(last_line_fmt.format("these directories")) - - # Add a note if any directory starts with ~ - warn_for_tilde = any( - i[0] == "~" for i in os.environ.get("PATH", "").split(os.pathsep) if i - ) - if warn_for_tilde: - tilde_warning_msg = ( - "NOTE: The current PATH contains path(s) starting with `~`, " - "which may not be expanded by all applications." - ) - msg_lines.append(tilde_warning_msg) - - # Returns the formatted multiline message - return "\n".join(msg_lines) - - -def sorted_outrows(outrows): - # type: (Iterable[InstalledCSVRow]) -> List[InstalledCSVRow] - """Return the given rows of a RECORD file in sorted order. - - Each row is a 3-tuple (path, hash, size) and corresponds to a record of - a RECORD file (see PEP 376 and PEP 427 for details). For the rows - passed to this function, the size can be an integer as an int or string, - or the empty string. - """ - # Normally, there should only be one row per path, in which case the - # second and third elements don't come into play when sorting. - # However, in cases in the wild where a path might happen to occur twice, - # we don't want the sort operation to trigger an error (but still want - # determinism). Since the third element can be an int or string, we - # coerce each element to a string to avoid a TypeError in this case. - # For additional background, see-- - # https://github.com/pypa/pip/issues/5868 - return sorted(outrows, key=lambda row: tuple(str(x) for x in row)) - - -def get_csv_rows_for_installed( - old_csv_rows, # type: Iterable[List[str]] - installed, # type: Dict[str, str] - changed, # type: Set[str] - generated, # type: List[str] - lib_dir, # type: str -): - # type: (...) -> List[InstalledCSVRow] - """ - :param installed: A map from archive RECORD path to installation RECORD - path. - """ - installed_rows = [] # type: List[InstalledCSVRow] - for row in old_csv_rows: - if len(row) > 3: - logger.warning( - 'RECORD line has more than three elements: {}'.format(row) - ) - # Make a copy because we are mutating the row. - row = list(row) - old_path = row[0] - new_path = installed.pop(old_path, old_path) - row[0] = new_path - if new_path in changed: - digest, length = rehash(new_path) - row[1] = digest - row[2] = length - installed_rows.append(tuple(row)) - for f in generated: - digest, length = rehash(f) - installed_rows.append((normpath(f, lib_dir), digest, str(length))) - for f in installed: - installed_rows.append((installed[f], '', '')) - return installed_rows - - -class MissingCallableSuffix(Exception): - pass - - -def _raise_for_invalid_entrypoint(specification): - # type: (str) -> None - entry = get_export_entry(specification) - if entry is not None and entry.suffix is None: - raise MissingCallableSuffix(str(entry)) - - -class PipScriptMaker(ScriptMaker): - def make(self, specification, options=None): - # type: (str, Dict[str, Any]) -> List[str] - _raise_for_invalid_entrypoint(specification) - return super(PipScriptMaker, self).make(specification, options) - - -def install_unpacked_wheel( - name, # type: str - wheeldir, # type: str - wheel_zip, # type: ZipFile - scheme, # type: Scheme - req_description, # type: str - pycompile=True, # type: bool - warn_script_location=True # type: bool -): - # type: (...) -> None - """Install a wheel. - - :param name: Name of the project to install - :param wheeldir: Base directory of the unpacked wheel - :param wheel_zip: open ZipFile for wheel being installed - :param scheme: Distutils scheme dictating the install directories - :param req_description: String used in place of the requirement, for - logging - :param pycompile: Whether to byte-compile installed Python files - :param warn_script_location: Whether to check that scripts are installed - into a directory on PATH - :raises UnsupportedWheel: - * when the directory holds an unpacked wheel with incompatible - Wheel-Version - * when the .dist-info dir does not match the wheel - """ - # TODO: Investigate and break this up. - # TODO: Look into moving this into a dedicated class for representing an - # installation. - - source = wheeldir.rstrip(os.path.sep) + os.path.sep - - info_dir, metadata = parse_wheel(wheel_zip, name) - - if wheel_root_is_purelib(metadata): - lib_dir = scheme.purelib - else: - lib_dir = scheme.platlib - - subdirs = os.listdir(source) - data_dirs = [s for s in subdirs if s.endswith('.data')] - - # Record details of the files moved - # installed = files copied from the wheel to the destination - # changed = files changed while installing (scripts #! line typically) - # generated = files newly generated during the install (script wrappers) - installed = {} # type: Dict[str, str] - changed = set() - generated = [] # type: List[str] - - # Compile all of the pyc files that we're going to be installing - if pycompile: - with captured_stdout() as stdout: - with warnings.catch_warnings(): - warnings.filterwarnings('ignore') - compileall.compile_dir(source, force=True, quiet=True) - logger.debug(stdout.getvalue()) - - def record_installed(srcfile, destfile, modified=False): - # type: (str, str, bool) -> None - """Map archive RECORD paths to installation RECORD paths.""" - oldpath = normpath(srcfile, wheeldir) - newpath = normpath(destfile, lib_dir) - installed[oldpath] = newpath - if modified: - changed.add(destfile) - - def clobber( - source, # type: str - dest, # type: str - is_base, # type: bool - fixer=None, # type: Optional[Callable[[str], Any]] - filter=None # type: Optional[Callable[[str], bool]] - ): - # type: (...) -> None - ensure_dir(dest) # common for the 'include' path - - for dir, subdirs, files in os.walk(source): - basedir = dir[len(source):].lstrip(os.path.sep) - destdir = os.path.join(dest, basedir) - if is_base and basedir == '': - subdirs[:] = [s for s in subdirs if not s.endswith('.data')] - for f in files: - # Skip unwanted files - if filter and filter(f): - continue - srcfile = os.path.join(dir, f) - destfile = os.path.join(dest, basedir, f) - # directory creation is lazy and after the file filtering above - # to ensure we don't install empty dirs; empty dirs can't be - # uninstalled. - ensure_dir(destdir) - - # copyfile (called below) truncates the destination if it - # exists and then writes the new contents. This is fine in most - # cases, but can cause a segfault if pip has loaded a shared - # object (e.g. from pyopenssl through its vendored urllib3) - # Since the shared object is mmap'd an attempt to call a - # symbol in it will then cause a segfault. Unlinking the file - # allows writing of new contents while allowing the process to - # continue to use the old copy. - if os.path.exists(destfile): - os.unlink(destfile) - - # We use copyfile (not move, copy, or copy2) to be extra sure - # that we are not moving directories over (copyfile fails for - # directories) as well as to ensure that we are not copying - # over any metadata because we want more control over what - # metadata we actually copy over. - shutil.copyfile(srcfile, destfile) - - # Copy over the metadata for the file, currently this only - # includes the atime and mtime. - st = os.stat(srcfile) - if hasattr(os, "utime"): - os.utime(destfile, (st.st_atime, st.st_mtime)) - - # If our file is executable, then make our destination file - # executable. - if os.access(srcfile, os.X_OK): - st = os.stat(srcfile) - permissions = ( - st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH - ) - os.chmod(destfile, permissions) - - changed = False - if fixer: - changed = fixer(destfile) - record_installed(srcfile, destfile, changed) - - clobber(source, lib_dir, True) - - dest_info_dir = os.path.join(lib_dir, info_dir) - - # Get the defined entry points - ep_file = os.path.join(dest_info_dir, 'entry_points.txt') - console, gui = get_entrypoints(ep_file) - - def is_entrypoint_wrapper(name): - # type: (str) -> bool - # EP, EP.exe and EP-script.py are scripts generated for - # entry point EP by setuptools - if name.lower().endswith('.exe'): - matchname = name[:-4] - elif name.lower().endswith('-script.py'): - matchname = name[:-10] - elif name.lower().endswith(".pya"): - matchname = name[:-4] - else: - matchname = name - # Ignore setuptools-generated scripts - return (matchname in console or matchname in gui) - - for datadir in data_dirs: - fixer = None - filter = None - for subdir in os.listdir(os.path.join(wheeldir, datadir)): - fixer = None - if subdir == 'scripts': - fixer = fix_script - filter = is_entrypoint_wrapper - source = os.path.join(wheeldir, datadir, subdir) - dest = getattr(scheme, subdir) - clobber(source, dest, False, fixer=fixer, filter=filter) - - maker = PipScriptMaker(None, scheme.scripts) - - # Ensure old scripts are overwritten. - # See https://github.com/pypa/pip/issues/1800 - maker.clobber = True - - # Ensure we don't generate any variants for scripts because this is almost - # never what somebody wants. - # See https://bitbucket.org/pypa/distlib/issue/35/ - maker.variants = {''} - - # This is required because otherwise distlib creates scripts that are not - # executable. - # See https://bitbucket.org/pypa/distlib/issue/32/ - maker.set_mode = True - - scripts_to_generate = [] - - # Special case pip and setuptools to generate versioned wrappers - # - # The issue is that some projects (specifically, pip and setuptools) use - # code in setup.py to create "versioned" entry points - pip2.7 on Python - # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into - # the wheel metadata at build time, and so if the wheel is installed with - # a *different* version of Python the entry points will be wrong. The - # correct fix for this is to enhance the metadata to be able to describe - # such versioned entry points, but that won't happen till Metadata 2.0 is - # available. - # In the meantime, projects using versioned entry points will either have - # incorrect versioned entry points, or they will not be able to distribute - # "universal" wheels (i.e., they will need a wheel per Python version). - # - # Because setuptools and pip are bundled with _ensurepip and virtualenv, - # we need to use universal wheels. So, as a stopgap until Metadata 2.0, we - # override the versioned entry points in the wheel and generate the - # correct ones. This code is purely a short-term measure until Metadata 2.0 - # is available. - # - # To add the level of hack in this section of code, in order to support - # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment - # variable which will control which version scripts get installed. - # - # ENSUREPIP_OPTIONS=altinstall - # - Only pipX.Y and easy_install-X.Y will be generated and installed - # ENSUREPIP_OPTIONS=install - # - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note - # that this option is technically if ENSUREPIP_OPTIONS is set and is - # not altinstall - # DEFAULT - # - The default behavior is to install pip, pipX, pipX.Y, easy_install - # and easy_install-X.Y. - pip_script = console.pop('pip', None) - if pip_script: - if "ENSUREPIP_OPTIONS" not in os.environ: - scripts_to_generate.append('pip = ' + pip_script) - - if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall": - scripts_to_generate.append( - 'pip%s = %s' % (sys.version_info[0], pip_script) - ) - - scripts_to_generate.append( - 'pip%s = %s' % (get_major_minor_version(), pip_script) - ) - # Delete any other versioned pip entry points - pip_ep = [k for k in console if re.match(r'pip(\d(\.\d)?)?$', k)] - for k in pip_ep: - del console[k] - easy_install_script = console.pop('easy_install', None) - if easy_install_script: - if "ENSUREPIP_OPTIONS" not in os.environ: - scripts_to_generate.append( - 'easy_install = ' + easy_install_script - ) - - scripts_to_generate.append( - 'easy_install-%s = %s' % ( - get_major_minor_version(), easy_install_script - ) - ) - # Delete any other versioned easy_install entry points - easy_install_ep = [ - k for k in console if re.match(r'easy_install(-\d\.\d)?$', k) - ] - for k in easy_install_ep: - del console[k] - - # Generate the console and GUI entry points specified in the wheel - scripts_to_generate.extend( - '%s = %s' % kv for kv in console.items() - ) - - gui_scripts_to_generate = [ - '%s = %s' % kv for kv in gui.items() - ] - - generated_console_scripts = [] # type: List[str] - - try: - generated_console_scripts = maker.make_multiple(scripts_to_generate) - generated.extend(generated_console_scripts) - - generated.extend( - maker.make_multiple(gui_scripts_to_generate, {'gui': True}) - ) - except MissingCallableSuffix as e: - entry = e.args[0] - raise InstallationError( - "Invalid script entry point: {} for req: {} - A callable " - "suffix is required. Cf https://packaging.python.org/" - "specifications/entry-points/#use-for-scripts for more " - "information.".format(entry, req_description) - ) - - if warn_script_location: - msg = message_about_scripts_not_on_PATH(generated_console_scripts) - if msg is not None: - logger.warning(msg) - - # Record pip as the installer - installer = os.path.join(dest_info_dir, 'INSTALLER') - temp_installer = os.path.join(dest_info_dir, 'INSTALLER.pip') - with open(temp_installer, 'wb') as installer_file: - installer_file.write(b'pip\n') - shutil.move(temp_installer, installer) - generated.append(installer) - - # Record details of all files installed - record = os.path.join(dest_info_dir, 'RECORD') - temp_record = os.path.join(dest_info_dir, 'RECORD.pip') - with open_for_csv(record, 'r') as record_in: - with open_for_csv(temp_record, 'w+') as record_out: - reader = csv.reader(record_in) - outrows = get_csv_rows_for_installed( - reader, installed=installed, changed=changed, - generated=generated, lib_dir=lib_dir, - ) - writer = csv.writer(record_out) - # Sort to simplify testing. - for row in sorted_outrows(outrows): - writer.writerow(row) - shutil.move(temp_record, record) - - -def install_wheel( - name, # type: str - wheel_path, # type: str - scheme, # type: Scheme - req_description, # type: str - pycompile=True, # type: bool - warn_script_location=True, # type: bool - _temp_dir_for_testing=None, # type: Optional[str] -): - # type: (...) -> None - with TempDirectory( - path=_temp_dir_for_testing, kind="unpacked-wheel" - ) as unpacked_dir, ZipFile(wheel_path, allowZip64=True) as z: - unpack_file(wheel_path, unpacked_dir.path) - install_unpacked_wheel( - name=name, - wheeldir=unpacked_dir.path, - wheel_zip=z, - scheme=scheme, - req_description=req_description, - pycompile=pycompile, - warn_script_location=warn_script_location, - ) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/prepare.py b/venv/lib/python3.8/site-packages/pip/_internal/operations/prepare.py deleted file mode 100644 index 0b61f20..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/operations/prepare.py +++ /dev/null @@ -1,591 +0,0 @@ -"""Prepares a distribution for installation -""" - -# The following comment should be removed at some point in the future. -# mypy: strict-optional=False - -import logging -import mimetypes -import os -import shutil -import sys - -from pip._vendor import requests -from pip._vendor.six import PY2 - -from pip._internal.distributions import ( - make_distribution_for_install_requirement, -) -from pip._internal.distributions.installed import InstalledDistribution -from pip._internal.exceptions import ( - DirectoryUrlHashUnsupported, - HashMismatch, - HashUnpinned, - InstallationError, - PreviousBuildDirError, - VcsHashUnsupported, -) -from pip._internal.utils.filesystem import copy2_fixed -from pip._internal.utils.hashes import MissingHashes -from pip._internal.utils.logging import indent_log -from pip._internal.utils.marker_files import write_delete_marker_file -from pip._internal.utils.misc import ( - ask_path_exists, - backup_dir, - display_path, - hide_url, - path_to_display, - rmtree, -) -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.unpacking import unpack_file -from pip._internal.vcs import vcs - -if MYPY_CHECK_RUNNING: - from typing import ( - Callable, List, Optional, Tuple, - ) - - from mypy_extensions import TypedDict - - from pip._internal.distributions import AbstractDistribution - from pip._internal.index.package_finder import PackageFinder - from pip._internal.models.link import Link - from pip._internal.network.download import Downloader - from pip._internal.req.req_install import InstallRequirement - from pip._internal.req.req_tracker import RequirementTracker - from pip._internal.utils.hashes import Hashes - - if PY2: - CopytreeKwargs = TypedDict( - 'CopytreeKwargs', - { - 'ignore': Callable[[str, List[str]], List[str]], - 'symlinks': bool, - }, - total=False, - ) - else: - CopytreeKwargs = TypedDict( - 'CopytreeKwargs', - { - 'copy_function': Callable[[str, str], None], - 'ignore': Callable[[str, List[str]], List[str]], - 'ignore_dangling_symlinks': bool, - 'symlinks': bool, - }, - total=False, - ) - -logger = logging.getLogger(__name__) - - -def _get_prepared_distribution( - req, # type: InstallRequirement - req_tracker, # type: RequirementTracker - finder, # type: PackageFinder - build_isolation # type: bool -): - # type: (...) -> AbstractDistribution - """Prepare a distribution for installation. - """ - abstract_dist = make_distribution_for_install_requirement(req) - with req_tracker.track(req): - abstract_dist.prepare_distribution_metadata(finder, build_isolation) - return abstract_dist - - -def unpack_vcs_link(link, location): - # type: (Link, str) -> None - vcs_backend = vcs.get_backend_for_scheme(link.scheme) - assert vcs_backend is not None - vcs_backend.unpack(location, url=hide_url(link.url)) - - -def _copy_file(filename, location, link): - # type: (str, str, Link) -> None - copy = True - download_location = os.path.join(location, link.filename) - if os.path.exists(download_location): - response = ask_path_exists( - 'The file {} exists. (i)gnore, (w)ipe, (b)ackup, (a)abort'.format( - display_path(download_location) - ), - ('i', 'w', 'b', 'a'), - ) - if response == 'i': - copy = False - elif response == 'w': - logger.warning('Deleting %s', display_path(download_location)) - os.remove(download_location) - elif response == 'b': - dest_file = backup_dir(download_location) - logger.warning( - 'Backing up %s to %s', - display_path(download_location), - display_path(dest_file), - ) - shutil.move(download_location, dest_file) - elif response == 'a': - sys.exit(-1) - if copy: - shutil.copy(filename, download_location) - logger.info('Saved %s', display_path(download_location)) - - -def unpack_http_url( - link, # type: Link - location, # type: str - downloader, # type: Downloader - download_dir=None, # type: Optional[str] - hashes=None, # type: Optional[Hashes] -): - # type: (...) -> str - temp_dir = TempDirectory(kind="unpack", globally_managed=True) - # If a download dir is specified, is the file already downloaded there? - already_downloaded_path = None - if download_dir: - already_downloaded_path = _check_download_dir( - link, download_dir, hashes - ) - - if already_downloaded_path: - from_path = already_downloaded_path - content_type = mimetypes.guess_type(from_path)[0] - else: - # let's download to a tmp dir - from_path, content_type = _download_http_url( - link, downloader, temp_dir.path, hashes - ) - - # unpack the archive to the build dir location. even when only - # downloading archives, they have to be unpacked to parse dependencies - unpack_file(from_path, location, content_type) - - return from_path - - -def _copy2_ignoring_special_files(src, dest): - # type: (str, str) -> None - """Copying special files is not supported, but as a convenience to users - we skip errors copying them. This supports tools that may create e.g. - socket files in the project source directory. - """ - try: - copy2_fixed(src, dest) - except shutil.SpecialFileError as e: - # SpecialFileError may be raised due to either the source or - # destination. If the destination was the cause then we would actually - # care, but since the destination directory is deleted prior to - # copy we ignore all of them assuming it is caused by the source. - logger.warning( - "Ignoring special file error '%s' encountered copying %s to %s.", - str(e), - path_to_display(src), - path_to_display(dest), - ) - - -def _copy_source_tree(source, target): - # type: (str, str) -> None - def ignore(d, names): - # type: (str, List[str]) -> List[str] - # Pulling in those directories can potentially be very slow, - # exclude the following directories if they appear in the top - # level dir (and only it). - # See discussion at https://github.com/pypa/pip/pull/6770 - return ['.tox', '.nox'] if d == source else [] - - kwargs = dict(ignore=ignore, symlinks=True) # type: CopytreeKwargs - - if not PY2: - # Python 2 does not support copy_function, so we only ignore - # errors on special file copy in Python 3. - kwargs['copy_function'] = _copy2_ignoring_special_files - - shutil.copytree(source, target, **kwargs) - - -def unpack_file_url( - link, # type: Link - location, # type: str - download_dir=None, # type: Optional[str] - hashes=None # type: Optional[Hashes] -): - # type: (...) -> Optional[str] - """Unpack link into location. - """ - link_path = link.file_path - # If it's a url to a local directory - if link.is_existing_dir(): - if os.path.isdir(location): - rmtree(location) - _copy_source_tree(link_path, location) - return None - - # If a download dir is specified, is the file already there and valid? - already_downloaded_path = None - if download_dir: - already_downloaded_path = _check_download_dir( - link, download_dir, hashes - ) - - if already_downloaded_path: - from_path = already_downloaded_path - else: - from_path = link_path - - # If --require-hashes is off, `hashes` is either empty, the - # link's embedded hash, or MissingHashes; it is required to - # match. If --require-hashes is on, we are satisfied by any - # hash in `hashes` matching: a URL-based or an option-based - # one; no internet-sourced hash will be in `hashes`. - if hashes: - hashes.check_against_path(from_path) - - content_type = mimetypes.guess_type(from_path)[0] - - # unpack the archive to the build dir location. even when only downloading - # archives, they have to be unpacked to parse dependencies - unpack_file(from_path, location, content_type) - - return from_path - - -def unpack_url( - link, # type: Link - location, # type: str - downloader, # type: Downloader - download_dir=None, # type: Optional[str] - hashes=None, # type: Optional[Hashes] -): - # type: (...) -> Optional[str] - """Unpack link into location, downloading if required. - - :param hashes: A Hashes object, one of whose embedded hashes must match, - or HashMismatch will be raised. If the Hashes is empty, no matches are - required, and unhashable types of requirements (like VCS ones, which - would ordinarily raise HashUnsupported) are allowed. - """ - # non-editable vcs urls - if link.is_vcs: - unpack_vcs_link(link, location) - return None - - # file urls - elif link.is_file: - return unpack_file_url(link, location, download_dir, hashes=hashes) - - # http urls - else: - return unpack_http_url( - link, - location, - downloader, - download_dir, - hashes=hashes, - ) - - -def _download_http_url( - link, # type: Link - downloader, # type: Downloader - temp_dir, # type: str - hashes, # type: Optional[Hashes] -): - # type: (...) -> Tuple[str, str] - """Download link url into temp_dir using provided session""" - download = downloader(link) - - file_path = os.path.join(temp_dir, download.filename) - with open(file_path, 'wb') as content_file: - for chunk in download.chunks: - content_file.write(chunk) - - if hashes: - hashes.check_against_path(file_path) - - return file_path, download.response.headers.get('content-type', '') - - -def _check_download_dir(link, download_dir, hashes): - # type: (Link, str, Optional[Hashes]) -> Optional[str] - """ Check download_dir for previously downloaded file with correct hash - If a correct file is found return its path else None - """ - download_path = os.path.join(download_dir, link.filename) - - if not os.path.exists(download_path): - return None - - # If already downloaded, does its hash match? - logger.info('File was already downloaded %s', download_path) - if hashes: - try: - hashes.check_against_path(download_path) - except HashMismatch: - logger.warning( - 'Previously-downloaded file %s has bad hash. ' - 'Re-downloading.', - download_path - ) - os.unlink(download_path) - return None - return download_path - - -class RequirementPreparer(object): - """Prepares a Requirement - """ - - def __init__( - self, - build_dir, # type: str - download_dir, # type: Optional[str] - src_dir, # type: str - wheel_download_dir, # type: Optional[str] - build_isolation, # type: bool - req_tracker, # type: RequirementTracker - downloader, # type: Downloader - finder, # type: PackageFinder - require_hashes, # type: bool - use_user_site, # type: bool - ): - # type: (...) -> None - super(RequirementPreparer, self).__init__() - - self.src_dir = src_dir - self.build_dir = build_dir - self.req_tracker = req_tracker - self.downloader = downloader - self.finder = finder - - # Where still-packed archives should be written to. If None, they are - # not saved, and are deleted immediately after unpacking. - self.download_dir = download_dir - - # Where still-packed .whl files should be written to. If None, they are - # written to the download_dir parameter. Separate to download_dir to - # permit only keeping wheel archives for pip wheel. - self.wheel_download_dir = wheel_download_dir - - # NOTE - # download_dir and wheel_download_dir overlap semantically and may - # be combined if we're willing to have non-wheel archives present in - # the wheelhouse output by 'pip wheel'. - - # Is build isolation allowed? - self.build_isolation = build_isolation - - # Should hash-checking be required? - self.require_hashes = require_hashes - - # Should install in user site-packages? - self.use_user_site = use_user_site - - @property - def _download_should_save(self): - # type: () -> bool - if not self.download_dir: - return False - - if os.path.exists(self.download_dir): - return True - - logger.critical('Could not find download directory') - raise InstallationError( - "Could not find or access download directory '{}'" - .format(self.download_dir)) - - def prepare_linked_requirement( - self, - req, # type: InstallRequirement - ): - # type: (...) -> AbstractDistribution - """Prepare a requirement that would be obtained from req.link - """ - assert req.link - link = req.link - - # TODO: Breakup into smaller functions - if link.scheme == 'file': - path = link.file_path - logger.info('Processing %s', display_path(path)) - else: - logger.info('Collecting %s', req.req or req) - - with indent_log(): - # @@ if filesystem packages are not marked - # editable in a req, a non deterministic error - # occurs when the script attempts to unpack the - # build directory - # Since source_dir is only set for editable requirements. - assert req.source_dir is None - req.ensure_has_source_dir(self.build_dir) - # If a checkout exists, it's unwise to keep going. version - # inconsistencies are logged later, but do not fail the - # installation. - # FIXME: this won't upgrade when there's an existing - # package unpacked in `req.source_dir` - if os.path.exists(os.path.join(req.source_dir, 'setup.py')): - raise PreviousBuildDirError( - "pip can't proceed with requirements '{}' due to a" - " pre-existing build directory ({}). This is " - "likely due to a previous installation that failed" - ". pip is being responsible and not assuming it " - "can delete this. Please delete it and try again." - .format(req, req.source_dir) - ) - - # Now that we have the real link, we can tell what kind of - # requirements we have and raise some more informative errors - # than otherwise. (For example, we can raise VcsHashUnsupported - # for a VCS URL rather than HashMissing.) - if self.require_hashes: - # We could check these first 2 conditions inside - # unpack_url and save repetition of conditions, but then - # we would report less-useful error messages for - # unhashable requirements, complaining that there's no - # hash provided. - if link.is_vcs: - raise VcsHashUnsupported() - elif link.is_existing_dir(): - raise DirectoryUrlHashUnsupported() - if not req.original_link and not req.is_pinned: - # Unpinned packages are asking for trouble when a new - # version is uploaded. This isn't a security check, but - # it saves users a surprising hash mismatch in the - # future. - # - # file:/// URLs aren't pinnable, so don't complain - # about them not being pinned. - raise HashUnpinned() - - hashes = req.hashes(trust_internet=not self.require_hashes) - if self.require_hashes and not hashes: - # Known-good hashes are missing for this requirement, so - # shim it with a facade object that will provoke hash - # computation and then raise a HashMissing exception - # showing the user what the hash should be. - hashes = MissingHashes() - - download_dir = self.download_dir - if link.is_wheel and self.wheel_download_dir: - # when doing 'pip wheel` we download wheels to a - # dedicated dir. - download_dir = self.wheel_download_dir - - try: - local_path = unpack_url( - link, req.source_dir, self.downloader, download_dir, - hashes=hashes, - ) - except requests.HTTPError as exc: - logger.critical( - 'Could not install requirement %s because of error %s', - req, - exc, - ) - raise InstallationError( - 'Could not install requirement {} because of HTTP ' - 'error {} for URL {}'.format(req, exc, link) - ) - - # For use in later processing, preserve the file path on the - # requirement. - if local_path: - req.local_file_path = local_path - - if link.is_wheel: - if download_dir: - # When downloading, we only unpack wheels to get - # metadata. - autodelete_unpacked = True - else: - # When installing a wheel, we use the unpacked - # wheel. - autodelete_unpacked = False - else: - # We always delete unpacked sdists after pip runs. - autodelete_unpacked = True - if autodelete_unpacked: - write_delete_marker_file(req.source_dir) - - abstract_dist = _get_prepared_distribution( - req, self.req_tracker, self.finder, self.build_isolation, - ) - - if download_dir: - if link.is_existing_dir(): - logger.info('Link is a directory, ignoring download_dir') - elif local_path and not os.path.exists( - os.path.join(download_dir, link.filename) - ): - _copy_file(local_path, download_dir, link) - - if self._download_should_save: - # Make a .zip of the source_dir we already created. - if link.is_vcs: - req.archive(self.download_dir) - return abstract_dist - - def prepare_editable_requirement( - self, - req, # type: InstallRequirement - ): - # type: (...) -> AbstractDistribution - """Prepare an editable requirement - """ - assert req.editable, "cannot prepare a non-editable req as editable" - - logger.info('Obtaining %s', req) - - with indent_log(): - if self.require_hashes: - raise InstallationError( - 'The editable requirement {} cannot be installed when ' - 'requiring hashes, because there is no single file to ' - 'hash.'.format(req) - ) - req.ensure_has_source_dir(self.src_dir) - req.update_editable(not self._download_should_save) - - abstract_dist = _get_prepared_distribution( - req, self.req_tracker, self.finder, self.build_isolation, - ) - - if self._download_should_save: - req.archive(self.download_dir) - req.check_if_exists(self.use_user_site) - - return abstract_dist - - def prepare_installed_requirement( - self, - req, # type: InstallRequirement - skip_reason # type: str - ): - # type: (...) -> AbstractDistribution - """Prepare an already-installed requirement - """ - assert req.satisfied_by, "req should have been satisfied but isn't" - assert skip_reason is not None, ( - "did not get skip reason skipped but req.satisfied_by " - "is set to {}".format(req.satisfied_by) - ) - logger.info( - 'Requirement %s: %s (%s)', - skip_reason, req, req.satisfied_by.version - ) - with indent_log(): - if self.require_hashes: - logger.debug( - 'Since it is already installed, we are trusting this ' - 'package without checking its hash. To ensure a ' - 'completely repeatable environment, install into an ' - 'empty virtualenv.' - ) - abstract_dist = InstalledDistribution(req) - - return abstract_dist diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index ac85ff047e40b90b42ab859685990c1b10432e6f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2194 zcmaJCO>Y}TbY^zFUT^%7IBlu=AzTEgmZ;N9IiM1?YO7Kx1`?{aD^<(JGqyL~ugs1c zV(bg;6%bd1P;zT8oH+3dxbO$&%7xxIBN}*b?M+jP7;E0XdGp?z_w8G?nnPgyn*Q-w z0@!bOIJ`_aT!Ni_4}cR+LlRM!Qp8!vTn1kwG$PYAbD9~JBFnV^FL5g@N49I{csZ;@ zj_c&O9WF#ww@Qhy8&ow5e|R8(9*Ll<3Ot_i)G83K@TcbdV2xKx8xDjW{55u+RWT4g$9oL0w z8``)W?`ZR8kST4i1FwjCLfW8NmJwJ0bTgRg@&>^J5#vi)59lu}2B%A~vr_;BaVaMd zY0B9n;u_rGCVWj^0sXu=Uqlp>X$_bQzJ-^3YTw_QRZe8=;& z<9SiSM&)XXL;p|2(<6}o(d=Y~x@mW~|Z~}IQ{bf_z%qh8DJ@mO)n6CxcAHmLk z2QVSBrN}PDV%TM~QkamdeCl5c*ZzatPhC*R|HZgu+6Z30m`P(EuZxUtScjS+h;14w? z-vO*t$<&_M^6{j+>+HeJm*g&qPu!Vt{EQsa%A_KHf%^r#pOkj1ss{8DT29H<`RA`s zu(0j%$Z5fv=eQ*v2)Uz%K|E*$aZ3$FEAO9H2+h`Ua@MmdX>EvB4;oeQmfwe}Yz_Sf zD8iHNI81zw^q9Aba?bT&W%~n>wR0uoGxHZwte1eQo&u?Y>7CXa*_gf6dZALWvN3Dx zm?g~b0Ahd7nbHZ}B;T?vbA4WSb-07NWS#TcfM)r3F*+B~n_d#7s~1oe7Ka7RJAN~G zX=ZdTh6#9@tpZXAjgMbeN<^tb+eh(S2u=PJ##PlHsl@9gaX*kzyRI!5h65qB8N~fW zo0~}xOY}l7X2WC@a%haXhP;7v4l-@s-_F04IXgVF0HG|V zwO&53QgAQz)i4uEHwupmdunsS%&dRqLE^A^9TV_A08%%pNf~YKnK&q^7=t2X8$)Bog&Ej-;gdN1;Ud5 zGihrsTLD>#^G4#p(PhtrK7z4U83=VVuM~L9FV2SJ gD%zF32B6ApR;5+k08M(tV1!ZF5M0MttdVE`0IoPi2LJ#7 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/constructors.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/constructors.cpython-38.pyc deleted file mode 100644 index b16e945fe5c420361f03b79d33553ff0ae0c6231..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10363 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 Rb7QDX*Z#|WIe-42{{xt7-DCg& diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_file.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_file.cpython-38.pyc deleted file mode 100644 index fe181fef4e325da590319d91b2c8dab47a68eec0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12702 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 UdmuYBXk_59OCHWn_wLScUaIaP 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_set.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_set.cpython-38.pyc deleted file mode 100644 index 7123c70c1efca81ecfc377824d6a615fab005e35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6021 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-38.pyc deleted file mode 100644 index cb88b6fc069dfdeb3f7c6653427838afd0863c20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4041 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 UR^9Po@85R*$BmzR!!Z5}Uq=5N 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/compat.cpython-38.pyc deleted file mode 100644 index 8813c55dcb2bb7ea529553e0b34abcba352abd16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6120 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 C_C$;T diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-38.pyc deleted file mode 100644 index 558945d10437ac8c0f5bc3064b1b5bd4458e5c32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1139 zcmZ`(OK%e~5VrS`Y|>3h+NcK(XirFyNOG$2ut&=qLetlebWebx5TCQ7)# zmHz-oehh!WS5DkGaN@*x+dK}%mS^qx#-49H<9$`DRS~ow+3)uUCPF{eV!7F{cnE_J zK@dc6gktPstmayz#k#8(b3HO*(={=oCc6)q5tZVyTaGQ)0^B4eQYIFukSbXrHmQ+S za*Nalwp*b(t$f06l{CoOXXLJs^_QsC`~}`n3(Lk{$VD!~i0`n$K4U2Z<;sDd1fxSL z(oDc|?fLQ1vA6qZfA^{P;#IHrxOdpnq_GzULK@Fte@h?R^pXbcjM0@T!)`z-Rse~_Hfn-Lzc zFcV8Y%CkUbi%h zfC>JB-)d8RYP?2C(?CKytFlduR6j=N)*CdzU-gM`YJ7u2IJYJkQl^bR9{G$@Cu8Y{ zkWk|IY>>w^5&WLRsK{9oCIiP$oV0&R1L26FFPx#zVM418wAdHHaCu*+TIhF@k&`E9 zNqUhi&V(6t!a;dw2S zse6$nMtL3ysl!1Md(td8eMf8!(7y*=5og^j%-VU9`N0__?TaC$QJeQq1j{Zq71s5_ zL{OIaQMahu?t+S9*U3h*nW>9f;;4W-;DOgcpt6B2tlW;$$>w}DY-&Ztu`>WEPWsbGdOC|xg9X|R&gSROp9Fikj9e}=+) m5&n``FYLDBl;jb8pel^t1z}@bvo!OaBMWb}_vG diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-38.pyc deleted file mode 100644 index aaea1983639c527418d093a99cf09be7a5424e32..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1247 zcmZuv&u`;I6rS;~I8M5hZg&OCB3a^614*=vRIL!8)g~z*y4lsXJ*>A?a6FU7bYh#C ziAt*U1YGz7IHH6be+>V?TsifI#0f6&#%`k=b}YZ|eeaFm`{sF$H#R&3>yP}eZ+2{i z{?ufBxj>%4D}Dh(5Wx(ECE^el+z5>V&Cmoim^HCO8zXA-E^w1MlS){bxS>0#hE<58 zZ#`m-48R((3#=2TzztF<@D6bce2Y{I+$7$}IIDzjQ)973YD*m6C3Uj#BMP?(K19Kt zYtV-J0ajbjUcGoV=zQ7hd_8!1-0y$Y{~|Dzb&v?D?4xPUsIrde_wv%7%2DI-rK91| z-etAK#*nUDM$2q_w+yv+S6Ofw75AZMoRK6wd;Q60rzhgWo!5<%i{|M^L5#JYn`HsQ zU{MEN@f#S4y6E)d6XObB8FRG2bG*ddnj>k<@ei2bpNx0W!kimRY#@vd(RYwrSOhr1 z#MD{%zI$cPO=1ySbK;yEyesX6GdH2u%3D;Hh*-KBsVvKG>vg+O*Ocy}O57#Rf0f>% zwnR%k(CX#SoiUBi{m38ABo)4p9M0*FG7h1q&!71+^W%(j8cR0w36T92<{j84XyCKtocdW#)1AQ2QvbzFj3^$(zqB?${J!gl03iI)4A3lNhRfJ#9C9CFwwfL)y!wA z7ENU~C{LqHifu5+u44~BH16XE_#M27Exh?3e;?w(J>}?g$AaGlstiu~J?%VzKFw91 zX3?i9XF2>{t|zRV8)5?C`tovpdzB009ULF+KUUQn@6n#BuiU}Y-a0$zt+usySBduS z`Ziz(JzmqrD{(f-6Gr)_?x*z^Q(H3+3k{!6GBRcKb1h5wU|d{0M%}RRwt2(K*gux% Gng0VpEK^tj diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc deleted file mode 100644 index ca7666eab0c6e3383e1e72d93ef803e9e8a5dcbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4035 zcmZ`+&2JmW72hu|R}?MNvMf7}?QDalFk6{&?Iv-8G;plQj*v!jBs-Fc1e+CSC@rmM{Y`tvZji6R5rvY5r})M^&3-L%cv8MbcIHDj;onYPp{ znbvRmXq~j&4Vu^leK#HHR+<&l_tMdBwOKX&QhK60)*Lf^KRwy4HEX6{PEU2mo8#Tn z&C|BU$HiZ;N03f*&os|;C!3SDb;n{Otn%1m6@F&lZJuSLtoqn$o?|E27}{6ZNmfI9 zo(Jp{8-Hx=+s#*bm7Qi2?98`L^8z0e|Kb$VLc=B%Gm zzZylG{Wu-Y1U-@WxKKNy_UyVZE-p@zY!uZbih0ezc5EX#rVY|Jfpuuh%gTQQ8|>KwYhZ7<;*VyoOmpIEUtylwx*3$k5qXRmndWg~Hl<9j1Cumm(XYD~o zPt^T+UD`^r>(_J{IOBlWJwf)oT_4jfw623*8mo3Ly1Kj`%UCI)om^^<5UERvj8~-| z`#?(QF3Gc5A#$P1Dc??{l7iGFd{nx;uvE7Z>rMyoAc~CT!2CIi4NZRj2AYcGVt3KY(n)7H?oh z%YcT~;zw|;q8MulbardXIxu!PbZiS+{v29{-P#T`ofeuVE47^utuJouIk1Q~a9|M^ zYbR(e*4=$(k4vNxw5!CINK0;Yrh-QC|Wi?|ocbpm^%mG^e8 zU9N|#eHC^g=A=&h&yNu1sW*o}t6ScZHXLd995QY_&- zj8mD1>q_=pB4wXnfBWsLR~zPm-P)IL$S=c0hVk&s`MR(D z;*z>#ZYf@a#&mgZp|I;nBBSDZy7uywz$UH~E$uNbmA2b@?D^t|-sNQzkD3E8wawW( zI7JeUtg>U*>~YxC*wyu6=b9s?F>}lZ3B4s0W7TnV$fn9Ua0&Yz?+~mk$m$>lPpVky zU@4kgT3VR-Se%Dgmr^4wOGR7(MmETN>58I`rJte{EaaH+v1_=PB*tjbqE%E1AyL_# z;YCc(qbo6ox!-!<-Pp5LiFpHi-vO{H1Lrfi^|JLQT)N{Qln*gd_Ca7qBZqj-hP%`J zr`95Rg){Gdb0>MoGgyth2M9rr6g(Az+(--(?HNg!Ar#SqM1_*K`hurBVVtp$XA%R0 z0!#q`TOv^k4`VG$y{H>+M|h`rM_0DuL=`wa#w^4#&*Q*N41T~YKOeHiy9HYSqwc^aqaJ0T zAx|Kp7Krr^A6Y?We6v7T1LMlQP^^GGTT!APNmR{eyJfLtw>pTi|;wBLu0*=-3DflRa zvVBU0oZYn%_QXyR=EnEq8z~oj>a4@2iY+-mmwf}0JtovQ89ZD zRPYVd#@u}y@#SxO&cJ5gf&G=$wpoe!j|0q=X>K1#Icx2?%IUZ!Ub%Q0rIhSBG=onA{R1h^})J=Mf#`lYK!sq+IrI2NV{3y+Z0muA8u{$>|Xulwd=on z^R2gUyz`V$tdDE-8E~(YMk%))SYOmYs$l=G0bZihO^5DN_>u#n0N>?Z?YGwRqy-Ps zPUEV!qbIfw;j$To}$JB);&H`bm5k#L$)YI(d>E0k%ifuKk5* z@x$dsC)`o*~L!~$J1PL?f0`Z$u@Lt zHhY+eJnI7MCZ^ZR1sUI<*S8aK8*RbDPMc|a7`7KlY7*o-=zWJGe}>BPJllg4gy0#+ zz68D@hp2j0djc*|u>)|B^It*F)I;$(nu6TQ@OuhgVxB~_lekJ1rTn@w3^{4CD#+eC zpnzsl2y&$61il{{5h5VVMZrmBi}-Woc72cTm!Wt<3&D1IZ>?~TnNqu6v<9kAwj-0QYi(e{|Dq3>GuEt diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-38.pyc deleted file mode 100644 index 7631e2d171091577aba1021899b1d96138d98b58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 556 zcmY*VO;5r=6x=Q?Ehv~6BZ()kJ@Et|Fk*?;7Z@elOs z$(v^{`dW$N+q}unOm^SoUDaw;1obLD?)NZ4Z#h{m(9j`tat1&VK~$lbD3t=S_tu{5mIkFBBH0VN$u zQhRL zG!1xSLGB@*ZML~KqY;Xgbv+MGQy#+%7-l*VGVn|t fEHTfF{cu93oE<3eYq9~L;#I6FdBed5bp7iakLQ~f diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-38.pyc deleted file mode 100644 index d42e3b391adc19d3640535d4e40fcb0d8acb9442..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4144 zcmbVPTW=f36`t8$E|(NZT`VcSrPu;ZT^2EwII)`=u4~73ETIkUO1{L~q^s4=kX& zGZ-#>`Qq^l_ulG*d%tqmpSIg;?T5`$Zrl%inH#?jGMQVS2eBu1*B<3oJ6Y#)AmZFw z0~0){6zY#(d;*F}E^e(lJ?P|S*7L4izoEXLeDYwrjzO}VgT&y)7nAP8AzM}trXX~=Cn0?%xiNn)SdUd(L2 z$Nhc=;ykjwt`~rBt2R9SIN6D>c9VqJ#idl$&uw3W15F<6<9iR@Y#EvnWwdXJT0mlL zL`TF0Tmu@kVWL)};+v@_yl8C7P5Z9R;8N_QV|!sY0aWxNJN6>5GEIV5!iC#1u|v4B ztPl#59nPlOP-Bn31|?k%BGcd7aAlSYC_(9_mKzxlJGogn;4Kjs!Px)YUXf9{k_PG3 zL7aMipR=nwJDVv9gq=uNe{Inav$KZk1o^Orxv1e#8if_@-+FTu}39% ze4joelxzcEY>>AU53YwihBIrekMi=^G3vlYa|u-Bm0MjN^Vg}k{V8fhn+&+h;g84G z7t35f8N{-6D@=SZ%x<@)iy%VvY!Hd}P?uQ%1t`Z!px&bB?hba%2$A>v1aw=NNAdfjgo#(I6 z3CNxXHwah1Pw$g&ZtdyA1*skCBmIcNS@m1wIoWO)L>jWx(fU=fO5vs{ktU-feHozg zhQ0uauizb_hRb_~ERQs$t+7`cl@6_uaYO+fUvEE_mGO-IwYI14nIrSCdZczA=@&@f z6t95kfxEX~jmY85NW*oCU-aRdd&m;DVgvL5a!A1yKqN3go{@G(B$16Q?rj0rKtvaG z483VsGEaJ~f=MuP*S#R)Ho9&?^>)y)W6)_U;y)oeTzVQSPEyRFDB`C5LDp{81cJA? z(=r+t23xrv^PRl<46}*K5P9XvZd!DOh2n^-+#IA}5ElqEzyN<;+tiztPkd+NDTg&+4Zwv+2+DnWgv>>U-uJ`BvpYe^uZBS%5VG}>`||%n z0~`yZPgJ0RKJrd(pyo5@$`?-i5k-Cr!jrJQ@J?@|)TtvQK&FxVAq1S=l6h< zfRP|to&$egC%+-<|Eu8A#7LP^SF@pD)|As!?3WKVnszx)rwQI3I_ zVrrt*=#Wf;t_#6C4Q|#P~!=9ZfMz1xC(0cZ3v-Cc(bb?X(jqxR`4~ zR%~FlMuvCYyz079!UiGsYp%OJ@WSy-*>zdsyRNtl>T)X;aAQL5iVtvq%<={7Fj~|- zieF$)S$79}$5EwvDzq?Lqq9`nwy0rLEsa(Ut74tEuq|07figb4ryfKdKG{#8Iaxz~ zOFB?AF#W)C3}&zrRDz{%A%8oV5zV{~WQvt?;q>9(peRg4-%~NyNrd8CAnifM8D`Dc z-r-jSFmAER_6mkYNzWF1dk_d7@pv4lYtr_UD20Mv6^*v%OK@MY1SlV~?};_4#8hMo z8Dm29Xq(Ci{I$a@1Q3>g zI8IzYyr0BZu)6GwD}&9=0?eD6c7Mkc-By!|3!tjqH1bk5fZG;dz_7Ug`WJVfJz8IT z^1xlayRoY9_m<`r*Y!g$%K#>v?Am;XC7S{z94`LOY6>NTn%`w`h9R7RweZt|3XKa`xwY#|Xb8K*DaUUDBUnPOO zK0cn$LkO!Ad#s^|+6XK+ZcTBK70FAT9cdvyBd7}U768{*nIOM-T2C=8cT<3tK<>-U z@n8l`t6@{e2D6xef6|G-L@MU7!GcpcJg;v&S%1`is6g;wBR7k@rDC=K%ke!-0g+p` m3W~Xn1f2Zn#>fd1SfV(Eh*%L=hl#v=auG1 zno3hDZFh;1q?kE3j-sP6Uk1dCRV5f1a>A74gc`!B7H7^Wl`+Lo@LggR;nDyep+XSN zKUCa64=Pz?I3y`)$Q`B092oFZt~-Q6Zmv0mjL?w0Myotl5-^SN*=;=*(?fCU-mNAuQnGPUser%XtG7hW`A20qfPu#MNn=4og H{qW{LP0a%K diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/marker_files.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/marker_files.cpython-38.pyc deleted file mode 100644 index 6b145039e0d45aeb85e3ab8b323da87906e17088..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 928 zcmZuv&2AGh5VrRxNmsN2Br1f2wx}qVWxICCw$AR#_L8P* zPjKfInj??EL+}E7MI5+s=ERIQRH=j|kN?Ks%=gW_U0x0djPK>|_dgv%e&Atoz#Vx8 zQ{Mx_38#__DR+hrcZV+bxc`|9J>KGNSba`+N!a-Xo@8+PZEuumc9==QU@c{m3eHAC z33f1LWmYm%uq@|Uni#>%NHASgDiv&!fOlnr1=n5>yw2gtAYz%M$H@l^s;e{=S|3(Y zP611sL`n!^-R5X%!2vRpk{yVE3n>gZ+^=#8|Jbysm=fdS;~W~34ST`qT}ZFnICl}O z%QGcXQ>baroS2j%!TG>_3+8i}dKHWzNA$w6);%M}n>jO7g$_c$b_!j4WnxBkOPpld z!0D*S^7_v9#&*0OZAN=hytTITD%y!(Y-~n@wXG%;J!EVxc-*LRQ=XU(RlGpkc diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/misc.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/misc.cpython-38.pyc deleted file mode 100644 index 5d359790f27dd754f33229d4f5fea53ee59a30a8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23778 zcmbt+dypK*dEd0Y^as4-jx9h?U62-uB$x z-t7xLvjA>!rxz$wvP4NvT>c|}BtV>0g^A;&;>2;@uc}lzj$Ls|sU%ZQ%CTa{Oj4;- zN|jVWmYLu0>zREWNXhbUP0yoy`tkMm?yu*yZQJq|e!toN-&cO$x2*5;X7D$Go8vfw zf1R={WhuLEHSCgY^V+F9B}dMwQcBKl$(3`ul$LX*l#z3`l$CR?l#}yVX-v-fQeMvE zrExhIN(G!#^=*xb(uB0(*0(n%OOtY)uHV<#QQ9Hbnfm>Wou!?P2TBjfeYU=Zjp@>K<6!BaJfEn4qA^pNX&fpYlKbuTV&ib>aO26+leXpW{I0E^ z!3ZYnnZ{G4BevD#c<#g95#IST$p03e?5IE8c&7AB5#^~zmnTXm{Os+M{_GvQbV}`4kG*Y`POHb&6FASQkE=&;enlNnAH(_6{th*z zrq#iB9rZ0WqjtV+-?B?*)FD+w?q}3t^(4-pRZpo0a6YTvRZpv3Z`-9;)idf@JegO| zspoM%r(RIIaXzm;sgC0OIrXAChVupWDfJ-E7u8E@FU|{oX7#ltTfMA~qn6jzx7A7Y z5Uwt%S+xiGZ>UphAI_K6X*Gv)Nxh;zjq~T#8TA>Qzo0&=&f@&0dR5Ki{FXZ5PpcE^ z6Zktz8FfybM{Q;GIduWKSJXwdfOAE?re4Q+@fAy5Qg6I%sW<%UtrRM^)MZt|eaSz9 zd*63fm(=Ig7v8o2g=O`odKho5sJB!Z=Nd|1Q5BS~$lI&xJ8DsRXm3qbl|qTS^3@W~ z4YjORaBiyas#Udy5-n9%4LoV9rfT7QRkhVsoVC&_z&TK%>fjuzYw9}A9d$#k<9tnZ z)uT9HS2xuL&NtA9P4z|e;fvCTb@e6nWjybyuc)u$d{f<0Z{xh7zNUT#=S}r<>g(zo z=)o7&&#G_Y$(NLK(VG46(E*=iJI$+|R>;foa`~FC zgIcRuF5|W^+iEl_O?6u9mYz;UyO;g2+^DR!bh%M$B8>}2+kzT;)~;07D$9NljdcQF zm-%ekjk1@{%%3`U>0*@kZ?sVv^P=$}RQ1|o866Lzi6GSFuvJ#Ipk1%9+dE#peExEI z_S2_lKU===+Wh>P`Bx&hS_wkr?a`fPv({WLcbW>VT&wA@Q>pvSYthdBb-CFpFV|a( zl{yD_ay|5eGv{!byBKP`i|er{b)vZ*Wsu-mG&b96hLu_qeaoE*eO+0s`;mLL7KBmm zTss6rD)q=+03f6ELZ^+)^lME#C6rE~l&&pySSrfsMyP#1D#W7!RKk@gzX;fL+8Cma zQk7sW%3-L052_nqYUxHL1h~3>w4)Z3Yt106)a&ell%D{k8(+9#y;^C99qp?!;M(ehfORv#y}bVbi^Y|qL^5YPwclu6^UIY^xKduytwy<{>s6v# z^0RS~#xaW{cm_#mt=hL8NmHSF$5!~?No|_v=?&|Sy$OMHI}>I%tT1=Wx|0G5r{=p( zvDn?)uC=|Jn;u)@d8)l0uC$uCoW@)@tsrs*QtoQ2){L?M6bBjQ%H^dR08x&zpa3b6 zF#yvA^hi_mVGhPoJCTV4e$Ub`;_2OEhr>quFftBxnnX=s9lE~a`}IS?;!>#F*PmnF zVL%4cjoCen`Kt$q8?~TXY_CV#1-Pg+hSz6NWiW}va`xDTlxsVdW4RwVALvivS(UI# ze!O;Z2;5HLBD6NZsFb~C>HQlJ&*pv)V71eF-rBU9dwL~YeH0~9%Kn=3AaX)mxp3+4+^j0d@e6P}6_e|fC9)XW_baSW+rhq3M_i9Vtm685l@oE7YY939K_`^uZD75$=gf7(>>ehTwAZEMc$d^G;L;gV+nA97jrN$-*Z z(e{z<2rioB7)nID`qUhQLZEyJd4Xtog@V1yF4zS}pTx5v#B%U}WoB9UJd*B2Xx+9+ zc(!%PY94c~&{@mt&)C)`o^&7Huvb%IYSmp!0j1Tn6oAwv&H>}H6(|H4T zKr*N6wSpqatk|f4Vrn|@uGc`QozOdd`i(Oe7mD-K8T~Zcj&ezfD0}Xrh=?fdYu#)` z8B;VGJ3W7H;q0)Y?%B$@G|v-V7(VSOK|_Po;u&aIlJAzD7CcS399dkckta5e>cp z(AWZ`u(`~if&985*I-~S`S>VoiWv7b95LT<>>YLvh>^E<+8Mj{YvYzx`vG7B41@@6 zwbAh#W#vPJM)~WNS_sa0!&h@vqD}JSb&sd-#0>$tVQtuQ>+JMf)z4L{RG~R?l%I@6a)FFy01wSz#YAS0;7ZCOK;-{GDxgc&UQYi zlDLu|Ip-J-LGm|n(FJz|lG}IeRVM@zAGZqDW-6XkH%u=P<)OHnDJ2@eVQr-J1-zBP zxbVgu#|A2FKxM}GkpI;L*?;?7)4NoIs&_q@0Y~vY%9;So)GG$pnqEcwU=|g1sMV~m z&v-%0g8*rIX24U^9;Ozh!n?=vNklU+UEB>s}SgO0C)Pd$bAcfx6HLK%H4boi3D! zFv18H*$Zfw z6-6kF&L;WRH*o|zkXWu`@3D6{ImdM-oSf}Cn)zFJSPlUNG?@D?~)GZ&6g+-};2 zuWgX8x!oTMZ2OXPkvgF_1tCQ(Y}zBwqp0GYH`Qs@ssI}?A(o;?rakB#UaZwgWt@|G zYk8T{w%yU~R^SJ*;96M0q!Xgl3B3UPv#z|R5038%5qV&!MejsCXc6xQ%i@~+2b0|N zeb_0|5?fCC;RUs3b+Bhodr&{6|AAm^rOwG(mysCZH6LZDp;p6gdhzC?dUHA-gIjQHyR<^$NF{ z=TP6$RLOQjDI;!9XSxfo)UJ{I!8T&7@UB(rAWF_w#al*hQ>JAGGrC43sfA!C^-72w zqFVL3nO!I`z@4B53NDHmdY@c6f}Rg^sOm>HsCr^h>QIG%HRS6TP|nO)VNjXSRX!(i zMH!hq7#5gOlPO)YeUk8yqt#+`*XN}%HeF-n<+D8;K?Zgb#VjI2bwVQ!qkRy%LbTJ zS3%Our#$L@VXn3egNAe?5U0?k-dh3ewO0v7+}Dd0*||$x?`QP-rNaL02t6`c5FBfMB7E{>W&cj2q8ve zAT=M|cmB-zvZ!Pi%O_?R&YYW%pvM^IpM^PG)38QUnARvQwx*s!Q!wJQFdYM!=@955 zo`NV-5jHh48n_&SHL*C$F);9cKwe=vyD+M}t-pfnEu_ie$<7uSj2X_T#@S0C0h15KN{t06N;|bcW zCL~n%*k$;MdiUPc6MEVsAe*f)F%ZeqdT{N%Nf>sW8IKkKN35x)0lOet+EJQQrQubA zeL!v^eD=LR9WPny(+L*Nd+metA5A6^^qMri(JvLT)l_nr&14D%6$lA zNb5+Y*IYfLGPvqLbMfrBf(wUbSx$iw%bBcrY`%8<^hYvJB16F$f;^$# zW1uvH6KQhC4knEn2|rZ|0}!QAa$S;?E|Q4kp1Cem0prbbHyq@iWiH>JPIph935-fe zHZ&k(sCh#@qZk2$>9k=b($UdghX%e1K2!`_jrz-?w9R#MNs)!_#Bhn2Q5$_bT?=R| zk!GSyEui8B+M)D?n~;r^;g9N90NtrkA3jsSkt!2>+3f!E2X}6HVX7=$QEu*3=Sz(1a+M7&E6k`H}d0 zHe?q!F$2IDF=}TMDx@yL1yGDh9mE~r`nHfcWN;de0U|uy0`Z#$Ugphfc=MWg*0N*^ z;#u1Xt1}0yGfdnJ10J*I6KKVL`Kf6GDdP*FR~E`D8Ahe5q2_zazg7bwfjkCWNqQ5* z&><5dw0<2)QL32{`JUR0o6n@P%20^{Go^E6|#mNE~ z6Vq0p$E0rAw78(n?!k=6TN`+WT=*vyylz)NqtbXES1JR%%T|67lPvUj!FXsFG^{D; zgkm8JBNp<67j8g1q}mS`2HeZB?R{p+yY3%=tpMY_;`P^r;J{f2N^2i(F&JFpF{i-~ zU8i5@Kp-73rCx+S1Ven_HFN?JAgIAmhQ?WMfjNw}N;PUr%XqNt!+%z(qiM#!&w>bSM~dGiK1fckUwi3*1v0{&8t}Nvt3&AHzD4^$LzYUfYq52d#z=ClxIv z3=9McEF2ub)b*7byiZkeNGwA2_JYo0--K!{nOb^)f`L?AE_#PMfj%t51#)u)F%Sl; z2Fvv8RN$LZP%5H}L=5B>of?!Kyz33C=uMr$Q|T#HBY5FBeghJ(EE!S{hfyAC>>d*_ zZFul3RxN0ju<5glR@OEE`Jh8>IJLc*VLO7MhcRFTDUuZ4%Tj?zq2#oFTF&3rOLZ#UXYL zNt<%?7G=NPHLFA;^k^*WQv=JMiSP$~^i~?-FHLX}0~U~yhK)_Pg=!%b*|}&NfhvO` zOx}YA!3U!QHl>nL-{h!8KxFkVp^_~l>}iXAJ^eO3-e728M>5Vi>EDkZ=gv&$GS=v);uWy1L)-pgLwi8x5JMXZ3wXCTzKs6m(eV)ndj|7!xS?Q%=r{!jkKN=g)a@=Hq*=iYR)E<8!-OVH=JgU!uf6M z8_?_Zb5QkMTw8dWHdjz|&Z>;c;wjwbDrc@XT>Vz)e#6C+F_lN2`;PUF{f_fa>K%6} zt;SX1?c7G@6nF$EXItg15usi2>L6Hh*FGn>2dhXt<&f4_t{BcnVS7cEZ$Tx*B3+~@NOe#bh=ul*E5TZ=jW)4x2jPI%$f25W z)S3tojzatzhiCwJ@r-+%@!qjMd?;i0B^>6R@da^AOHh{6eOwT7m;=)Td&^;e?7rG}O3-or6^1iU0|auhU3< z&zWBk{t9_vt5HrH3r?)}g#WU~gY52M^0^+4B65U|EEB~O6psl~1uuzou9x}lkMD;5 z+vtyJ{qOXygzeM65p7E*P^$Y^16?`t6Ln?i^)0=j{1c#%i5TU*fCul{2o)1fqVLfs z{c9-voBf`Ac&)UzOsy9!{r7OA|2~s@)EV8MbTkk|mC^oozm4t-f1=S2RI;UasB{<+ zK6(c9KS25K^?UNCtuGFABXUIjTDu}Ze=K4NMQ*_>&LXk;ejLG3B+Ky5ym@5P{yL2H zTegOIwQ7AmwU*WH*SQ#gCtru@E@$MK5;X;FSRr)c+8d26qKn^T$Yy)mEeZ(tqOE=#$G>4#ZL(2mU|&2??lQ51d{UUQzy1 zOLIN!BGx9xq4x8-4BjESo2Wk1*(fGjvMl{i`PO|~*k?2`jA-$6@D)Zkf-UKPfj7;d z{t2&SWDk7=`u#-?)k9Hhp9{BR#&PY8lS^S)GSyG{ME^R<4B-!Ft!F^rz|As(a6$_v z^FcUapvBOYKodGR8M;`K!< zG(H>KNWq+*+epPrL~{}}nyTy`k;&x4V(ZW?&YPZkBmO&@n^>DP%RJ!VC=rKBnHVZz z(+jjJ4+I{To2&3>=vpf{Dj82r%hJJ!gq1AMLyUwh%q=0xf@_w!0Z$lHF^%<4)_p|UOsYa^w(~~!JtKz--8@2 z_R7<|67!QzY5g~uh=%JL4L8kcM7$GEQ5Idjmx{YB(S5~a{R2|gUQ}e=51IlK$%DSQ z+@FV|pZYG=6S;OeL{sF3JZ5nO4EP#Sm&Dyn24U)jrhY z`%*>Ha5BL|RhhsbA9gb1wt*H1I7ueiMEqPg8q)O&G$yE(Yt7d6KBn|hguZoD7Hef7 z)EEn57nKYcW9|7e7~jay1Rd6@oq7fSCh>J7ZfLws$D>LNzm!ajn6ptX=^*TN8aw)L zF&Q>(#RSe{-pp!oo_=dsGc=61%x($~U%?UVL_(Wy!&<_;{(0xySb<Lt8qr!EKIWHqp0D>Drt@3j4$Gqb>f+-}vRkD?Z z{W3Q8%D{t(IDA*RDvfj67)sbHlLMlSMY%aR!sh_^?&mJ)N*lbYr@bPITw=&T#qpYm zfS2nVpc9{gV{lpGbwQC?F}lw)7@uywc6+@zJ^+WMu(P@AaRE;`eFJQ;kk z3=JBQhULD(+2k_3IiVb8cgZ1~}yIk&Al&|of0?i&mW-Gwqk;h;1n5C{w4AOcdHdGNKn z06?h!BN~au=3)3r*i*FaA_6YY&`dOLDjlJ~mZ2q6{sf06tD11V8|V8jxa0=Ray&lIObBhF?qU$?oudm97pgtl7#Mj z1isT@fn7bWpEeE)TxYmWFr6XL0jCD(t?la%r;-Ay#BvsB1D?zTV9N*(_mM>7)jFKrMl;a=olkP`TmWL>y3{%_-2T-4 zH~#8~O? z>@o7}WloW}3A1^GgFA5W>;Hp_x6l_SY8HpgX9%Go3X;?Pomm4*QC>`)RED_5W%dpo zH6AOd?jp5DKo8-C<&vZ%3MD^@`xS>*dgAR}<^G?a1CC%wDqQ{@}N#>7D`jRPU| z4?d*n;cZ$dS?YDe)&CbS-Lo&pkr8-E5+-?XVlXiZ0HsYhuox@QY!T;f;!n+rC?+#r;1jf?>TA$5eO|Nh>`RvCOOo8QMBNr-bxs@gQJHJFC&nxvsgq&4==XDuLK_6`zeCfhHe2`_%K#O7&X=LkiFnTG)jPs0rALbqmIH8Tt@X(S|7S z{{Xr0;r}n3F5#s760-OJbj0)SJ-U3x1 zn{zdv4NcAvAf7>PKO94XQ@Al;AJ#Wg2$RHQnE(!eC8eL-z$TwKTFdFqCe~ih`by$* z$lGXi38(cc*IG3R0Up{g3xWpKaG2tr8oz*TwFoNadVnUY)&Cp`Bbb^h%EocljCASM zD{iJJrTweMCK>_7Q+T~YPzc{n6{r=Z^6rparJ6@*%;J#kKGbHZ484o6ig;z~5ts^G z!ya0p08P(we;vYPlXd9~_5oo>+Po%?LG8)G9D<(O(gPF4If}B7x2*6Tb`A%PBnakV zKEz&e4$t8jkoa6ZHS5H;99nGOMzB$AnK<0ALF;P(8peRrme05nQ_MgJovcbNdx`vJ zr!iox^a@7XHA4>qAG@g9ZKwm0dm2SegBh+uSHmdPWu&X-9zlH^m0~wFlnyvTWOKC} zMgSZ(3#X|+D{P5FE!aI3*FM@+m)Y;KlZF=e${sI`Zz&8@3TLN>9|v(mCYG=a z26iG;{9$Z^0q7Xzrd(bz#0l_Dca3gxvQtACADn7_2rE7b;9F@0;UQT#YFBDTo0`9C zAHC~-{^sVJ-So}Pqu8Qr%kB^yY}bx4%~OM80+D~7_EbCQSg|B$)GdlT?lv+<}re9514^t z`?T3dZA#xE1c-T7`eBZKADS2_C0`}i)kUhM810zLhx`Q`2ACg*E#|r=#zZ_RvQLD;NBv!S9yhu}%Yh3V+wJKCl&$CqImC*H0d8>A zn=-RFgS}wTUJ0QYc+5-$_jK$T)A*DLT?O-+eilun8fI<8Y)-MbVfNz!jBPI^nTY!x z%HoPWy_h3z88GdMc*2s8GbBEm8zW?=|2?Yx4Ne2W%x&r2X^Gez*w`PVes4{)=b}Mi zZbqBkA&fta(y}2t!2*{Mix*WSGJOQ^cip?4Uu9?LsA9xwE{%9YY~#wo%jB0z6Fp)9wm<@ z9rE@QN3eZ92#&|O)LZuh`?%9Qi1S(PP=2BevxZ6)F`?MS3)6F`OuvqMzdnE0WrldG zy6L05?ml>v{n@;k;Opk`n+63o8Hvq2cm!fx7J`TJ$a&HD1P_ovz6N4=pWz4k6U>}p zGJ*oz5C)08Cownpx14#dB3NULGNsp->t_t%&d~Ao$C}a1L%g31vN!w3ag&5EQ~v|& zW8f)SAT$YX=OZ)30Zn2xvy|RMAS%|yu!^>s-binxgiSh?3ut5kLOLL+i#ZcpGKu7q z83%pElNu&v<6%e;NPqVxBA%fR2<8|l##M4^nNg8x6v{DQH8ATgu!JO{1PZ7uBuIh8 z<&V(axHIyK)Ihxft3$nV26>>@8M`>}})J?o66MIhD zpaTp>TRpBLX@WkMUIhshk{X_hWhS6%A+k|$gaX9y4ay7s5EDvnA`jv>qui3NEOYo# z9wj?XDGLSLL&0crv?=HlC>0e9c*`eRgq+evIJTL=Pv1R385){lz`WqSJ~Hj4vxls@{AjZhmh zjV$#%f!LCQcl0Njj5IQVJ=X)YWkZf6?YubJ4p~3t%q$Ms(ZP1Ok(wM72Ls#56;n&( ziFWsA1R0E^tO&Xw8WmwnK4g0Zfj(wvGa@pPLXHB!hB;z?9>u~iQbJs!K$)Hacwa>F z%=9X`rvQ}>yywWg2;9Je404QCWM<&NJs`AqK>oz2BMw>AkS4SU6)U^L*7z>h*2(X| zi+=e8UgR-=5ca$na`P(ilyHmBQXc{b5`{n*KEsxeABgpg*ap+wzyRFgfJUZOA3tJOS;}MQc zupf=F zm$CcbN38?SF7b1nVuf=|&M?6amcja^C2@P5K*qytfn9_8JC<{E>D;*H^DPtELnM>YF>%PH7NR_kP#!hw%D-~$f!YSxsdg-GLAU&Av*EvwveN^-|~A8AO1h+T#k zVf=QUF;e_A2zH%w8L`m)?s<*R-I-5wfU$Eo20qzi%t6^nggt*INTm057^8v>el3RI zs-k1vlr$TVs10&+QvAISY_Gw$>Y$1BO$8HHAAe8CD;AAv)y>9z=#Jsy<|ex%&b)5H z+?z-9;<3O-i5mJ0U?@gs_vwXX`xBdnjav5^s?3I|7B028-+~>3LBenO9nIg|ylZ>Y zp-N)o#-0+3ahj+$67m#|M`y50UkZWB@3*W z&`sK6h)sVhx!K}74{<{XauYoK%G|w+MUTOcDx%( z;)gY0LSefEHVI%`@8evE{hW1ypGl%hNV<2sM`ML&3frMpX5!DVnQz`m2) zTQr6xo$8wG4z}?z67!9>$VSYFWQ^j=7^{~L170QgB(g&Mj0J3U;`h^ZWpvVU-wzp? z!c7-n9Ky~;e9t8g1+ft>0{<2Nm&N6d1!{!R!hQOJXsa=R5UB^kGGUas_Umv9N#r7J zyWaZ4fXy^Nw?L1gl#RyE$mcsHhy>tTM7Kr<$8SJN;eK%XmpDpF6noW zZ2UbV!wCKy^Im6inTcTfcoiJQFwa1fugkX=i}++9_bJK>N@*v^IC)ZpdZyQbJDLKZ zw0$rO8-;b2HPikoJus40WDr^)ADJlayJubzl7|B!WW+8l?fsG7~6CjWps1EeCe-$!<(~eLyXSm+oNs`p>>`vv%?J6;UcQrwYk7!I_A&VwlZTl+!o*|pD3kq69z#-k za1c^M%VGL)ctPo17S@!Hvi^2yic<|ItGblUKZ8J3x5!kx{s zTd*H7u78=&euc@eGx;qh?=krvk|<*W@gx*Uf?A@9m=NMn6B94M*Z^6Hm!(S0g*#ag zll2%`zYuRa*#x@6M9gxSSbhTcJ93X9%|Wr<#!$BS ze>ZV56N}E;IQU6yr?p;aoO9 G@&5s`fS+an diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/models.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/models.cpython-38.pyc deleted file mode 100644 index 6995c35d5e2216b1940363b8177246fdb86baa60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1924 zcmb_cO>fgc5Z$$%)J>Cq7bH+COGrpLw7GGrs)`;ELPSVaC6vqJcs7kw$98u&lvcU5 zKLn2bG5i5vIdS96i5WYoLTE%pS!;LJyW{6KZ+GUTR;w^p~T3Xcu7_ zR?t>p71q!$!8&Z9t->a<+sZcI$jg_$mT;8xQ(wuq;ioXZ+JC2#k0BuCAYTr35_^H4 z`t5Njrt2Fo)Lxsu^>Eks&g5mq!xq>`dE97Du^eI7t2hk#kO?-laKxC7*)4C@t*k1F zA4!2I*@_seB!bA-x^8EVmQg3OX?OYe&0D4x5%=do!}QZe8m7C0IQ4@w3A-0vDWhH8 z?iiI`yr8{?2xB8v>_?3O9*b@ir?8h^X0E`!&+7x}@H$szG&%QTpf898xd^d_Z<^59Yz~EIkb99QHkuQB zuJlDVdHN`dS`BuO68kGWo02E4FA^3iDjk4bfuc&r|1Ybv5%=e zogoh){R1&Yl+_9jIUOm4A|a+(Y~b2s?0;o}01swyilN-gf^>K?2MYptIEz_YY$1c~ zd06}pE#&zOEgm5QZw?j&@L(NKU3>2Ae7n#0J4&}Zy-2|pDG+q1W z*frGz#;e@1W>ub1;x_9wDi*Qd$5^t85Ln3u5zVVYoDckHw6h=tBmth<5&|o#ZFvqW zN+CrzSkVPibbgBDD>9HO>NH0xEwrxbE0;UA>$vvhqsXJ~DAI3~!%4d*1Cwt|z~$&g Rx!W&jA5iVgi>_00?Oy_tlnwv@ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc deleted file mode 100644 index c310ad11208309e88769096eafed5e1745bc3ef7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2927 zcmZ`*OLN>r5Y}t8^1hrH0wKHv0c=%S>lBrOsu-t$R9*#aQn7Q0ff8EH>{>)CiILWc z7v%yuaDacn0gnCy`~a#r!Vl1u6F1H-DENA$wVe=VOEc3wJu}@sUw7~AZnveN{hI#y z*>6uN%I`!RZ#sx~@ns`)OkrxIY}2Sk>O|YtRE29|6|^4d6Jy($G`1TPbK6uEW^6av z5;Ixzp}K7`i!D4hjlTwS&uDZ?64E;B*rdNHx=ipKX8{aaMW_?qdPb6 zc$cnSzVv~2>-J!9eQ?#$OXI^Z%S-Dn^IWXV_pRE? zNy_8pRhtH9Wxl~#4-&>VMt#A3w&Gw&BR}9P%b$o(NO~E)vp(tvQIhc$XPw{Y!Ag)! zQe20T@zuk-Axx{wj&mh2$N_b0V5IL7zU&IRT=`rbs}GDq7ta(1!~AUpl)6d!%tL2Y1wF3Ib3$=EgSkx{FvEr({#e)JhShG`Hr3K zgcJLo@Y9sDO57%|*1gqI*Xdt_Ifc+-pvFG%81IKE(CAK6=C3NN!T z^M?`7?39a)P-BxEOeMLgsMRND)Y?zu;dC_Of-^6f=IJy)c9_ptX6LZyNXX9Mqd*#m z1!>5k|Lh2Ot<;=p?i62e&~@E7aY+X^7>ymH)B()0MF^PYq-lA=+q}GW`{ve-8y{|Z zo7b*?RGOniO#IwwlwJ8+bKjP|N1avn9(6-`@<`9xn9{)GX8Vdb0YDvGTgxZuS{kPA zG*12CE@$q&9nK>+8;)|3-g}GI*1Ryzxq$1|rg<1;Ye$IjhSM-&c+c{=iGP=S$5se5 z9^LgU!FLIra>7y#wWThhuV#YS|Bv|$&g^#mFmx-RxUE0YaX+3lT-T2xaSAL)KeFqIdY^e*Z+V2&_$u~iHPXfkLob;n%3QxlRG!AHib`3 zdoKfz(#K^X5>Y|II&xjP7{*x+r_Mnk@6)m9wW3z$*kqNn7czCzL8)uq({omTtY?zdE$x2zWBJY zhubLrcd@NPmnoxOYgN`c;0F|o^F|>_ib?B!#-y--u119}%ufS9r;j0RL1qQxLAz*E zoYYx?sD`w@jk-tp+5*R{G1o3C%z`#P^`v z)yZ)S^GDSiUgEzDZ7Ezu4=;OpLC3y~?al60R;P0bo(Gk{j`AQ5bK)^)Qm9!K2W zMVSITU4FmHxzV1Bn(U7`n*q@xNpkT5d?Q|@jzA<{Mn|Dg|GSuVWK_(lldfA|=kDOI z3QiX`HaMLl(2G~WC>JYLWSF+Paw?W zi=gohPRS@=D!mQ>Ux$LK{biaxwWT2tC>Z2N0YP5{9!nEz*yZShD_5MJpd3}6L8_?$U0!XGfCJq j;urB>O3CO+ER9rrdO`a~Ybz>#f3=>sPFX$c6>I5V%h2$R diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-38.pyc deleted file mode 100644 index fc08d0cea3fdc9cc65f6b78fdff0c8838ca94aa8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5598 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 SHjAcZ!nRX$N7a96uJ&Jf`;wag diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/ui.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/ui.cpython-38.pyc deleted file mode 100644 index b70884de57abe04da284c43f109f740496bea906..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11802 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 ZJ&b=pbtiJWVH)i%Oc!#6^M#|1`M)%lRJs5F diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-38.pyc deleted file mode 100644 index 4b7f273bc3799e584493a0794e940acf543a5274..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6075 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 L=SBNn?ZH0)FRp1! diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/urls.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/urls.cpython-38.pyc deleted file mode 100644 index adc63e28af2da56a6c5a3b1da880a062db473a35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1465 zcmZ8h&2Aev5GJ|1(pp|Cso};*QMA0YhzeK++#(0VC|Vdn8#Hx;BragVfVvjxXl*XJ zA-Ps;tS)UIL_YRWdgu%A+EZ>l`{E9{c94Vuhco<{otf_&?XRr#5R8AS|9<;BLFiv^ zygLXO-@!Cf5DYOa(5PMU2!l-oDWg%0{ayrmGU^097Tq!(r5N#4KY_DEES0@cuUsB2 zm)R(TI~~^j6OC3_%9dd5vmRT9^$x?&(I9&RUqgEX?2;Q}OZFw06YM?R46ny9cVQX|g5d_8c6G+k zbJU;(*o<5f7Tre+dE;h{3vDMY=p+DOk7t(SKfo|5e5M~n`m|=D9`Y*X1gE2OfDKEMA zXgVMeNpXzz9njv(#zW)JLpEQ5V$lg+kRYQ5UE)hTM>bw04BO748+OPXH@?8+V%noH zc9lHi+R~g>xt&t0Kszo3-=_P|o(w5{G3D*atPp}8aa!h#)BMONQCm@Ua4;Zx74p`Z7rtJt=!52#{l&3WzM^Ze(U!8ahF7t^5B7Vd^rQgxx22Szv}Cx% z=AH#gH0U1s1OJXKS%ktKCUZO|^9UqvhaJ&Vf#l$DmmQ&w_@GibNP&J+8k}4_AsjaoVfeo@X z6bPn*?F(h-1F0r%SG9tVerR0I>brx+7=$go!8<*a` zcfDV8QS@AP&GfJa!$)EyUNN{UOls#^dateGX2{XCP3L;m&m&t&xm$ zaF6r|!SK5#*KyLv`b)SmxT`;cMN<%?PoXh~<1;Rq(nC|c9+v8in<2OcPHNw2Ar&2Y zErj|>cyZgx!_dk@dtMdtrS^1kog2gRO8Y+5T`zna2Lgs5-eGM>D^NGxDHW>)|JMKI V7|-w&rzFD}BopJcDD9@p{{!oCdu#vz diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc deleted file mode 100644 index b9e06c856e8519175e34730ffd14ff0b39b55b52..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3280 zcmaJ@OLH5?5uVvyESBI?4>Kx9b|$tf3|u7WL!3&bWG4y*DJn}eLsAt9mDF;H82~Hp zD>JjCh>$1R*Z41xm0bKoa?BstYfirToJ-O@0}vp^cu~9a!0b-<*I)NHFXrbP1g?J- z-|sz|C*n0@^YwB2Ok*=v&i?t%^9z=bi z{-i$s4DO%*X6wOWl$7FgElY9IixMT8UEF&5s=;6bZgm$Pn!Kjk(EuX$&fEhR%yov@ z#z1rr6pMQd_G|4&N`!?Jz4#4_GH&KZ!!**}L95YVaP1Ca#Rjk-5sGcKx7aT}`IL3@ zv`FG8)9f&ox{MMgGU(-5Dl)BF=EZ7uYKNvyR%VET;A=+%A(Az<-_x=<`X&Ci9>$p#65v}eb)2a6kp*Btt2nOigtE-CIO~UH z#)S+IVIDD24m^l2=ivDkdPqKl9@?UbrktK(h@D}26*DQKWQ-ZWqJ+K)rJFEeU3gau z&W>U|V8w9}t*9}0X!;1UsSSWH^+BW%C0Pf%CP3NVEX-9uz2>eI{W6KbZ5tN&@_Vq% zI$xKI(0|K$3X{fpghrDyQZzI@Bj7$AKG_z!lo{Iv>LG8A#EKMbgfNRU6?4I&DL+=( zVsz9*Nin~yQYkQwtk&_TYRJKBBiaeCpL zl3`2NPRJSk=Kd)?q38YuIj>)kKN5$0O8!8$$={*BV|p*4mo0ll2L}zgO9}p7LFw5c zFU_;*4!_zXsc_vm7+gQUZWx`pOYX&^v>ruBWlwtrS>&3|k%3))&=Vo)Ja&lF9MWhFn_d1U= zOO*hysJy%oS>@rUs)mAm)n@yu{`AYXl(__gE!uB|V1I~PRJ1o09>cJALP*tcYMuE= z3pP+l7~(Hchc@U(bb-ouVSI&OE=+iEn*eP=2l;hMPM|a$1oFOyU~%UHt2~sb6Y_}s z`QuZn-E;4RUeHtL#DR4)lASo`HSS$dUOR9kv#bBYxDOnyM;#!r$x^oWe?qgzdbz~< z1~rylsj)y|D8LG;u?@<&zNtcV<6aCEPY)u^pbBL-zaK$5V7ydW6uE-*);Zf3CYcXo z74IhyI+>^JGDoHh*FJx68xmJA`KHc1S_To`H+qP?Ucy!(7G_CG7n&-T80Oi^J(CE)cLPh^PB*ZW0?k2egyw? z@$d14)$3BXKY_uhdSMN7wf7p1D3Anp*2k2Aie?o3ypHK%^y#0L`4GkrvV6_jboCg~ z(r@$!OuT^#q#zuoVk7P#mX;ny;L{i@0u-veA9oRVRH!LwH5tSO2rtABBM2#hC4Q6@ zhM-rYiJ37@ff1i?&_zqK;g5g7_+}t)0XXtDJgPd6LHbis)#1=(s~&D!1)-^5VJPq5 zGT-_O6>bjy4%3{6@Md*?5;!wIK5LnmuZQ`=aI)GSCf-(86dhX!>&w)q4uPP%ausH; zgc`=6C!;!eA39hE<($=7?LhyYc2RS=4eRrvdL(pJ z$2 bool - return os.path.exists(os.path.join(directory, PIP_DELETE_MARKER_FILENAME)) - - -def write_delete_marker_file(directory): - # type: (str) -> None - """ - Write the pip delete marker file into this directory. - """ - filepath = os.path.join(directory, PIP_DELETE_MARKER_FILENAME) - with open(filepath, 'w') as marker_fp: - marker_fp.write(DELETE_MARKER_MESSAGE) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 3fcf4cf4f05031f7c8a22547f6990787bbef0f81..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 448 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc deleted file mode 100644 index 1d88176e1114bec8c8510f1ddd6e3fd4e3955b10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4888 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 E4d(ig^8f$< diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc deleted file mode 100644 index c9596121b61611414a8c35283c3fa86d67781042..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19216 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 -Aakanksha Agrawal <11389424+rasponic@users.noreply.github.com> -Abhinav Sagar <40603139+abhinavsagar@users.noreply.github.com> -ABHYUDAY PRATAP SINGH -abs51295 -AceGentile -Adam Chainz -Adam Tse -Adam Tse -Adam Wentz -admin -Adrien Morison -ahayrapetyan -Ahilya -AinsworthK -Akash Srivastava -Alan Yee -Albert Tugushev -Albert-Guan -albertg -Aleks Bunin -Alethea Flowers -Alex Gaynor -Alex Grönholm -Alex Loosley -Alex Morega -Alex Stachowiak -Alexander Shtyrov -Alexandre Conrad -Alexey Popravka -Alexey Popravka -Alli -Ami Fischman -Ananya Maiti -Anatoly Techtonik -Anders Kaseorg -Andreas Lutro -Andrei Geacar -Andrew Gaul -Andrey Bulgakov -Andrés Delfino <34587441+andresdelfino@users.noreply.github.com> -Andrés Delfino -Andy Freeland -Andy Freeland -Andy Kluger -Ani Hayrapetyan -Aniruddha Basak -Anish Tambe -Anrs Hu -Anthony Sottile -Antoine Musso -Anton Ovchinnikov -Anton Patrushev -Antonio Alvarado Hernandez -Antony Lee -Antti Kaihola -Anubhav Patel -Anuj Godase -AQNOUCH Mohammed -AraHaan -Arindam Choudhury -Armin Ronacher -Artem -Ashley Manton -Ashwin Ramaswami -atse -Atsushi Odagiri -Avner Cohen -Baptiste Mispelon -Barney Gale -barneygale -Bartek Ogryczak -Bastian Venthur -Ben Darnell -Ben Hoyt -Ben Rosser -Bence Nagy -Benjamin Peterson -Benjamin VanEvery -Benoit Pierre -Berker Peksag -Bernardo B. Marques -Bernhard M. Wiedemann -Bertil Hatt -Bogdan Opanchuk -BorisZZZ -Brad Erickson -Bradley Ayers -Brandon L. Reiss -Brandt Bucher -Brett Randall -Brian Cristante <33549821+brcrista@users.noreply.github.com> -Brian Cristante -Brian Rosner -BrownTruck -Bruno Oliveira -Bruno Renié -Bstrdsmkr -Buck Golemon -burrows -Bussonnier Matthias -c22 -Caleb Martinez -Calvin Smith -Carl Meyer -Carlos Liam -Carol Willing -Carter Thayer -Cass -Chandrasekhar Atina -Chih-Hsuan Yen -Chih-Hsuan Yen -Chris Brinker -Chris Hunt -Chris Jerdonek -Chris McDonough -Chris Wolfe -Christian Heimes -Christian Oudard -Christopher Hunt -Christopher Snyder -Clark Boylan -Clay McClure -Cody -Cody Soyland -Colin Watson -Connor Osborn -Cooper Lees -Cooper Ry Lees -Cory Benfield -Cory Wright -Craig Kerstiens -Cristian Sorinel -Curtis Doty -cytolentino -Damian Quiroga -Dan Black -Dan Savilonis -Dan Sully -daniel -Daniel Collins -Daniel Hahler -Daniel Holth -Daniel Jost -Daniel Shaulov -Daniele Esposti -Daniele Procida -Danny Hermes -Dav Clark -Dave Abrahams -Dave Jones -David Aguilar -David Black -David Bordeynik -David Bordeynik -David Caro -David Evans -David Linke -David Pursehouse -David Tucker -David Wales -Davidovich -derwolfe -Desetude -Diego Caraballo -DiegoCaraballo -Dmitry Gladkov -Domen Kožar -Donald Stufft -Dongweiming -Douglas Thor -DrFeathers -Dustin Ingram -Dwayne Bailey -Ed Morley <501702+edmorley@users.noreply.github.com> -Ed Morley -Eitan Adler -ekristina -elainechan -Eli Schwartz -Eli Schwartz -Emil Burzo -Emil Styrke -Endoh Takanao -enoch -Erdinc Mutlu -Eric Gillingham -Eric Hanchrow -Eric Hopper -Erik M. Bray -Erik Rose -Ernest W Durbin III -Ernest W. Durbin III -Erwin Janssen -Eugene Vereshchagin -everdimension -Felix Yan -fiber-space -Filip Kokosiński -Florian Briand -Florian Rathgeber -Francesco -Francesco Montesano -Frost Ming -Gabriel Curio -Gabriel de Perthuis -Garry Polley -gdanielson -Geoffrey Lehée -Geoffrey Sneddon -George Song -Georgi Valkov -Giftlin Rajaiah -gizmoguy1 -gkdoc <40815324+gkdoc@users.noreply.github.com> -Gopinath M <31352222+mgopi1990@users.noreply.github.com> -GOTO Hayato <3532528+gh640@users.noreply.github.com> -gpiks -Guilherme Espada -Guy Rozendorn -gzpan123 -Hanjun Kim -Hari Charan -Harsh Vardhan -Herbert Pfennig -Hsiaoming Yang -Hugo -Hugo Lopes Tavares -Hugo van Kemenade -hugovk -Hynek Schlawack -Ian Bicking -Ian Cordasco -Ian Lee -Ian Stapleton Cordasco -Ian Wienand -Ian Wienand -Igor Kuzmitshov -Igor Sobreira -Ilya Baryshev -INADA Naoki -Ionel Cristian Mărieș -Ionel Maries Cristian -Ivan Pozdeev -Jacob Kim -jakirkham -Jakub Stasiak -Jakub Vysoky -Jakub Wilk -James Cleveland -James Cleveland -James Firth -James Polley -Jan Pokorný -Jannis Leidel -jarondl -Jason R. Coombs -Jay Graves -Jean-Christophe Fillion-Robin -Jeff Barber -Jeff Dairiki -Jelmer Vernooij -jenix21 -Jeremy Stanley -Jeremy Zafran -Jiashuo Li -Jim Garrison -Jivan Amara -John Paton -John-Scott Atlakson -johnthagen -johnthagen -Jon Banafato -Jon Dufresne -Jon Parise -Jonas Nockert -Jonathan Herbert -Joost Molenaar -Jorge Niedbalski -Joseph Long -Josh Bronson -Josh Hansen -Josh Schneier -Juanjo Bazán -Julian Berman -Julian Gethmann -Julien Demoor -jwg4 -Jyrki Pulliainen -Kai Chen -Kamal Bin Mustafa -kaustav haldar -keanemind -Keith Maxwell -Kelsey Hightower -Kenneth Belitzky -Kenneth Reitz -Kenneth Reitz -Kevin Burke -Kevin Carter -Kevin Frommelt -Kevin R Patterson -Kexuan Sun -Kit Randel -kpinc -Krishna Oza -Kumar McMillan -Kyle Persohn -lakshmanaram -Laszlo Kiss-Kollar -Laurent Bristiel -Laurie Opperman -Leon Sasson -Lev Givon -Lincoln de Sousa -Lipis -Loren Carvalho -Lucas Cimon -Ludovic Gasc -Luke Macken -Luo Jiebin -luojiebin -luz.paz -László Kiss Kollár -László Kiss Kollár -Marc Abramowitz -Marc Tamlyn -Marcus Smith -Mariatta -Mark Kohler -Mark Williams -Mark Williams -Markus Hametner -Masaki -Masklinn -Matej Stuchlik -Mathew Jennings -Mathieu Bridon -Matt Good -Matt Maker -Matt Robenolt -matthew -Matthew Einhorn -Matthew Gilliard -Matthew Iversen -Matthew Trumbell -Matthew Willson -Matthias Bussonnier -mattip -Maxim Kurnikov -Maxime Rouyrre -mayeut -mbaluna <44498973+mbaluna@users.noreply.github.com> -mdebi <17590103+mdebi@users.noreply.github.com> -memoselyk -Michael -Michael Aquilina -Michael E. Karpeles -Michael Klich -Michael Williamson -michaelpacer -Mickaël Schoentgen -Miguel Araujo Perez -Mihir Singh -Mike -Mike Hendricks -Min RK -MinRK -Miro Hrončok -Monica Baluna -montefra -Monty Taylor -Nate Coraor -Nathaniel J. Smith -Nehal J Wani -Neil Botelho -Nick Coghlan -Nick Stenning -Nick Timkovich -Nicolas Bock -Nikhil Benesch -Nitesh Sharma -Nowell Strite -NtaleGrey -nvdv -Ofekmeister -ofrinevo -Oliver Jeeves -Oliver Tonnhofer -Olivier Girardot -Olivier Grisel -Ollie Rutherfurd -OMOTO Kenji -Omry Yadan -Oren Held -Oscar Benjamin -Oz N Tiram -Pachwenko <32424503+Pachwenko@users.noreply.github.com> -Patrick Dubroy -Patrick Jenkins -Patrick Lawson -patricktokeeffe -Patrik Kopkan -Paul Kehrer -Paul Moore -Paul Nasrat -Paul Oswald -Paul van der Linden -Paulus Schoutsen -Pavithra Eswaramoorthy <33131404+QueenCoffee@users.noreply.github.com> -Pawel Jasinski -Pekka Klärck -Peter Lisák -Peter Waller -petr-tik -Phaneendra Chiruvella -Phil Freo -Phil Pennock -Phil Whelan -Philip Jägenstedt -Philip Molloy -Philippe Ombredanne -Pi Delport -Pierre-Yves Rofes -pip -Prabakaran Kumaresshan -Prabhjyotsing Surjit Singh Sodhi -Prabhu Marappan -Pradyun Gedam -Pratik Mallya -Preet Thakkar -Preston Holmes -Przemek Wrzos -Pulkit Goyal <7895pulkit@gmail.com> -Qiangning Hong -Quentin Pradet -R. David Murray -Rafael Caricio -Ralf Schmitt -Razzi Abuissa -rdb -Remi Rampin -Remi Rampin -Rene Dudfield -Riccardo Magliocchetti -Richard Jones -RobberPhex -Robert Collins -Robert McGibbon -Robert T. McGibbon -robin elisha robinson -Roey Berman -Rohan Jain -Rohan Jain -Rohan Jain -Roman Bogorodskiy -Romuald Brunet -Ronny Pfannschmidt -Rory McCann -Ross Brattain -Roy Wellington Ⅳ -Roy Wellington Ⅳ -Ryan Wooden -ryneeverett -Sachi King -Salvatore Rinchiera -Savio Jomton -schlamar -Scott Kitterman -Sean -seanj -Sebastian Jordan -Sebastian Schaetz -Segev Finer -SeongSoo Cho -Sergey Vasilyev -Seth Woodworth -Shlomi Fish -Shovan Maity -Simeon Visser -Simon Cross -Simon Pichugin -sinoroc -Sorin Sbarnea -Stavros Korokithakis -Stefan Scherfke -Stephan Erb -stepshal -Steve (Gadget) Barnes -Steve Barnes -Steve Dower -Steve Kowalik -Steven Myint -stonebig -Stéphane Bidoul (ACSONE) -Stéphane Bidoul -Stéphane Klein -Sumana Harihareswara -Sviatoslav Sydorenko -Sviatoslav Sydorenko -Swat009 -Takayuki SHIMIZUKAWA -tbeswick -Thijs Triemstra -Thomas Fenzl -Thomas Grainger -Thomas Guettler -Thomas Johansson -Thomas Kluyver -Thomas Smith -Tim D. Smith -Tim Gates -Tim Harder -Tim Heap -tim smith -tinruufu -Tom Forbes -Tom Freudenheim -Tom V -Tomas Orsava -Tomer Chachamu -Tony Beswick -Tony Zhaocheng Tan -TonyBeswick -toonarmycaptain -Toshio Kuratomi -Travis Swicegood -Tzu-ping Chung -Valentin Haenel -Victor Stinner -victorvpaulo -Viktor Szépe -Ville Skyttä -Vinay Sajip -Vincent Philippon -Vinicyus Macedo <7549205+vinicyusmacedo@users.noreply.github.com> -Vitaly Babiy -Vladimir Rutsky -W. Trevor King -Wil Tan -Wilfred Hughes -William ML Leslie -William T Olson -Wilson Mo -wim glenn -Wolfgang Maier -Xavier Fernandez -Xavier Fernandez -xoviat -xtreak -YAMAMOTO Takashi -Yen Chi Hsuan -Yeray Diaz Diaz -Yoval P -Yu Jian -Yuan Jing Vincent Yan -Zearin -Zearin -Zhiping Deng -Zvezdan Petkovic -Łukasz Langa -Семён Марьясин diff --git a/venv/lib/python3.8/site-packages/pkg_resources/__pycache__/py31compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/__pycache__/py31compat.cpython-38.pyc deleted file mode 100644 index c69703b9a3baf63af5e81785b5e623078566b75a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 600 zcmYjO&2AGh5T3EU$!3*=o={(54{4gVh)abkP^u!Kf)sw*y`&*F?PinR)p$dbD&>H9 z5IFKMynwHqa^uVaF%F{YSpLRik7vG_dDCh|!1AN~b+ID=etP4+NH&gm+Y1H_8mEx_ z)0p7K7KzY8%c-2HL?P&g4s`7cCV^3tTKPiPjhNIGNXW1_(P0L;5`d6|CZx9}$d!Rf zBWY+HKpd?(3!JWzF-9kCx;P#)tvm5_JmF`&?Fqw8yMnK{f^UfM4)Oy9mB=D`if}6s zZXT|Xc2{B|D>+e_q`lAV^@t0&6`#ZzoI}p2fm7pY95_)}7tThR(J5J1e>vzA732a# zlozhn@1H#%ypE+)<*2%Hp;@H18Wx$8W-Y*C@24I6T-V`$bPrlSWOz6$^n7Zb_&HghIYeHfDWhf$xBm$B7g?rg`kg0lr55A%qI;5m2QF4tp`19cS0-u5I}dl>J70 z7$nZQa^l9B1Hw)~#UuahvBqQn$Nn%J_K<5|<)&UR%6{>?Y zs9R~P4%09|(1H*mXu}b7Ack%crxEnhHuTdY7^EE-rZF6+T{ua5FiQLIfObz&I)H~u zGvGo@Y4a#1I8E3@Q2O|-a}J#QvAf@c-r zrLpU^!5Ih4xR(hwt8gy3QEX+6P`VkxKJ-fOLuX7h<2TD2>`s5}vX&ITJzV}7{&-M| z&t~)H^!lF)d^TU4PaQ7sQ~iE2^krCEW0jMu+%qE;dPEMsZdv7OqS}7x$fM)oUtV=R z{0~umkAcG%q(*-3@#|e;YMDqTr$6*WowO~K~j@nV+tmVuz_yZwD&lUgx diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 7e9dc63663107b546241da2f50ecb8ca86acad22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 545 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 G*#83{?8xB& diff --git a/venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/AUTHORS.txt b/venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/AUTHORS.txt deleted file mode 100644 index 72c87d7..0000000 --- a/venv/lib/python3.8/site-packages/setuptools-44.0.0.dist-info/AUTHORS.txt +++ /dev/null @@ -1,562 +0,0 @@ -A_Rog -Aakanksha Agrawal <11389424+rasponic@users.noreply.github.com> -Abhinav Sagar <40603139+abhinavsagar@users.noreply.github.com> -ABHYUDAY PRATAP SINGH -abs51295 -AceGentile -Adam Chainz -Adam Tse -Adam Tse -Adam Wentz -admin -Adrien Morison -ahayrapetyan -Ahilya -AinsworthK -Akash Srivastava -Alan Yee -Albert Tugushev -Albert-Guan -albertg -Aleks Bunin -Alethea Flowers -Alex Gaynor -Alex Grönholm -Alex Loosley -Alex Morega -Alex Stachowiak -Alexander Shtyrov -Alexandre Conrad -Alexey Popravka -Alexey Popravka -Alli -Ami Fischman -Ananya Maiti -Anatoly Techtonik -Anders Kaseorg -Andreas Lutro -Andrei Geacar -Andrew Gaul -Andrey Bulgakov -Andrés Delfino <34587441+andresdelfino@users.noreply.github.com> -Andrés Delfino -Andy Freeland -Andy Freeland -Andy Kluger -Ani Hayrapetyan -Aniruddha Basak -Anish Tambe -Anrs Hu -Anthony Sottile -Antoine Musso -Anton Ovchinnikov -Anton Patrushev -Antonio Alvarado Hernandez -Antony Lee -Antti Kaihola -Anubhav Patel -Anuj Godase -AQNOUCH Mohammed -AraHaan -Arindam Choudhury -Armin Ronacher -Artem -Ashley Manton -Ashwin Ramaswami -atse -Atsushi Odagiri -Avner Cohen -Baptiste Mispelon -Barney Gale -barneygale -Bartek Ogryczak -Bastian Venthur -Ben Darnell -Ben Hoyt -Ben Rosser -Bence Nagy -Benjamin Peterson -Benjamin VanEvery -Benoit Pierre -Berker Peksag -Bernardo B. Marques -Bernhard M. Wiedemann -Bertil Hatt -Bogdan Opanchuk -BorisZZZ -Brad Erickson -Bradley Ayers -Brandon L. Reiss -Brandt Bucher -Brett Randall -Brian Cristante <33549821+brcrista@users.noreply.github.com> -Brian Cristante -Brian Rosner -BrownTruck -Bruno Oliveira -Bruno Renié -Bstrdsmkr -Buck Golemon -burrows -Bussonnier Matthias -c22 -Caleb Martinez -Calvin Smith -Carl Meyer -Carlos Liam -Carol Willing -Carter Thayer -Cass -Chandrasekhar Atina -Chih-Hsuan Yen -Chih-Hsuan Yen -Chris Brinker -Chris Hunt -Chris Jerdonek -Chris McDonough -Chris Wolfe -Christian Heimes -Christian Oudard -Christopher Hunt -Christopher Snyder -Clark Boylan -Clay McClure -Cody -Cody Soyland -Colin Watson -Connor Osborn -Cooper Lees -Cooper Ry Lees -Cory Benfield -Cory Wright -Craig Kerstiens -Cristian Sorinel -Curtis Doty -cytolentino -Damian Quiroga -Dan Black -Dan Savilonis -Dan Sully -daniel -Daniel Collins -Daniel Hahler -Daniel Holth -Daniel Jost -Daniel Shaulov -Daniele Esposti -Daniele Procida -Danny Hermes -Dav Clark -Dave Abrahams -Dave Jones -David Aguilar -David Black -David Bordeynik -David Bordeynik -David Caro -David Evans -David Linke -David Pursehouse -David Tucker -David Wales -Davidovich -derwolfe -Desetude -Diego Caraballo -DiegoCaraballo -Dmitry Gladkov -Domen Kožar -Donald Stufft -Dongweiming -Douglas Thor -DrFeathers -Dustin Ingram -Dwayne Bailey -Ed Morley <501702+edmorley@users.noreply.github.com> -Ed Morley -Eitan Adler -ekristina -elainechan -Eli Schwartz -Eli Schwartz -Emil Burzo -Emil Styrke -Endoh Takanao -enoch -Erdinc Mutlu -Eric Gillingham -Eric Hanchrow -Eric Hopper -Erik M. Bray -Erik Rose -Ernest W Durbin III -Ernest W. Durbin III -Erwin Janssen -Eugene Vereshchagin -everdimension -Felix Yan -fiber-space -Filip Kokosiński -Florian Briand -Florian Rathgeber -Francesco -Francesco Montesano -Frost Ming -Gabriel Curio -Gabriel de Perthuis -Garry Polley -gdanielson -Geoffrey Lehée -Geoffrey Sneddon -George Song -Georgi Valkov -Giftlin Rajaiah -gizmoguy1 -gkdoc <40815324+gkdoc@users.noreply.github.com> -Gopinath M <31352222+mgopi1990@users.noreply.github.com> -GOTO Hayato <3532528+gh640@users.noreply.github.com> -gpiks -Guilherme Espada -Guy Rozendorn -gzpan123 -Hanjun Kim -Hari Charan -Harsh Vardhan -Herbert Pfennig -Hsiaoming Yang -Hugo -Hugo Lopes Tavares -Hugo van Kemenade -hugovk -Hynek Schlawack -Ian Bicking -Ian Cordasco -Ian Lee -Ian Stapleton Cordasco -Ian Wienand -Ian Wienand -Igor Kuzmitshov -Igor Sobreira -Ilya Baryshev -INADA Naoki -Ionel Cristian Mărieș -Ionel Maries Cristian -Ivan Pozdeev -Jacob Kim -jakirkham -Jakub Stasiak -Jakub Vysoky -Jakub Wilk -James Cleveland -James Cleveland -James Firth -James Polley -Jan Pokorný -Jannis Leidel -jarondl -Jason R. Coombs -Jay Graves -Jean-Christophe Fillion-Robin -Jeff Barber -Jeff Dairiki -Jelmer Vernooij -jenix21 -Jeremy Stanley -Jeremy Zafran -Jiashuo Li -Jim Garrison -Jivan Amara -John Paton -John-Scott Atlakson -johnthagen -johnthagen -Jon Banafato -Jon Dufresne -Jon Parise -Jonas Nockert -Jonathan Herbert -Joost Molenaar -Jorge Niedbalski -Joseph Long -Josh Bronson -Josh Hansen -Josh Schneier -Juanjo Bazán -Julian Berman -Julian Gethmann -Julien Demoor -jwg4 -Jyrki Pulliainen -Kai Chen -Kamal Bin Mustafa -kaustav haldar -keanemind -Keith Maxwell -Kelsey Hightower -Kenneth Belitzky -Kenneth Reitz -Kenneth Reitz -Kevin Burke -Kevin Carter -Kevin Frommelt -Kevin R Patterson -Kexuan Sun -Kit Randel -kpinc -Krishna Oza -Kumar McMillan -Kyle Persohn -lakshmanaram -Laszlo Kiss-Kollar -Laurent Bristiel -Laurie Opperman -Leon Sasson -Lev Givon -Lincoln de Sousa -Lipis -Loren Carvalho -Lucas Cimon -Ludovic Gasc -Luke Macken -Luo Jiebin -luojiebin -luz.paz -László Kiss Kollár -László Kiss Kollár -Marc Abramowitz -Marc Tamlyn -Marcus Smith -Mariatta -Mark Kohler -Mark Williams -Mark Williams -Markus Hametner -Masaki -Masklinn -Matej Stuchlik -Mathew Jennings -Mathieu Bridon -Matt Good -Matt Maker -Matt Robenolt -matthew -Matthew Einhorn -Matthew Gilliard -Matthew Iversen -Matthew Trumbell -Matthew Willson -Matthias Bussonnier -mattip -Maxim Kurnikov -Maxime Rouyrre -mayeut -mbaluna <44498973+mbaluna@users.noreply.github.com> -mdebi <17590103+mdebi@users.noreply.github.com> -memoselyk -Michael -Michael Aquilina -Michael E. Karpeles -Michael Klich -Michael Williamson -michaelpacer -Mickaël Schoentgen -Miguel Araujo Perez -Mihir Singh -Mike -Mike Hendricks -Min RK -MinRK -Miro Hrončok -Monica Baluna -montefra -Monty Taylor -Nate Coraor -Nathaniel J. Smith -Nehal J Wani -Neil Botelho -Nick Coghlan -Nick Stenning -Nick Timkovich -Nicolas Bock -Nikhil Benesch -Nitesh Sharma -Nowell Strite -NtaleGrey -nvdv -Ofekmeister -ofrinevo -Oliver Jeeves -Oliver Tonnhofer -Olivier Girardot -Olivier Grisel -Ollie Rutherfurd -OMOTO Kenji -Omry Yadan -Oren Held -Oscar Benjamin -Oz N Tiram -Pachwenko <32424503+Pachwenko@users.noreply.github.com> -Patrick Dubroy -Patrick Jenkins -Patrick Lawson -patricktokeeffe -Patrik Kopkan -Paul Kehrer -Paul Moore -Paul Nasrat -Paul Oswald -Paul van der Linden -Paulus Schoutsen -Pavithra Eswaramoorthy <33131404+QueenCoffee@users.noreply.github.com> -Pawel Jasinski -Pekka Klärck -Peter Lisák -Peter Waller -petr-tik -Phaneendra Chiruvella -Phil Freo -Phil Pennock -Phil Whelan -Philip Jägenstedt -Philip Molloy -Philippe Ombredanne -Pi Delport -Pierre-Yves Rofes -pip -Prabakaran Kumaresshan -Prabhjyotsing Surjit Singh Sodhi -Prabhu Marappan -Pradyun Gedam -Pratik Mallya -Preet Thakkar -Preston Holmes -Przemek Wrzos -Pulkit Goyal <7895pulkit@gmail.com> -Qiangning Hong -Quentin Pradet -R. David Murray -Rafael Caricio -Ralf Schmitt -Razzi Abuissa -rdb -Remi Rampin -Remi Rampin -Rene Dudfield -Riccardo Magliocchetti -Richard Jones -RobberPhex -Robert Collins -Robert McGibbon -Robert T. McGibbon -robin elisha robinson -Roey Berman -Rohan Jain -Rohan Jain -Rohan Jain -Roman Bogorodskiy -Romuald Brunet -Ronny Pfannschmidt -Rory McCann -Ross Brattain -Roy Wellington Ⅳ -Roy Wellington Ⅳ -Ryan Wooden -ryneeverett -Sachi King -Salvatore Rinchiera -Savio Jomton -schlamar -Scott Kitterman -Sean -seanj -Sebastian Jordan -Sebastian Schaetz -Segev Finer -SeongSoo Cho -Sergey Vasilyev -Seth Woodworth -Shlomi Fish -Shovan Maity -Simeon Visser -Simon Cross -Simon Pichugin -sinoroc -Sorin Sbarnea -Stavros Korokithakis -Stefan Scherfke -Stephan Erb -stepshal -Steve (Gadget) Barnes -Steve Barnes -Steve Dower -Steve Kowalik -Steven Myint -stonebig -Stéphane Bidoul (ACSONE) -Stéphane Bidoul -Stéphane Klein -Sumana Harihareswara -Sviatoslav Sydorenko -Sviatoslav Sydorenko -Swat009 -Takayuki SHIMIZUKAWA -tbeswick -Thijs Triemstra -Thomas Fenzl -Thomas Grainger -Thomas Guettler -Thomas Johansson -Thomas Kluyver -Thomas Smith -Tim D. Smith -Tim Gates -Tim Harder -Tim Heap -tim smith -tinruufu -Tom Forbes -Tom Freudenheim -Tom V -Tomas Orsava -Tomer Chachamu -Tony Beswick -Tony Zhaocheng Tan -TonyBeswick -toonarmycaptain -Toshio Kuratomi -Travis Swicegood -Tzu-ping Chung -Valentin Haenel -Victor Stinner -victorvpaulo -Viktor Szépe -Ville Skyttä -Vinay Sajip -Vincent Philippon -Vinicyus Macedo <7549205+vinicyusmacedo@users.noreply.github.com> -Vitaly Babiy -Vladimir Rutsky -W. Trevor King -Wil Tan -Wilfred Hughes -William ML Leslie -William T Olson -Wilson Mo -wim glenn -Wolfgang Maier -Xavier Fernandez -Xavier Fernandez -xoviat -xtreak -YAMAMOTO Takashi -Yen Chi Hsuan -Yeray Diaz Diaz -Yoval P -Yu Jian -Yuan Jing Vincent Yan -Zearin -Zearin -Zhiping Deng -Zvezdan Petkovic -Łukasz Langa -Семён Марьясин diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 0febf9c0f3053cbd6185e3c2c459cc58a6973feb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7768 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 diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-38.pyc deleted file mode 100644 index 7e457113e5a02348de86edc9b79852e2ea0a17f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 516 zcmZWly-ve05O&gvRuPpL7#X})qRoU@5UK!)txG{jU2HdYiG^buJ84x`coH@qh8M`n z3m~yEarqG~;-v3J^xT;TJe;9n zCxOf#3Ba2G`~fI|pbpJL9?UyUeR(t!d0}&7l)n#U2nE5&4IVbUI9Y&WhtaRncO>Ibzy9foDE Yy<#2M4sEO+)Rz6T=CkJ&{R@D80BjhJo&W#< diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/glob.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/glob.cpython-38.pyc deleted file mode 100644 index 5a1cff99f44ff4dad3c719b12087ed5122a49d04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3733 zcmeHK&2Jn@74NG4n4b37vAtO**$t@ngLTFmJ72p3q17&nH&JrHLoSxcMuBX~=nH4PA*W;ueJH2p4Ema!$^ppGx^*OTKc% z)~D_0B1SXvRk?t<3-Xe@jDA*Lkv{r4$salGs|QEXy(~|QxSxt{UT$t?MOW;aEYHkv zMf{-DCLfAeB;{Zz$}O=$Yc|A|D*NK$(Dcee+*x^lC5l#ianVh+$ciN2mFagQu_QKz zS(;0`ctga66c6t{ymRa3ZLzVmAynEgpQUnz7T(XKObf9EL9~cfDvHvGtXq_d7W@sS zbJl8)j;{U8c0sC>c#z&pI89C-8vAIgXnGdJIEGbD1!Mn)KW9*v$3x~gKT6H6Dxg)K zX+v5KV$;*2ADg5{>c^I0O@bMdssaiMJU{NGG({Y&9>OYxiL*lJtUt(8p?hhbFKaWz zcrVLk5-SOPL>}9(w+eg0inw3yrO#4zUF;Tlwv&p<#C2-`I#vs9Vr58{z0CB)_78d{d6nqMi0SPg57JI!c=?M#W@`yF!{}J`SK$KSpopDNNbuxVnuG%Zo zeN)eTtaXY&DvP^Hm8$Kj20U&7R`bl%Ok0$VNt31s8s9|IHm^@bti?k7&OnHO8K5P! z?w=sW*=C2la*o*NfYHb`E`dnj19)!QIgjSl_bca9hdIT(<@psq;YsI_Q*r$(K(H`D z8hMpR-#*Drd)4U*dd#7kv{e3EF-URJ_YZK4xg| zKj56NCg*%*8l&LppG-Ik3eQBNpz?9z+Xx4IGdcg_s9|NE0;h4rtt5YW`e!=x1zT&k zYF_HvqX4dbJwWZKo4r_f`f)c)>PDXKBhEE)w?;}(Q?OX=Q>@+|cefN7dpy2bd)sAJ zw8K-LYTzqM40X7PlxIh5zxKe@^%U*X$%+o%;B-nKGwb!HVbchlwrF~Lrx?lU-*IbGoCGZ^z{j%gf{d)X24%?rL(`yW4A zeej^&tfNe41jK&WiS z1aG+B{15Q;7Qvw^71dMOuA`V7FRTj@kxZ34=&SN4x+Z>8wdf1M4o1yvZ!D zyh$2(_H>PQQg1-4cBI}yr`{$)=v3b#@(z(jklIfv4Uc_Fo>a>q@HF93T_<9#L_V+C z@VvEX@z2pTeR>v=6xAWTyZ{^8O%EE^9xr|L_(@w+#-EJO7?t2k?q5aI*FfkZU=6x} zP(=nusInq5-pesTVyAfm&tp~VIh*J@NiR)yIyN@zK&P=vdiB()Dd6@3&Z&KSO*^mM zMNIvUWEo=tm4_qBhw?I;*#9IaKB?=<<;H|s%Ixk|}Hjl5jy;#Kw@)fSEba~Wt;N#D4Jvs1*qC!}N zS*%31=tzaj?1_SkvVQI2BC065p*umL_Q%W4sZE=Ii8ikL{;bV*E!JlD=x@GmbULz3 zI-POS0P#Y?ddMR;nu+Gacf;v$HVnhLh(#{?#=ij6jb!ow diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/installer.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/installer.cpython-38.pyc deleted file mode 100644 index d727d03c910208e299561aa9e27b1446cc973586..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4102 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 diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/package_index.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/package_index.cpython-38.pyc deleted file mode 100644 index ba3d16f418d82c437a83ad10eee1c78f6d17d360..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32970 zcmd6Qd2}2{dS7?XJpcwENP>qXYQ#gtNCZfcx|ReX-XbLm;*!)gqBIzw8^8c_fYl9> z7!9=RrM#lo)>^ySOh7r#FFkKQqi-{(#HUlcb-@N>Ut z8HR1-4coM>vY9vKYUM4tM)DE4M)Og*#_}<_#`AHxCh`fnCi6+Trt&FVBjt3ZC*NbT z&S<%}(wFa(c&wbM^ym941Nni|R zGrv>fsq(JM{rUSPo-XgM4CjX>-c!z19>_l+@!s--l|A`A67MUIR7Ufors3?(?{gxn z580VDGrwPA{Z3^5z?zkRSndXp{)oiZ>Gb(W^N-nstB!;U#W{%ONmZ*P6e%0FS>W#9dVkw0SJV{gRusJ+d;7uRF`8mr&f)pf(y|AF z7N2oW+Yj1%-Y~A4`KO*V>=AqP4Z|M2ZsniG-Clbi?)EuPUytO^;{G9fJ?_^#TXFx4 z)U$uhoS(=)Yag&5M&0M^N9;#&{iyx4{h0kY-g@5th2k@bdVcS8tvXYhT`VfsQGTRST+H?PeaBCqJpS~v z&s{8>ICJ5m-+Q9uda5+Fb702(D=oLq~@(!<7m?@PV$?7@pTwX$V zrJCLoC!arg_Stj#4at*FJ}EKuvd4AH1$Sw2v8FtBx?G#ZCBwF(;br%vQZEa@@V=v4(PPxA2RcChg@bJqcM@RC-k@~)o zj}%59yzi9=ae&Z$$j83elPFd{>l@>FTc8b`*;?a_3LBBEVB=9N8*PZ-3^*BiXs4JGWgjbNcC*Uwz`02QNKwusF>L zIPA{Vt`;ixBlj08i-+vetmArU8yZy{nR(^41N&F-8f42Wa`izp`@vD&>Q`Rdzh@