From 9313dc5d5c41d872c30abfa5c46c1d24dfef5ef1 Mon Sep 17 00:00:00 2001 From: juan Date: Fri, 13 May 2022 17:55:48 +0800 Subject: [PATCH] Add everything --- .envrc | 2 + __pycache__/app.cpython-39.pyc | Bin 0 -> 596 bytes __pycache__/wsgi.cpython-39.pyc | Bin 0 -> 198 bytes app.py | 15 + templates/privacypolicy.html | 222 + wsgi.py | 4 + zhdo.space.ini | 11 + zhdo.space/bin/Activate.ps1 | 241 + zhdo.space/bin/activate | 66 + zhdo.space/bin/activate.csh | 25 + zhdo.space/bin/activate.fish | 64 + zhdo.space/bin/flask | 8 + zhdo.space/bin/pip | 8 + zhdo.space/bin/pip3 | 8 + zhdo.space/bin/pip3.10 | 8 + zhdo.space/bin/pip3.9 | 8 + zhdo.space/bin/python | 1 + zhdo.space/bin/python3 | 1 + zhdo.space/bin/python3.9 | 1 + zhdo.space/bin/uwsgi | Bin 0 -> 1447192 bytes zhdo.space/bin/wheel | 8 + .../Flask-2.1.2.dist-info/INSTALLER | 1 + .../Flask-2.1.2.dist-info/LICENSE.rst | 28 + .../Flask-2.1.2.dist-info/METADATA | 126 + .../Flask-2.1.2.dist-info/RECORD | 52 + .../Flask-2.1.2.dist-info/REQUESTED | 0 .../site-packages/Flask-2.1.2.dist-info/WHEEL | 5 + .../Flask-2.1.2.dist-info/entry_points.txt | 2 + .../Flask-2.1.2.dist-info/top_level.txt | 1 + .../Jinja2-3.1.2.dist-info/INSTALLER | 1 + .../Jinja2-3.1.2.dist-info/LICENSE.rst | 28 + .../Jinja2-3.1.2.dist-info/METADATA | 113 + .../Jinja2-3.1.2.dist-info/RECORD | 58 + .../Jinja2-3.1.2.dist-info/WHEEL | 5 + .../Jinja2-3.1.2.dist-info/entry_points.txt | 2 + .../Jinja2-3.1.2.dist-info/top_level.txt | 1 + .../MarkupSafe-2.1.1.dist-info/INSTALLER | 1 + .../MarkupSafe-2.1.1.dist-info/LICENSE.rst | 28 + .../MarkupSafe-2.1.1.dist-info/METADATA | 101 + .../MarkupSafe-2.1.1.dist-info/RECORD | 14 + .../MarkupSafe-2.1.1.dist-info/WHEEL | 6 + .../MarkupSafe-2.1.1.dist-info/top_level.txt | 1 + .../Werkzeug-2.1.2.dist-info/INSTALLER | 1 + .../Werkzeug-2.1.2.dist-info/LICENSE.rst | 28 + .../Werkzeug-2.1.2.dist-info/METADATA | 128 + .../Werkzeug-2.1.2.dist-info/RECORD | 86 + .../Werkzeug-2.1.2.dist-info/WHEEL | 5 + .../Werkzeug-2.1.2.dist-info/top_level.txt | 1 + .../uwsgidecorators.cpython-39.pyc | Bin 0 -> 14170 bytes .../__pycache__/zipp.cpython-39.pyc | Bin 0 -> 9905 bytes .../site-packages/_distutils_hack/__init__.py | 128 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 5104 bytes .../__pycache__/override.cpython-39.pyc | Bin 0 -> 235 bytes .../site-packages/_distutils_hack/override.py | 1 + .../click-8.1.3.dist-info/INSTALLER | 1 + .../click-8.1.3.dist-info/LICENSE.rst | 28 + .../click-8.1.3.dist-info/METADATA | 111 + .../click-8.1.3.dist-info/RECORD | 39 + .../site-packages/click-8.1.3.dist-info/WHEEL | 5 + .../click-8.1.3.dist-info/top_level.txt | 1 + .../python3.9/site-packages/click/__init__.py | 73 + .../click/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2618 bytes .../click/__pycache__/_compat.cpython-39.pyc | Bin 0 -> 16057 bytes .../__pycache__/_termui_impl.cpython-39.pyc | Bin 0 -> 16004 bytes .../__pycache__/_textwrap.cpython-39.pyc | Bin 0 -> 1534 bytes .../__pycache__/_winconsole.cpython-39.pyc | Bin 0 -> 7785 bytes .../click/__pycache__/core.cpython-39.pyc | Bin 0 -> 89660 bytes .../__pycache__/decorators.cpython-39.pyc | Bin 0 -> 15572 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 10133 bytes .../__pycache__/formatting.cpython-39.pyc | Bin 0 -> 9413 bytes .../click/__pycache__/globals.cpython-39.pyc | Bin 0 -> 2425 bytes .../click/__pycache__/parser.cpython-39.pyc | Bin 0 -> 13568 bytes .../shell_completion.cpython-39.pyc | Bin 0 -> 16729 bytes .../click/__pycache__/termui.cpython-39.pyc | Bin 0 -> 25947 bytes .../click/__pycache__/testing.cpython-39.pyc | Bin 0 -> 15139 bytes .../click/__pycache__/types.cpython-39.pyc | Bin 0 -> 32956 bytes .../click/__pycache__/utils.cpython-39.pyc | Bin 0 -> 17575 bytes .../python3.9/site-packages/click/_compat.py | 626 ++ .../site-packages/click/_termui_impl.py | 717 ++ .../site-packages/click/_textwrap.py | 49 + .../site-packages/click/_winconsole.py | 279 + .../lib/python3.9/site-packages/click/core.py | 2998 ++++++ .../site-packages/click/decorators.py | 497 + .../site-packages/click/exceptions.py | 287 + .../site-packages/click/formatting.py | 301 + .../python3.9/site-packages/click/globals.py | 68 + .../python3.9/site-packages/click/parser.py | 529 + .../python3.9/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 580 ++ .../python3.9/site-packages/click/termui.py | 787 ++ .../python3.9/site-packages/click/testing.py | 479 + .../python3.9/site-packages/click/types.py | 1073 +++ .../python3.9/site-packages/click/utils.py | 580 ++ .../site-packages/distutils-precedence.pth | 1 + .../python3.9/site-packages/flask/__init__.py | 45 + .../python3.9/site-packages/flask/__main__.py | 3 + .../flask/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1851 bytes .../flask/__pycache__/__main__.cpython-39.pyc | Bin 0 -> 214 bytes .../flask/__pycache__/app.cpython-39.pyc | Bin 0 -> 63297 bytes .../__pycache__/blueprints.cpython-39.pyc | Bin 0 -> 21716 bytes .../flask/__pycache__/cli.cpython-39.pyc | Bin 0 -> 26317 bytes .../flask/__pycache__/config.cpython-39.pyc | Bin 0 -> 12446 bytes .../flask/__pycache__/ctx.cpython-39.pyc | Bin 0 -> 16055 bytes .../__pycache__/debughelpers.cpython-39.pyc | Bin 0 -> 6450 bytes .../flask/__pycache__/globals.cpython-39.pyc | Bin 0 -> 1833 bytes .../flask/__pycache__/helpers.cpython-39.pyc | Bin 0 -> 25941 bytes .../flask/__pycache__/logging.cpython-39.pyc | Bin 0 -> 2450 bytes .../flask/__pycache__/scaffold.cpython-39.pyc | Bin 0 -> 24784 bytes .../flask/__pycache__/sessions.cpython-39.pyc | Bin 0 -> 13639 bytes .../flask/__pycache__/signals.cpython-39.pyc | Bin 0 -> 2370 bytes .../__pycache__/templating.cpython-39.pyc | Bin 0 -> 5565 bytes .../flask/__pycache__/testing.cpython-39.pyc | Bin 0 -> 9210 bytes .../flask/__pycache__/typing.cpython-39.pyc | Bin 0 -> 1348 bytes .../flask/__pycache__/views.cpython-39.pyc | Bin 0 -> 4982 bytes .../flask/__pycache__/wrappers.cpython-39.pyc | Bin 0 -> 5076 bytes .../lib/python3.9/site-packages/flask/app.py | 2095 ++++ .../site-packages/flask/blueprints.py | 597 ++ .../lib/python3.9/site-packages/flask/cli.py | 992 ++ .../python3.9/site-packages/flask/config.py | 337 + .../lib/python3.9/site-packages/flask/ctx.py | 513 + .../site-packages/flask/debughelpers.py | 174 + .../python3.9/site-packages/flask/globals.py | 59 + .../python3.9/site-packages/flask/helpers.py | 790 ++ .../site-packages/flask/json/__init__.py | 303 + .../json/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 10511 bytes .../flask/json/__pycache__/tag.cpython-39.pyc | Bin 0 -> 11465 bytes .../python3.9/site-packages/flask/json/tag.py | 312 + .../python3.9/site-packages/flask/logging.py | 74 + .../python3.9/site-packages/flask/py.typed | 0 .../python3.9/site-packages/flask/scaffold.py | 869 ++ .../python3.9/site-packages/flask/sessions.py | 421 + .../python3.9/site-packages/flask/signals.py | 56 + .../site-packages/flask/templating.py | 166 + .../python3.9/site-packages/flask/testing.py | 283 + .../python3.9/site-packages/flask/typing.py | 55 + .../python3.9/site-packages/flask/views.py | 158 + .../python3.9/site-packages/flask/wrappers.py | 171 + .../INSTALLER | 1 + .../LICENSE | 13 + .../METADATA | 118 + .../RECORD | 23 + .../importlib_metadata-4.11.3.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../importlib_metadata/__init__.py | 1075 +++ .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 38194 bytes .../__pycache__/_adapters.cpython-39.pyc | Bin 0 -> 2382 bytes .../__pycache__/_collections.cpython-39.pyc | Bin 0 -> 1557 bytes .../__pycache__/_compat.cpython-39.pyc | Bin 0 -> 2041 bytes .../__pycache__/_functools.cpython-39.pyc | Bin 0 -> 3147 bytes .../__pycache__/_itertools.cpython-39.pyc | Bin 0 -> 2024 bytes .../__pycache__/_meta.cpython-39.pyc | Bin 0 -> 2401 bytes .../__pycache__/_text.cpython-39.pyc | Bin 0 -> 3090 bytes .../importlib_metadata/_adapters.py | 68 + .../importlib_metadata/_collections.py | 30 + .../importlib_metadata/_compat.py | 71 + .../importlib_metadata/_functools.py | 104 + .../importlib_metadata/_itertools.py | 73 + .../site-packages/importlib_metadata/_meta.py | 48 + .../site-packages/importlib_metadata/_text.py | 99 + .../site-packages/importlib_metadata/py.typed | 0 .../itsdangerous-2.1.2.dist-info/INSTALLER | 1 + .../itsdangerous-2.1.2.dist-info/LICENSE.rst | 28 + .../itsdangerous-2.1.2.dist-info/METADATA | 97 + .../itsdangerous-2.1.2.dist-info/RECORD | 23 + .../itsdangerous-2.1.2.dist-info/WHEEL | 5 + .../top_level.txt | 1 + .../site-packages/itsdangerous/__init__.py | 19 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 867 bytes .../__pycache__/_json.cpython-39.pyc | Bin 0 -> 923 bytes .../__pycache__/encoding.cpython-39.pyc | Bin 0 -> 1880 bytes .../__pycache__/exc.cpython-39.pyc | Bin 0 -> 3436 bytes .../__pycache__/serializer.cpython-39.pyc | Bin 0 -> 9744 bytes .../__pycache__/signer.cpython-39.pyc | Bin 0 -> 8435 bytes .../__pycache__/timed.cpython-39.pyc | Bin 0 -> 6481 bytes .../__pycache__/url_safe.cpython-39.pyc | Bin 0 -> 2716 bytes .../site-packages/itsdangerous/_json.py | 16 + .../site-packages/itsdangerous/encoding.py | 54 + .../site-packages/itsdangerous/exc.py | 107 + .../site-packages/itsdangerous/py.typed | 0 .../site-packages/itsdangerous/serializer.py | 295 + .../site-packages/itsdangerous/signer.py | 257 + .../site-packages/itsdangerous/timed.py | 234 + .../site-packages/itsdangerous/url_safe.py | 80 + .../site-packages/jinja2/__init__.py | 37 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1603 bytes .../__pycache__/_identifier.cpython-39.pyc | Bin 0 -> 2078 bytes .../__pycache__/async_utils.cpython-39.pyc | Bin 0 -> 2662 bytes .../jinja2/__pycache__/bccache.cpython-39.pyc | Bin 0 -> 13899 bytes .../__pycache__/compiler.cpython-39.pyc | Bin 0 -> 54179 bytes .../__pycache__/constants.cpython-39.pyc | Bin 0 -> 1539 bytes .../jinja2/__pycache__/debug.cpython-39.pyc | Bin 0 -> 3977 bytes .../__pycache__/defaults.cpython-39.pyc | Bin 0 -> 1339 bytes .../__pycache__/environment.cpython-39.pyc | Bin 0 -> 53107 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 5580 bytes .../jinja2/__pycache__/ext.cpython-39.pyc | Bin 0 -> 25535 bytes .../jinja2/__pycache__/filters.cpython-39.pyc | Bin 0 -> 50402 bytes .../__pycache__/idtracking.cpython-39.pyc | Bin 0 -> 11089 bytes .../jinja2/__pycache__/lexer.cpython-39.pyc | Bin 0 -> 20265 bytes .../jinja2/__pycache__/loaders.cpython-39.pyc | Bin 0 -> 20434 bytes .../jinja2/__pycache__/meta.cpython-39.pyc | Bin 0 -> 3797 bytes .../__pycache__/nativetypes.cpython-39.pyc | Bin 0 -> 4961 bytes .../jinja2/__pycache__/nodes.cpython-39.pyc | Bin 0 -> 40874 bytes .../__pycache__/optimizer.cpython-39.pyc | Bin 0 -> 1928 bytes .../jinja2/__pycache__/parser.cpython-39.pyc | Bin 0 -> 27576 bytes .../jinja2/__pycache__/runtime.cpython-39.pyc | Bin 0 -> 32166 bytes .../jinja2/__pycache__/sandbox.cpython-39.pyc | Bin 0 -> 11919 bytes .../jinja2/__pycache__/tests.cpython-39.pyc | Bin 0 -> 6571 bytes .../jinja2/__pycache__/utils.cpython-39.pyc | Bin 0 -> 24539 bytes .../jinja2/__pycache__/visitor.cpython-39.pyc | Bin 0 -> 3922 bytes .../site-packages/jinja2/_identifier.py | 6 + .../site-packages/jinja2/async_utils.py | 84 + .../python3.9/site-packages/jinja2/bccache.py | 406 + .../site-packages/jinja2/compiler.py | 1957 ++++ .../site-packages/jinja2/constants.py | 20 + .../python3.9/site-packages/jinja2/debug.py | 191 + .../site-packages/jinja2/defaults.py | 48 + .../site-packages/jinja2/environment.py | 1667 ++++ .../site-packages/jinja2/exceptions.py | 166 + .../lib/python3.9/site-packages/jinja2/ext.py | 859 ++ .../python3.9/site-packages/jinja2/filters.py | 1840 ++++ .../site-packages/jinja2/idtracking.py | 318 + .../python3.9/site-packages/jinja2/lexer.py | 866 ++ .../python3.9/site-packages/jinja2/loaders.py | 661 ++ .../python3.9/site-packages/jinja2/meta.py | 111 + .../site-packages/jinja2/nativetypes.py | 130 + .../python3.9/site-packages/jinja2/nodes.py | 1204 +++ .../site-packages/jinja2/optimizer.py | 47 + .../python3.9/site-packages/jinja2/parser.py | 1032 ++ .../python3.9/site-packages/jinja2/py.typed | 0 .../python3.9/site-packages/jinja2/runtime.py | 1053 ++ .../python3.9/site-packages/jinja2/sandbox.py | 428 + .../python3.9/site-packages/jinja2/tests.py | 255 + .../python3.9/site-packages/jinja2/utils.py | 755 ++ .../python3.9/site-packages/jinja2/visitor.py | 92 + .../site-packages/markupsafe/__init__.py | 295 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 10767 bytes .../__pycache__/_native.cpython-39.pyc | Bin 0 -> 2009 bytes .../site-packages/markupsafe/_native.py | 63 + .../site-packages/markupsafe/_speedups.c | 320 + .../_speedups.cpython-39-x86_64-linux-gnu.so | Bin 0 -> 44008 bytes .../site-packages/markupsafe/_speedups.pyi | 9 + .../site-packages/markupsafe/py.typed | 0 .../pip-22.1.dist-info/INSTALLER | 1 + .../pip-22.1.dist-info/LICENSE.txt | 20 + .../site-packages/pip-22.1.dist-info/METADATA | 92 + .../site-packages/pip-22.1.dist-info/RECORD | 1060 ++ .../pip-22.1.dist-info/REQUESTED | 0 .../site-packages/pip-22.1.dist-info/WHEEL | 5 + .../pip-22.1.dist-info/entry_points.txt | 4 + .../pip-22.1.dist-info/top_level.txt | 1 + .../python3.9/site-packages/pip/__init__.py | 13 + .../python3.9/site-packages/pip/__main__.py | 31 + .../pip/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 626 bytes .../pip/__pycache__/__main__.cpython-39.pyc | Bin 0 -> 584 bytes .../site-packages/pip/_internal/__init__.py | 19 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 749 bytes .../__pycache__/build_env.cpython-39.pyc | Bin 0 -> 9629 bytes .../__pycache__/cache.cpython-39.pyc | Bin 0 -> 8306 bytes .../__pycache__/configuration.cpython-39.pyc | Bin 0 -> 11241 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 23351 bytes .../_internal/__pycache__/main.cpython-39.pyc | Bin 0 -> 614 bytes .../__pycache__/pyproject.cpython-39.pyc | Bin 0 -> 3624 bytes .../self_outdated_check.cpython-39.pyc | Bin 0 -> 6623 bytes .../__pycache__/wheel_builder.cpython-39.pyc | Bin 0 -> 9158 bytes .../site-packages/pip/_internal/build_env.py | 302 + .../site-packages/pip/_internal/cache.py | 264 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 269 bytes .../__pycache__/autocompletion.cpython-39.pyc | Bin 0 -> 5252 bytes .../__pycache__/base_command.cpython-39.pyc | Bin 0 -> 6365 bytes .../cli/__pycache__/cmdoptions.cpython-39.pyc | Bin 0 -> 23666 bytes .../command_context.cpython-39.pyc | Bin 0 -> 1290 bytes .../cli/__pycache__/main.cpython-39.pyc | Bin 0 -> 1359 bytes .../__pycache__/main_parser.cpython-39.pyc | Bin 0 -> 2156 bytes .../cli/__pycache__/parser.cpython-39.pyc | Bin 0 -> 9949 bytes .../__pycache__/progress_bars.cpython-39.pyc | Bin 0 -> 1883 bytes .../__pycache__/req_command.cpython-39.pyc | Bin 0 -> 13122 bytes .../cli/__pycache__/spinners.cpython-39.pyc | Bin 0 -> 4927 bytes .../__pycache__/status_codes.cpython-39.pyc | Bin 0 -> 348 bytes .../pip/_internal/cli/autocompletion.py | 171 + .../pip/_internal/cli/base_command.py | 223 + .../pip/_internal/cli/cmdoptions.py | 1055 ++ .../pip/_internal/cli/command_context.py | 27 + .../site-packages/pip/_internal/cli/main.py | 70 + .../pip/_internal/cli/main_parser.py | 87 + .../site-packages/pip/_internal/cli/parser.py | 294 + .../pip/_internal/cli/progress_bars.py | 68 + .../pip/_internal/cli/req_command.py | 487 + .../pip/_internal/cli/spinners.py | 159 + .../pip/_internal/cli/status_codes.py | 6 + .../pip/_internal/commands/__init__.py | 127 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 3046 bytes .../commands/__pycache__/cache.cpython-39.pyc | Bin 0 -> 6173 bytes .../commands/__pycache__/check.cpython-39.pyc | Bin 0 -> 1562 bytes .../__pycache__/completion.cpython-39.pyc | Bin 0 -> 4159 bytes .../__pycache__/configuration.cpython-39.pyc | Bin 0 -> 8833 bytes .../commands/__pycache__/debug.cpython-39.pyc | Bin 0 -> 6667 bytes .../__pycache__/download.cpython-39.pyc | Bin 0 -> 3990 bytes .../__pycache__/freeze.cpython-39.pyc | Bin 0 -> 2632 bytes .../commands/__pycache__/hash.cpython-39.pyc | Bin 0 -> 2128 bytes .../commands/__pycache__/help.cpython-39.pyc | Bin 0 -> 1300 bytes .../commands/__pycache__/index.cpython-39.pyc | Bin 0 -> 4590 bytes .../__pycache__/install.cpython-39.pyc | Bin 0 -> 17798 bytes .../commands/__pycache__/list.cpython-39.pyc | Bin 0 -> 10155 bytes .../__pycache__/search.cpython-39.pyc | Bin 0 -> 5318 bytes .../commands/__pycache__/show.cpython-39.pyc | Bin 0 -> 6266 bytes .../__pycache__/uninstall.cpython-39.pyc | Bin 0 -> 3212 bytes .../commands/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 4857 bytes .../pip/_internal/commands/cache.py | 223 + .../pip/_internal/commands/check.py | 53 + .../pip/_internal/commands/completion.py | 126 + .../pip/_internal/commands/configuration.py | 276 + .../pip/_internal/commands/debug.py | 203 + .../pip/_internal/commands/download.py | 140 + .../pip/_internal/commands/freeze.py | 97 + .../pip/_internal/commands/hash.py | 59 + .../pip/_internal/commands/help.py | 41 + .../pip/_internal/commands/index.py | 139 + .../pip/_internal/commands/install.py | 772 ++ .../pip/_internal/commands/list.py | 361 + .../pip/_internal/commands/search.py | 174 + .../pip/_internal/commands/show.py | 183 + .../pip/_internal/commands/uninstall.py | 106 + .../pip/_internal/commands/wheel.py | 177 + .../pip/_internal/configuration.py | 374 + .../pip/_internal/distributions/__init__.py | 21 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 792 bytes .../__pycache__/base.cpython-39.pyc | Bin 0 -> 1867 bytes .../__pycache__/installed.cpython-39.pyc | Bin 0 -> 1225 bytes .../__pycache__/sdist.cpython-39.pyc | Bin 0 -> 5049 bytes .../__pycache__/wheel.cpython-39.pyc | Bin 0 -> 1592 bytes .../pip/_internal/distributions/base.py | 36 + .../pip/_internal/distributions/installed.py | 20 + .../pip/_internal/distributions/sdist.py | 145 + .../pip/_internal/distributions/wheel.py | 31 + .../site-packages/pip/_internal/exceptions.py | 658 ++ .../pip/_internal/index/__init__.py | 2 + .../index/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 223 bytes .../__pycache__/collector.cpython-39.pyc | Bin 0 -> 18028 bytes .../__pycache__/package_finder.cpython-39.pyc | Bin 0 -> 29109 bytes .../index/__pycache__/sources.cpython-39.pyc | Bin 0 -> 7188 bytes .../pip/_internal/index/collector.py | 610 ++ .../pip/_internal/index/package_finder.py | 1030 ++ .../pip/_internal/index/sources.py | 224 + .../pip/_internal/locations/__init__.py | 520 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 12518 bytes .../__pycache__/_distutils.cpython-39.pyc | Bin 0 -> 4662 bytes .../__pycache__/_sysconfig.cpython-39.pyc | Bin 0 -> 6253 bytes .../locations/__pycache__/base.cpython-39.pyc | Bin 0 -> 1531 bytes .../pip/_internal/locations/_distutils.py | 169 + .../pip/_internal/locations/_sysconfig.py | 219 + .../pip/_internal/locations/base.py | 52 + .../site-packages/pip/_internal/main.py | 12 + .../pip/_internal/metadata/__init__.py | 105 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 4028 bytes .../metadata/__pycache__/base.cpython-39.pyc | Bin 0 -> 22157 bytes .../__pycache__/pkg_resources.cpython-39.pyc | Bin 0 -> 9858 bytes .../pip/_internal/metadata/base.py | 561 ++ .../_internal/metadata/importlib/__init__.py | 4 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 314 bytes .../__pycache__/_compat.cpython-39.pyc | Bin 0 -> 2039 bytes .../__pycache__/_dists.cpython-39.pyc | Bin 0 -> 10933 bytes .../__pycache__/_envs.cpython-39.pyc | Bin 0 -> 6982 bytes .../_internal/metadata/importlib/_compat.py | 41 + .../_internal/metadata/importlib/_dists.py | 274 + .../pip/_internal/metadata/importlib/_envs.py | 163 + .../pip/_internal/metadata/pkg_resources.py | 254 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 257 bytes .../__pycache__/candidate.cpython-39.pyc | Bin 0 -> 1440 bytes .../__pycache__/direct_url.cpython-39.pyc | Bin 0 -> 7063 bytes .../__pycache__/format_control.cpython-39.pyc | Bin 0 -> 2711 bytes .../models/__pycache__/index.cpython-39.pyc | Bin 0 -> 1227 bytes .../models/__pycache__/link.cpython-39.pyc | Bin 0 -> 10251 bytes .../models/__pycache__/scheme.cpython-39.pyc | Bin 0 -> 1003 bytes .../__pycache__/search_scope.cpython-39.pyc | Bin 0 -> 3472 bytes .../selection_prefs.cpython-39.pyc | Bin 0 -> 1659 bytes .../__pycache__/target_python.cpython-39.pyc | Bin 0 -> 3405 bytes .../models/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 4329 bytes .../pip/_internal/models/candidate.py | 34 + .../pip/_internal/models/direct_url.py | 212 + .../pip/_internal/models/format_control.py | 80 + .../pip/_internal/models/index.py | 28 + .../pip/_internal/models/link.py | 288 + .../pip/_internal/models/scheme.py | 31 + .../pip/_internal/models/search_scope.py | 129 + .../pip/_internal/models/selection_prefs.py | 51 + .../pip/_internal/models/target_python.py | 110 + .../pip/_internal/models/wheel.py | 89 + .../pip/_internal/network/__init__.py | 2 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 245 bytes .../network/__pycache__/auth.cpython-39.pyc | Bin 0 -> 7484 bytes .../network/__pycache__/cache.cpython-39.pyc | Bin 0 -> 2923 bytes .../__pycache__/download.cpython-39.pyc | Bin 0 -> 5509 bytes .../__pycache__/lazy_wheel.cpython-39.pyc | Bin 0 -> 8389 bytes .../__pycache__/session.cpython-39.pyc | Bin 0 -> 10780 bytes .../network/__pycache__/utils.cpython-39.pyc | Bin 0 -> 1430 bytes .../network/__pycache__/xmlrpc.cpython-39.pyc | Bin 0 -> 2044 bytes .../pip/_internal/network/auth.py | 324 + .../pip/_internal/network/cache.py | 69 + .../pip/_internal/network/download.py | 185 + .../pip/_internal/network/lazy_wheel.py | 210 + .../pip/_internal/network/session.py | 456 + .../pip/_internal/network/utils.py | 96 + .../pip/_internal/network/xmlrpc.py | 60 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 193 bytes .../__pycache__/check.cpython-39.pyc | Bin 0 -> 3997 bytes .../__pycache__/freeze.cpython-39.pyc | Bin 0 -> 6146 bytes .../__pycache__/prepare.cpython-39.pyc | Bin 0 -> 13352 bytes .../_internal/operations/build/__init__.py | 0 .../build/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 199 bytes .../__pycache__/build_tracker.cpython-39.pyc | Bin 0 -> 4229 bytes .../build/__pycache__/metadata.cpython-39.pyc | Bin 0 -> 1410 bytes .../metadata_editable.cpython-39.pyc | Bin 0 -> 1444 bytes .../metadata_legacy.cpython-39.pyc | Bin 0 -> 2320 bytes .../build/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 1194 bytes .../__pycache__/wheel_editable.cpython-39.pyc | Bin 0 -> 1410 bytes .../__pycache__/wheel_legacy.cpython-39.pyc | Bin 0 -> 2717 bytes .../operations/build/build_tracker.py | 124 + .../_internal/operations/build/metadata.py | 39 + .../operations/build/metadata_editable.py | 41 + .../operations/build/metadata_legacy.py | 74 + .../pip/_internal/operations/build/wheel.py | 37 + .../operations/build/wheel_editable.py | 46 + .../operations/build/wheel_legacy.py | 102 + .../pip/_internal/operations/check.py | 149 + .../pip/_internal/operations/freeze.py | 254 + .../_internal/operations/install/__init__.py | 2 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 257 bytes .../editable_legacy.cpython-39.pyc | Bin 0 -> 1478 bytes .../install/__pycache__/legacy.cpython-39.pyc | Bin 0 -> 3277 bytes .../install/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 20996 bytes .../operations/install/editable_legacy.py | 47 + .../_internal/operations/install/legacy.py | 120 + .../pip/_internal/operations/install/wheel.py | 739 ++ .../pip/_internal/operations/prepare.py | 576 ++ .../site-packages/pip/_internal/pyproject.py | 175 + .../pip/_internal/req/__init__.py | 94 + .../req/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2559 bytes .../__pycache__/constructors.cpython-39.pyc | Bin 0 -> 12302 bytes .../req/__pycache__/req_file.cpython-39.pyc | Bin 0 -> 13403 bytes .../__pycache__/req_install.cpython-39.pyc | Bin 0 -> 22208 bytes .../req/__pycache__/req_set.cpython-39.pyc | Bin 0 -> 5890 bytes .../__pycache__/req_uninstall.cpython-39.pyc | Bin 0 -> 18931 bytes .../pip/_internal/req/constructors.py | 501 + .../pip/_internal/req/req_file.py | 540 ++ .../pip/_internal/req/req_install.py | 862 ++ .../pip/_internal/req/req_set.py | 189 + .../pip/_internal/req/req_uninstall.py | 640 ++ .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 193 bytes .../__pycache__/base.cpython-39.pyc | Bin 0 -> 1050 bytes .../pip/_internal/resolution/base.py | 20 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 200 bytes .../__pycache__/resolver.cpython-39.pyc | Bin 0 -> 12188 bytes .../_internal/resolution/legacy/resolver.py | 467 + .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 204 bytes .../__pycache__/base.cpython-39.pyc | Bin 0 -> 6601 bytes .../__pycache__/candidates.cpython-39.pyc | Bin 0 -> 18579 bytes .../__pycache__/factory.cpython-39.pyc | Bin 0 -> 19281 bytes .../found_candidates.cpython-39.pyc | Bin 0 -> 4835 bytes .../__pycache__/provider.cpython-39.pyc | Bin 0 -> 7630 bytes .../__pycache__/reporter.cpython-39.pyc | Bin 0 -> 3265 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 0 -> 7574 bytes .../__pycache__/resolver.cpython-39.pyc | Bin 0 -> 8173 bytes .../_internal/resolution/resolvelib/base.py | 141 + .../resolution/resolvelib/candidates.py | 550 ++ .../resolution/resolvelib/factory.py | 746 ++ .../resolution/resolvelib/found_candidates.py | 155 + .../resolution/resolvelib/provider.py | 248 + .../resolution/resolvelib/reporter.py | 68 + .../resolution/resolvelib/requirements.py | 166 + .../resolution/resolvelib/resolver.py | 298 + .../pip/_internal/self_outdated_check.py | 240 + .../pip/_internal/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 188 bytes .../utils/__pycache__/_log.cpython-39.pyc | Bin 0 -> 1513 bytes .../utils/__pycache__/appdirs.cpython-39.pyc | Bin 0 -> 1619 bytes .../utils/__pycache__/compat.cpython-39.pyc | Bin 0 -> 1507 bytes .../compatibility_tags.cpython-39.pyc | Bin 0 -> 4059 bytes .../utils/__pycache__/datetime.cpython-39.pyc | Bin 0 -> 507 bytes .../__pycache__/deprecation.cpython-39.pyc | Bin 0 -> 3245 bytes .../direct_url_helpers.cpython-39.pyc | Bin 0 -> 2078 bytes .../__pycache__/distutils_args.cpython-39.pyc | Bin 0 -> 1093 bytes .../utils/__pycache__/egg_link.cpython-39.pyc | Bin 0 -> 2134 bytes .../utils/__pycache__/encoding.cpython-39.pyc | Bin 0 -> 1297 bytes .../__pycache__/entrypoints.cpython-39.pyc | Bin 0 -> 2640 bytes .../__pycache__/filesystem.cpython-39.pyc | Bin 0 -> 4454 bytes .../__pycache__/filetypes.cpython-39.pyc | Bin 0 -> 938 bytes .../utils/__pycache__/glibc.cpython-39.pyc | Bin 0 -> 1669 bytes .../utils/__pycache__/hashes.cpython-39.pyc | Bin 0 -> 5183 bytes .../inject_securetransport.cpython-39.pyc | Bin 0 -> 977 bytes .../utils/__pycache__/logging.cpython-39.pyc | Bin 0 -> 9615 bytes .../utils/__pycache__/misc.cpython-39.pyc | Bin 0 -> 21758 bytes .../utils/__pycache__/models.cpython-39.pyc | Bin 0 -> 2056 bytes .../__pycache__/packaging.cpython-39.pyc | Bin 0 -> 2076 bytes .../setuptools_build.cpython-39.pyc | Bin 0 -> 4564 bytes .../__pycache__/subprocess.cpython-39.pyc | Bin 0 -> 5698 bytes .../utils/__pycache__/temp_dir.cpython-39.pyc | Bin 0 -> 7273 bytes .../__pycache__/unpacking.cpython-39.pyc | Bin 0 -> 6719 bytes .../utils/__pycache__/urls.cpython-39.pyc | Bin 0 -> 1592 bytes .../__pycache__/virtualenv.cpython-39.pyc | Bin 0 -> 3282 bytes .../utils/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 4472 bytes .../site-packages/pip/_internal/utils/_log.py | 38 + .../pip/_internal/utils/appdirs.py | 52 + .../pip/_internal/utils/compat.py | 63 + .../pip/_internal/utils/compatibility_tags.py | 165 + .../pip/_internal/utils/datetime.py | 11 + .../pip/_internal/utils/deprecation.py | 120 + .../pip/_internal/utils/direct_url_helpers.py | 87 + .../pip/_internal/utils/distutils_args.py | 42 + .../pip/_internal/utils/egg_link.py | 75 + .../pip/_internal/utils/encoding.py | 36 + .../pip/_internal/utils/entrypoints.py | 79 + .../pip/_internal/utils/filesystem.py | 153 + .../pip/_internal/utils/filetypes.py | 27 + .../pip/_internal/utils/glibc.py | 88 + .../pip/_internal/utils/hashes.py | 144 + .../_internal/utils/inject_securetransport.py | 35 + .../pip/_internal/utils/logging.py | 346 + .../site-packages/pip/_internal/utils/misc.py | 723 ++ .../pip/_internal/utils/models.py | 39 + .../pip/_internal/utils/packaging.py | 57 + .../pip/_internal/utils/setuptools_build.py | 195 + .../pip/_internal/utils/subprocess.py | 260 + .../pip/_internal/utils/temp_dir.py | 246 + .../pip/_internal/utils/unpacking.py | 257 + .../site-packages/pip/_internal/utils/urls.py | 62 + .../pip/_internal/utils/virtualenv.py | 104 + .../pip/_internal/utils/wheel.py | 136 + .../pip/_internal/vcs/__init__.py | 15 + .../vcs/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 511 bytes .../vcs/__pycache__/bazaar.cpython-39.pyc | Bin 0 -> 3350 bytes .../vcs/__pycache__/git.cpython-39.pyc | Bin 0 -> 12558 bytes .../vcs/__pycache__/mercurial.cpython-39.pyc | Bin 0 -> 5055 bytes .../vcs/__pycache__/subversion.cpython-39.pyc | Bin 0 -> 8472 bytes .../__pycache__/versioncontrol.cpython-39.pyc | Bin 0 -> 21178 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 101 + .../site-packages/pip/_internal/vcs/git.py | 526 + .../pip/_internal/vcs/mercurial.py | 163 + .../pip/_internal/vcs/subversion.py | 324 + .../pip/_internal/vcs/versioncontrol.py | 705 ++ .../pip/_internal/wheel_builder.py | 377 + .../site-packages/pip/_vendor/__init__.py | 111 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2901 bytes .../_vendor/__pycache__/six.cpython-39.pyc | Bin 0 -> 27505 bytes .../typing_extensions.cpython-39.pyc | Bin 0 -> 58179 bytes .../pip/_vendor/cachecontrol/__init__.py | 18 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 639 bytes .../__pycache__/_cmd.cpython-39.pyc | Bin 0 -> 1567 bytes .../__pycache__/adapter.cpython-39.pyc | Bin 0 -> 3131 bytes .../__pycache__/cache.cpython-39.pyc | Bin 0 -> 2703 bytes .../__pycache__/compat.cpython-39.pyc | Bin 0 -> 743 bytes .../__pycache__/controller.cpython-39.pyc | Bin 0 -> 8585 bytes .../__pycache__/filewrapper.cpython-39.pyc | Bin 0 -> 2783 bytes .../__pycache__/heuristics.cpython-39.pyc | Bin 0 -> 4700 bytes .../__pycache__/serialize.cpython-39.pyc | Bin 0 -> 4343 bytes .../__pycache__/wrapper.cpython-39.pyc | Bin 0 -> 670 bytes .../pip/_vendor/cachecontrol/_cmd.py | 61 + .../pip/_vendor/cachecontrol/adapter.py | 137 + .../pip/_vendor/cachecontrol/cache.py | 65 + .../_vendor/cachecontrol/caches/__init__.py | 9 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 358 bytes .../__pycache__/file_cache.cpython-39.pyc | Bin 0 -> 4914 bytes .../__pycache__/redis_cache.cpython-39.pyc | Bin 0 -> 1606 bytes .../_vendor/cachecontrol/caches/file_cache.py | 188 + .../cachecontrol/caches/redis_cache.py | 39 + .../pip/_vendor/cachecontrol/compat.py | 32 + .../pip/_vendor/cachecontrol/controller.py | 439 + .../pip/_vendor/cachecontrol/filewrapper.py | 111 + .../pip/_vendor/cachecontrol/heuristics.py | 139 + .../pip/_vendor/cachecontrol/serialize.py | 190 + .../pip/_vendor/cachecontrol/wrapper.py | 33 + .../pip/_vendor/certifi/__init__.py | 3 + .../pip/_vendor/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 272 bytes .../__pycache__/__main__.cpython-39.pyc | Bin 0 -> 449 bytes .../certifi/__pycache__/core.cpython-39.pyc | Bin 0 -> 1540 bytes .../pip/_vendor/certifi/cacert.pem | 4362 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 76 + .../pip/_vendor/chardet/__init__.py | 83 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1896 bytes .../__pycache__/big5freq.cpython-39.pyc | Bin 0 -> 27175 bytes .../__pycache__/big5prober.cpython-39.pyc | Bin 0 -> 1130 bytes .../chardistribution.cpython-39.pyc | Bin 0 -> 6216 bytes .../charsetgroupprober.cpython-39.pyc | Bin 0 -> 2257 bytes .../__pycache__/charsetprober.cpython-39.pyc | Bin 0 -> 3479 bytes .../codingstatemachine.cpython-39.pyc | Bin 0 -> 2906 bytes .../chardet/__pycache__/compat.cpython-39.pyc | Bin 0 -> 395 bytes .../__pycache__/cp949prober.cpython-39.pyc | Bin 0 -> 1137 bytes .../chardet/__pycache__/enums.cpython-39.pyc | Bin 0 -> 2644 bytes .../__pycache__/escprober.cpython-39.pyc | Bin 0 -> 2629 bytes .../chardet/__pycache__/escsm.cpython-39.pyc | Bin 0 -> 7078 bytes .../__pycache__/eucjpprober.cpython-39.pyc | Bin 0 -> 2443 bytes .../__pycache__/euckrfreq.cpython-39.pyc | Bin 0 -> 12059 bytes .../__pycache__/euckrprober.cpython-39.pyc | Bin 0 -> 1138 bytes .../__pycache__/euctwfreq.cpython-39.pyc | Bin 0 -> 27179 bytes .../__pycache__/euctwprober.cpython-39.pyc | Bin 0 -> 1138 bytes .../__pycache__/gb2312freq.cpython-39.pyc | Bin 0 -> 19103 bytes .../__pycache__/gb2312prober.cpython-39.pyc | Bin 0 -> 1146 bytes .../__pycache__/hebrewprober.cpython-39.pyc | Bin 0 -> 3015 bytes .../__pycache__/jisfreq.cpython-39.pyc | Bin 0 -> 22131 bytes .../chardet/__pycache__/jpcntx.cpython-39.pyc | Bin 0 -> 37604 bytes .../langbulgarianmodel.cpython-39.pyc | Bin 0 -> 21806 bytes .../__pycache__/langgreekmodel.cpython-39.pyc | Bin 0 -> 20482 bytes .../langhebrewmodel.cpython-39.pyc | Bin 0 -> 20550 bytes .../langhungarianmodel.cpython-39.pyc | Bin 0 -> 21751 bytes .../langrussianmodel.cpython-39.pyc | Bin 0 -> 26354 bytes .../__pycache__/langthaimodel.cpython-39.pyc | Bin 0 -> 20726 bytes .../langturkishmodel.cpython-39.pyc | Bin 0 -> 20566 bytes .../__pycache__/latin1prober.cpython-39.pyc | Bin 0 -> 2951 bytes .../mbcharsetprober.cpython-39.pyc | Bin 0 -> 2258 bytes .../mbcsgroupprober.cpython-39.pyc | Bin 0 -> 1127 bytes .../chardet/__pycache__/mbcssm.cpython-39.pyc | Bin 0 -> 15714 bytes .../sbcharsetprober.cpython-39.pyc | Bin 0 -> 3111 bytes .../sbcsgroupprober.cpython-39.pyc | Bin 0 -> 1696 bytes .../__pycache__/sjisprober.cpython-39.pyc | Bin 0 -> 2479 bytes .../universaldetector.cpython-39.pyc | Bin 0 -> 5827 bytes .../__pycache__/utf8prober.cpython-39.pyc | Bin 0 -> 1988 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 435 bytes .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 233 + .../pip/_vendor/chardet/charsetgroupprober.py | 107 + .../pip/_vendor/chardet/charsetprober.py | 145 + .../pip/_vendor/chardet/cli/__init__.py | 1 + .../cli/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 192 bytes .../cli/__pycache__/chardetect.cpython-39.pyc | Bin 0 -> 2686 bytes .../pip/_vendor/chardet/cli/chardetect.py | 84 + .../pip/_vendor/chardet/codingstatemachine.py | 88 + .../pip/_vendor/chardet/compat.py | 36 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 76 + .../pip/_vendor/chardet/escprober.py | 101 + .../pip/_vendor/chardet/escsm.py | 246 + .../pip/_vendor/chardet/eucjpprober.py | 92 + .../pip/_vendor/chardet/euckrfreq.py | 195 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 387 + .../pip/_vendor/chardet/euctwprober.py | 46 + .../pip/_vendor/chardet/gb2312freq.py | 283 + .../pip/_vendor/chardet/gb2312prober.py | 46 + .../pip/_vendor/chardet/hebrewprober.py | 292 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/jpcntx.py | 233 + .../pip/_vendor/chardet/langbulgarianmodel.py | 4650 +++++++++ .../pip/_vendor/chardet/langgreekmodel.py | 4398 +++++++++ .../pip/_vendor/chardet/langhebrewmodel.py | 4383 +++++++++ .../pip/_vendor/chardet/langhungarianmodel.py | 4650 +++++++++ .../pip/_vendor/chardet/langrussianmodel.py | 5718 +++++++++++ .../pip/_vendor/chardet/langthaimodel.py | 4383 +++++++++ .../pip/_vendor/chardet/langturkishmodel.py | 4383 +++++++++ .../pip/_vendor/chardet/latin1prober.py | 145 + .../pip/_vendor/chardet/mbcharsetprober.py | 91 + .../pip/_vendor/chardet/mbcsgroupprober.py | 54 + .../pip/_vendor/chardet/mbcssm.py | 572 ++ .../pip/_vendor/chardet/metadata/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 197 bytes .../__pycache__/languages.cpython-39.pyc | Bin 0 -> 7928 bytes .../pip/_vendor/chardet/metadata/languages.py | 310 + .../pip/_vendor/chardet/sbcharsetprober.py | 145 + .../pip/_vendor/chardet/sbcsgroupprober.py | 83 + .../pip/_vendor/chardet/sjisprober.py | 92 + .../pip/_vendor/chardet/universaldetector.py | 286 + .../pip/_vendor/chardet/utf8prober.py | 82 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 6 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 440 bytes .../colorama/__pycache__/ansi.cpython-39.pyc | Bin 0 -> 3225 bytes .../__pycache__/ansitowin32.cpython-39.pyc | Bin 0 -> 7691 bytes .../__pycache__/initialise.cpython-39.pyc | Bin 0 -> 1707 bytes .../colorama/__pycache__/win32.cpython-39.pyc | Bin 0 -> 3939 bytes .../__pycache__/winterm.cpython-39.pyc | Bin 0 -> 4661 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 258 + .../pip/_vendor/colorama/initialise.py | 80 + .../pip/_vendor/colorama/win32.py | 152 + .../pip/_vendor/colorama/winterm.py | 169 + .../pip/_vendor/distlib/__init__.py | 23 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1053 bytes .../distlib/__pycache__/compat.cpython-39.pyc | Bin 0 -> 31818 bytes .../__pycache__/database.cpython-39.pyc | Bin 0 -> 42477 bytes .../distlib/__pycache__/index.cpython-39.pyc | Bin 0 -> 17286 bytes .../__pycache__/locators.cpython-39.pyc | Bin 0 -> 38250 bytes .../__pycache__/manifest.cpython-39.pyc | Bin 0 -> 10189 bytes .../__pycache__/markers.cpython-39.pyc | Bin 0 -> 4971 bytes .../__pycache__/metadata.cpython-39.pyc | Bin 0 -> 26584 bytes .../__pycache__/resources.cpython-39.pyc | Bin 0 -> 11007 bytes .../__pycache__/scripts.cpython-39.pyc | Bin 0 -> 11239 bytes .../distlib/__pycache__/util.cpython-39.pyc | Bin 0 -> 52602 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 20352 bytes .../distlib/__pycache__/wheel.cpython-39.pyc | Bin 0 -> 27165 bytes .../pip/_vendor/distlib/_backport/__init__.py | 6 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 480 bytes .../_backport/__pycache__/misc.cpython-39.pyc | Bin 0 -> 1100 bytes .../__pycache__/shutil.cpython-39.pyc | Bin 0 -> 21674 bytes .../__pycache__/sysconfig.cpython-39.pyc | Bin 0 -> 15964 bytes .../__pycache__/tarfile.cpython-39.pyc | Bin 0 -> 62728 bytes .../pip/_vendor/distlib/_backport/misc.py | 41 + .../pip/_vendor/distlib/_backport/shutil.py | 764 ++ .../_vendor/distlib/_backport/sysconfig.cfg | 84 + .../_vendor/distlib/_backport/sysconfig.py | 786 ++ .../pip/_vendor/distlib/_backport/tarfile.py | 2607 +++++ .../pip/_vendor/distlib/compat.py | 1122 +++ .../pip/_vendor/distlib/database.py | 1339 +++ .../pip/_vendor/distlib/index.py | 509 + .../pip/_vendor/distlib/locators.py | 1300 +++ .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 147 + .../pip/_vendor/distlib/metadata.py | 1058 ++ .../pip/_vendor/distlib/resources.py | 358 + .../pip/_vendor/distlib/scripts.py | 429 + .../site-packages/pip/_vendor/distlib/t32.exe | Bin 0 -> 96768 bytes .../pip/_vendor/distlib/t64-arm.exe | Bin 0 -> 180736 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 0 -> 105984 bytes .../site-packages/pip/_vendor/distlib/util.py | 1969 ++++ .../pip/_vendor/distlib/version.py | 739 ++ .../site-packages/pip/_vendor/distlib/w32.exe | Bin 0 -> 90112 bytes .../pip/_vendor/distlib/w64-arm.exe | Bin 0 -> 166400 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 0 -> 99840 bytes .../pip/_vendor/distlib/wheel.py | 1053 ++ .../pip/_vendor/distro/__init__.py | 54 + .../pip/_vendor/distro/__main__.py | 4 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 912 bytes .../__pycache__/__main__.cpython-39.pyc | Bin 0 -> 260 bytes .../distro/__pycache__/distro.cpython-39.pyc | Bin 0 -> 41540 bytes .../pip/_vendor/distro/distro.py | 1374 +++ .../pip/_vendor/html5lib/__init__.py | 35 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1299 bytes .../__pycache__/_ihatexml.cpython-39.pyc | Bin 0 -> 13768 bytes .../__pycache__/_inputstream.cpython-39.pyc | Bin 0 -> 21627 bytes .../__pycache__/_tokenizer.cpython-39.pyc | Bin 0 -> 39722 bytes .../__pycache__/_utils.cpython-39.pyc | Bin 0 -> 4799 bytes .../__pycache__/constants.cpython-39.pyc | Bin 0 -> 66337 bytes .../__pycache__/html5parser.cpython-39.pyc | Bin 0 -> 91008 bytes .../__pycache__/serializer.cpython-39.pyc | Bin 0 -> 10810 bytes .../pip/_vendor/html5lib/_ihatexml.py | 289 + .../pip/_vendor/html5lib/_inputstream.py | 918 ++ .../pip/_vendor/html5lib/_tokenizer.py | 1735 ++++ .../pip/_vendor/html5lib/_trie/__init__.py | 5 + .../_trie/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 349 bytes .../_trie/__pycache__/_base.cpython-39.pyc | Bin 0 -> 1593 bytes .../_trie/__pycache__/py.cpython-39.pyc | Bin 0 -> 2254 bytes .../pip/_vendor/html5lib/_trie/_base.py | 40 + .../pip/_vendor/html5lib/_trie/py.py | 67 + .../pip/_vendor/html5lib/_utils.py | 159 + .../pip/_vendor/html5lib/constants.py | 2946 ++++++ .../pip/_vendor/html5lib/filters/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 197 bytes .../alphabeticalattributes.cpython-39.pyc | Bin 0 -> 1319 bytes .../filters/__pycache__/base.cpython-39.pyc | Bin 0 -> 867 bytes .../inject_meta_charset.cpython-39.pyc | Bin 0 -> 1873 bytes .../filters/__pycache__/lint.cpython-39.pyc | Bin 0 -> 2615 bytes .../__pycache__/optionaltags.cpython-39.pyc | Bin 0 -> 2760 bytes .../__pycache__/sanitizer.cpython-39.pyc | Bin 0 -> 16883 bytes .../__pycache__/whitespace.cpython-39.pyc | Bin 0 -> 1365 bytes .../filters/alphabeticalattributes.py | 29 + .../pip/_vendor/html5lib/filters/base.py | 12 + .../html5lib/filters/inject_meta_charset.py | 73 + .../pip/_vendor/html5lib/filters/lint.py | 93 + .../_vendor/html5lib/filters/optionaltags.py | 207 + .../pip/_vendor/html5lib/filters/sanitizer.py | 916 ++ .../_vendor/html5lib/filters/whitespace.py | 38 + .../pip/_vendor/html5lib/html5parser.py | 2795 ++++++ .../pip/_vendor/html5lib/serializer.py | 409 + .../_vendor/html5lib/treeadapters/__init__.py | 30 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 934 bytes .../__pycache__/genshi.cpython-39.pyc | Bin 0 -> 1542 bytes .../__pycache__/sax.cpython-39.pyc | Bin 0 -> 1461 bytes .../_vendor/html5lib/treeadapters/genshi.py | 54 + .../pip/_vendor/html5lib/treeadapters/sax.py | 50 + .../_vendor/html5lib/treebuilders/__init__.py | 88 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 3329 bytes .../__pycache__/base.cpython-39.pyc | Bin 0 -> 11313 bytes .../__pycache__/dom.cpython-39.pyc | Bin 0 -> 9450 bytes .../__pycache__/etree.cpython-39.pyc | Bin 0 -> 11818 bytes .../__pycache__/etree_lxml.cpython-39.pyc | Bin 0 -> 13001 bytes .../pip/_vendor/html5lib/treebuilders/base.py | 417 + .../pip/_vendor/html5lib/treebuilders/dom.py | 239 + .../_vendor/html5lib/treebuilders/etree.py | 343 + .../html5lib/treebuilders/etree_lxml.py | 392 + .../_vendor/html5lib/treewalkers/__init__.py | 154 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 3995 bytes .../__pycache__/base.cpython-39.pyc | Bin 0 -> 6994 bytes .../__pycache__/dom.cpython-39.pyc | Bin 0 -> 1729 bytes .../__pycache__/etree.cpython-39.pyc | Bin 0 -> 3491 bytes .../__pycache__/etree_lxml.cpython-39.pyc | Bin 0 -> 6628 bytes .../__pycache__/genshi.cpython-39.pyc | Bin 0 -> 1885 bytes .../pip/_vendor/html5lib/treewalkers/base.py | 252 + .../pip/_vendor/html5lib/treewalkers/dom.py | 43 + .../pip/_vendor/html5lib/treewalkers/etree.py | 131 + .../html5lib/treewalkers/etree_lxml.py | 215 + .../_vendor/html5lib/treewalkers/genshi.py | 69 + .../pip/_vendor/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 844 bytes .../idna/__pycache__/codec.cpython-39.pyc | Bin 0 -> 3081 bytes .../idna/__pycache__/compat.cpython-39.pyc | Bin 0 -> 763 bytes .../idna/__pycache__/core.cpython-39.pyc | Bin 0 -> 9759 bytes .../idna/__pycache__/idnadata.cpython-39.pyc | Bin 0 -> 23040 bytes .../idna/__pycache__/intranges.cpython-39.pyc | Bin 0 -> 1994 bytes .../__pycache__/package_data.cpython-39.pyc | Bin 0 -> 208 bytes .../idna/__pycache__/uts46data.cpython-39.pyc | Bin 0 -> 151741 bytes .../site-packages/pip/_vendor/idna/codec.py | 112 + .../site-packages/pip/_vendor/idna/compat.py | 13 + .../site-packages/pip/_vendor/idna/core.py | 397 + .../pip/_vendor/idna/idnadata.py | 2137 +++++ .../pip/_vendor/idna/intranges.py | 54 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 8512 +++++++++++++++++ .../pip/_vendor/msgpack/__init__.py | 54 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1411 bytes .../__pycache__/_version.cpython-39.pyc | Bin 0 -> 215 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 1849 bytes .../msgpack/__pycache__/ext.cpython-39.pyc | Bin 0 -> 6277 bytes .../__pycache__/fallback.cpython-39.pyc | Bin 0 -> 25616 bytes .../pip/_vendor/msgpack/_version.py | 1 + .../pip/_vendor/msgpack/exceptions.py | 48 + .../site-packages/pip/_vendor/msgpack/ext.py | 193 + .../pip/_vendor/msgpack/fallback.py | 1012 ++ .../pip/_vendor/packaging/__about__.py | 26 + .../pip/_vendor/packaging/__init__.py | 25 + .../__pycache__/__about__.cpython-39.pyc | Bin 0 -> 587 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 443 bytes .../__pycache__/_manylinux.cpython-39.pyc | Bin 0 -> 7291 bytes .../__pycache__/_musllinux.cpython-39.pyc | Bin 0 -> 4606 bytes .../__pycache__/_structures.cpython-39.pyc | Bin 0 -> 2800 bytes .../__pycache__/markers.cpython-39.pyc | Bin 0 -> 9450 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 0 -> 3971 bytes .../__pycache__/specifiers.cpython-39.pyc | Bin 0 -> 21518 bytes .../packaging/__pycache__/tags.cpython-39.pyc | Bin 0 -> 12249 bytes .../__pycache__/utils.cpython-39.pyc | Bin 0 -> 3608 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 13149 bytes .../pip/_vendor/packaging/_manylinux.py | 301 + .../pip/_vendor/packaging/_musllinux.py | 136 + .../pip/_vendor/packaging/_structures.py | 61 + .../pip/_vendor/packaging/markers.py | 304 + .../pip/_vendor/packaging/requirements.py | 146 + .../pip/_vendor/packaging/specifiers.py | 802 ++ .../pip/_vendor/packaging/tags.py | 487 + .../pip/_vendor/packaging/utils.py | 136 + .../pip/_vendor/packaging/version.py | 504 + .../pip/_vendor/pep517/__init__.py | 6 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 310 bytes .../pep517/__pycache__/build.cpython-39.pyc | Bin 0 -> 3558 bytes .../pep517/__pycache__/check.cpython-39.pyc | Bin 0 -> 5105 bytes .../__pycache__/colorlog.cpython-39.pyc | Bin 0 -> 2935 bytes .../pep517/__pycache__/compat.cpython-39.pyc | Bin 0 -> 1526 bytes .../__pycache__/dirtools.cpython-39.pyc | Bin 0 -> 1344 bytes .../__pycache__/envbuild.cpython-39.pyc | Bin 0 -> 4504 bytes .../pep517/__pycache__/meta.cpython-39.pyc | Bin 0 -> 2917 bytes .../__pycache__/wrappers.cpython-39.pyc | Bin 0 -> 12490 bytes .../site-packages/pip/_vendor/pep517/build.py | 127 + .../site-packages/pip/_vendor/pep517/check.py | 207 + .../pip/_vendor/pep517/colorlog.py | 115 + .../pip/_vendor/pep517/compat.py | 51 + .../pip/_vendor/pep517/dirtools.py | 44 + .../pip/_vendor/pep517/envbuild.py | 171 + .../pip/_vendor/pep517/in_process/__init__.py | 17 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 912 bytes .../__pycache__/_in_process.cpython-39.pyc | Bin 0 -> 10266 bytes .../_vendor/pep517/in_process/_in_process.py | 363 + .../site-packages/pip/_vendor/pep517/meta.py | 92 + .../pip/_vendor/pep517/wrappers.py | 375 + .../pip/_vendor/pkg_resources/__init__.py | 3296 +++++++ .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 100333 bytes .../__pycache__/py31compat.cpython-39.pyc | Bin 0 -> 647 bytes .../pip/_vendor/pkg_resources/py31compat.py | 23 + .../pip/_vendor/platformdirs/__init__.py | 340 + .../pip/_vendor/platformdirs/__main__.py | 46 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 10700 bytes .../__pycache__/__main__.cpython-39.pyc | Bin 0 -> 1219 bytes .../__pycache__/android.cpython-39.pyc | Bin 0 -> 4418 bytes .../__pycache__/api.cpython-39.pyc | Bin 0 -> 5281 bytes .../__pycache__/macos.cpython-39.pyc | Bin 0 -> 3303 bytes .../__pycache__/unix.cpython-39.pyc | Bin 0 -> 7051 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 290 bytes .../__pycache__/windows.cpython-39.pyc | Bin 0 -> 6447 bytes .../pip/_vendor/platformdirs/android.py | 120 + .../pip/_vendor/platformdirs/api.py | 156 + .../pip/_vendor/platformdirs/macos.py | 64 + .../pip/_vendor/platformdirs/unix.py | 181 + .../pip/_vendor/platformdirs/version.py | 4 + .../pip/_vendor/platformdirs/windows.py | 182 + .../pip/_vendor/pygments/__init__.py | 83 + .../pip/_vendor/pygments/__main__.py | 17 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 3022 bytes .../__pycache__/__main__.cpython-39.pyc | Bin 0 -> 583 bytes .../__pycache__/cmdline.cpython-39.pyc | Bin 0 -> 15375 bytes .../__pycache__/console.cpython-39.pyc | Bin 0 -> 1880 bytes .../__pycache__/filter.cpython-39.pyc | Bin 0 -> 2641 bytes .../__pycache__/formatter.cpython-39.pyc | Bin 0 -> 3005 bytes .../pygments/__pycache__/lexer.cpython-39.pyc | Bin 0 -> 24435 bytes .../__pycache__/modeline.cpython-39.pyc | Bin 0 -> 1183 bytes .../__pycache__/plugin.cpython-39.pyc | Bin 0 -> 2103 bytes .../__pycache__/regexopt.cpython-39.pyc | Bin 0 -> 2937 bytes .../__pycache__/scanner.cpython-39.pyc | Bin 0 -> 3550 bytes .../__pycache__/sphinxext.cpython-39.pyc | Bin 0 -> 4555 bytes .../pygments/__pycache__/style.cpython-39.pyc | Bin 0 -> 4492 bytes .../pygments/__pycache__/token.cpython-39.pyc | Bin 0 -> 4354 bytes .../__pycache__/unistring.cpython-39.pyc | Bin 0 -> 31212 bytes .../pygments/__pycache__/util.cpython-39.pyc | Bin 0 -> 9169 bytes .../pip/_vendor/pygments/cmdline.py | 663 ++ .../pip/_vendor/pygments/console.py | 70 + .../pip/_vendor/pygments/filter.py | 71 + .../pip/_vendor/pygments/filters/__init__.py | 937 ++ .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 23390 bytes .../pip/_vendor/pygments/formatter.py | 94 + .../_vendor/pygments/formatters/__init__.py | 153 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 4658 bytes .../__pycache__/_mapping.cpython-39.pyc | Bin 0 -> 5414 bytes .../__pycache__/bbcode.cpython-39.pyc | Bin 0 -> 3062 bytes .../__pycache__/groff.cpython-39.pyc | Bin 0 -> 4335 bytes .../__pycache__/html.cpython-39.pyc | Bin 0 -> 29047 bytes .../formatters/__pycache__/img.cpython-39.pyc | Bin 0 -> 17489 bytes .../formatters/__pycache__/irc.cpython-39.pyc | Bin 0 -> 4401 bytes .../__pycache__/latex.cpython-39.pyc | Bin 0 -> 13483 bytes .../__pycache__/other.cpython-39.pyc | Bin 0 -> 4785 bytes .../__pycache__/pangomarkup.cpython-39.pyc | Bin 0 -> 2087 bytes .../formatters/__pycache__/rtf.cpython-39.pyc | Bin 0 -> 4121 bytes .../formatters/__pycache__/svg.cpython-39.pyc | Bin 0 -> 6333 bytes .../__pycache__/terminal.cpython-39.pyc | Bin 0 -> 3902 bytes .../__pycache__/terminal256.cpython-39.pyc | Bin 0 -> 9212 bytes .../_vendor/pygments/formatters/_mapping.py | 84 + .../pip/_vendor/pygments/formatters/bbcode.py | 108 + .../pip/_vendor/pygments/formatters/groff.py | 168 + .../pip/_vendor/pygments/formatters/html.py | 983 ++ .../pip/_vendor/pygments/formatters/img.py | 641 ++ .../pip/_vendor/pygments/formatters/irc.py | 179 + .../pip/_vendor/pygments/formatters/latex.py | 511 + .../pip/_vendor/pygments/formatters/other.py | 161 + .../pygments/formatters/pangomarkup.py | 83 + .../pip/_vendor/pygments/formatters/rtf.py | 146 + .../pip/_vendor/pygments/formatters/svg.py | 188 + .../_vendor/pygments/formatters/terminal.py | 127 + .../pygments/formatters/terminal256.py | 338 + .../pip/_vendor/pygments/lexer.py | 879 ++ .../pip/_vendor/pygments/lexers/__init__.py | 341 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 9135 bytes .../__pycache__/_mapping.cpython-39.pyc | Bin 0 -> 50818 bytes .../lexers/__pycache__/python.cpython-39.pyc | Bin 0 -> 28963 bytes .../pip/_vendor/pygments/lexers/_mapping.py | 580 ++ .../pip/_vendor/pygments/lexers/python.py | 1188 +++ .../pip/_vendor/pygments/modeline.py | 43 + .../pip/_vendor/pygments/plugin.py | 69 + .../pip/_vendor/pygments/regexopt.py | 91 + .../pip/_vendor/pygments/scanner.py | 104 + .../pip/_vendor/pygments/sphinxext.py | 155 + .../pip/_vendor/pygments/style.py | 197 + .../pip/_vendor/pygments/styles/__init__.py | 93 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 3003 bytes .../pip/_vendor/pygments/token.py | 212 + .../pip/_vendor/pygments/unistring.py | 153 + .../pip/_vendor/pygments/util.py | 308 + .../pip/_vendor/pyparsing/__init__.py | 331 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 7118 bytes .../__pycache__/actions.cpython-39.pyc | Bin 0 -> 7165 bytes .../__pycache__/common.cpython-39.pyc | Bin 0 -> 10056 bytes .../pyparsing/__pycache__/core.cpython-39.pyc | Bin 0 -> 177834 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 9153 bytes .../__pycache__/helpers.cpython-39.pyc | Bin 0 -> 35183 bytes .../__pycache__/results.cpython-39.pyc | Bin 0 -> 24791 bytes .../__pycache__/testing.cpython-39.pyc | Bin 0 -> 12106 bytes .../__pycache__/unicode.cpython-39.pyc | Bin 0 -> 10247 bytes .../pyparsing/__pycache__/util.cpython-39.pyc | Bin 0 -> 8616 bytes .../pip/_vendor/pyparsing/actions.py | 207 + .../pip/_vendor/pyparsing/common.py | 424 + .../pip/_vendor/pyparsing/core.py | 5812 +++++++++++ .../pip/_vendor/pyparsing/diagram/__init__.py | 611 ++ .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 16007 bytes .../pip/_vendor/pyparsing/exceptions.py | 267 + .../pip/_vendor/pyparsing/helpers.py | 1083 +++ .../pip/_vendor/pyparsing/results.py | 760 ++ .../pip/_vendor/pyparsing/testing.py | 331 + .../pip/_vendor/pyparsing/unicode.py | 332 + .../pip/_vendor/pyparsing/util.py | 235 + .../pip/_vendor/requests/__init__.py | 154 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 4025 bytes .../__pycache__/__version__.cpython-39.pyc | Bin 0 -> 552 bytes .../_internal_utils.cpython-39.pyc | Bin 0 -> 1299 bytes .../__pycache__/adapters.cpython-39.pyc | Bin 0 -> 17109 bytes .../requests/__pycache__/api.cpython-39.pyc | Bin 0 -> 6716 bytes .../requests/__pycache__/auth.cpython-39.pyc | Bin 0 -> 8328 bytes .../requests/__pycache__/certs.cpython-39.pyc | Bin 0 -> 630 bytes .../__pycache__/compat.cpython-39.pyc | Bin 0 -> 1665 bytes .../__pycache__/cookies.cpython-39.pyc | Bin 0 -> 18819 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 5655 bytes .../requests/__pycache__/help.cpython-39.pyc | Bin 0 -> 2890 bytes .../requests/__pycache__/hooks.cpython-39.pyc | Bin 0 -> 987 bytes .../__pycache__/models.cpython-39.pyc | Bin 0 -> 24368 bytes .../__pycache__/packages.cpython-39.pyc | Bin 0 -> 499 bytes .../__pycache__/sessions.cpython-39.pyc | Bin 0 -> 19703 bytes .../__pycache__/status_codes.cpython-39.pyc | Bin 0 -> 4236 bytes .../__pycache__/structures.cpython-39.pyc | Bin 0 -> 4457 bytes .../requests/__pycache__/utils.cpython-39.pyc | Bin 0 -> 24284 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 42 + .../pip/_vendor/requests/adapters.py | 538 ++ .../site-packages/pip/_vendor/requests/api.py | 159 + .../pip/_vendor/requests/auth.py | 305 + .../pip/_vendor/requests/certs.py | 18 + .../pip/_vendor/requests/compat.py | 77 + .../pip/_vendor/requests/cookies.py | 549 ++ .../pip/_vendor/requests/exceptions.py | 133 + .../pip/_vendor/requests/help.py | 132 + .../pip/_vendor/requests/hooks.py | 34 + .../pip/_vendor/requests/models.py | 973 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 771 ++ .../pip/_vendor/requests/status_codes.py | 123 + .../pip/_vendor/requests/structures.py | 105 + .../pip/_vendor/requests/utils.py | 1060 ++ .../pip/_vendor/resolvelib/__init__.py | 26 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 603 bytes .../__pycache__/providers.cpython-39.pyc | Bin 0 -> 6702 bytes .../__pycache__/reporters.cpython-39.pyc | Bin 0 -> 2614 bytes .../__pycache__/resolvers.cpython-39.pyc | Bin 0 -> 15305 bytes .../__pycache__/structs.cpython-39.pyc | Bin 0 -> 7276 bytes .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 198 bytes .../collections_abc.cpython-39.pyc | Bin 0 -> 372 bytes .../resolvelib/compat/collections_abc.py | 6 + .../pip/_vendor/resolvelib/providers.py | 133 + .../pip/_vendor/resolvelib/reporters.py | 43 + .../pip/_vendor/resolvelib/resolvers.py | 482 + .../pip/_vendor/resolvelib/structs.py | 165 + .../pip/_vendor/rich/__init__.py | 172 + .../pip/_vendor/rich/__main__.py | 282 + .../rich/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 5822 bytes .../rich/__pycache__/__main__.cpython-39.pyc | Bin 0 -> 7257 bytes .../__pycache__/_cell_widths.cpython-39.pyc | Bin 0 -> 7811 bytes .../__pycache__/_emoji_codes.cpython-39.pyc | Bin 0 -> 132698 bytes .../__pycache__/_emoji_replace.cpython-39.pyc | Bin 0 -> 1183 bytes .../__pycache__/_extension.cpython-39.pyc | Bin 0 -> 492 bytes .../rich/__pycache__/_inspect.cpython-39.pyc | Bin 0 -> 6738 bytes .../__pycache__/_log_render.cpython-39.pyc | Bin 0 -> 2575 bytes .../rich/__pycache__/_loop.cpython-39.pyc | Bin 0 -> 1265 bytes .../__pycache__/_lru_cache.cpython-39.pyc | Bin 0 -> 1682 bytes .../rich/__pycache__/_palettes.cpython-39.pyc | Bin 0 -> 5094 bytes .../rich/__pycache__/_pick.cpython-39.pyc | Bin 0 -> 635 bytes .../rich/__pycache__/_ratio.cpython-39.pyc | Bin 0 -> 5119 bytes .../rich/__pycache__/_spinners.cpython-39.pyc | Bin 0 -> 11591 bytes .../rich/__pycache__/_stack.cpython-39.pyc | Bin 0 -> 840 bytes .../rich/__pycache__/_timer.cpython-39.pyc | Bin 0 -> 687 bytes .../__pycache__/_win32_console.cpython-39.pyc | Bin 0 -> 18192 bytes .../rich/__pycache__/_windows.cpython-39.pyc | Bin 0 -> 1772 bytes .../_windows_renderer.cpython-39.pyc | Bin 0 -> 1955 bytes .../rich/__pycache__/_wrap.cpython-39.pyc | Bin 0 -> 1493 bytes .../rich/__pycache__/abc.cpython-39.pyc | Bin 0 -> 1301 bytes .../rich/__pycache__/align.cpython-39.pyc | Bin 0 -> 7850 bytes .../rich/__pycache__/ansi.cpython-39.pyc | Bin 0 -> 5607 bytes .../rich/__pycache__/bar.cpython-39.pyc | Bin 0 -> 2939 bytes .../rich/__pycache__/box.cpython-39.pyc | Bin 0 -> 7853 bytes .../rich/__pycache__/cells.cpython-39.pyc | Bin 0 -> 3414 bytes .../rich/__pycache__/color.cpython-39.pyc | Bin 0 -> 15171 bytes .../__pycache__/color_triplet.cpython-39.pyc | Bin 0 -> 1422 bytes .../rich/__pycache__/columns.cpython-39.pyc | Bin 0 -> 6126 bytes .../rich/__pycache__/console.cpython-39.pyc | Bin 0 -> 79633 bytes .../rich/__pycache__/constrain.cpython-39.pyc | Bin 0 -> 1660 bytes .../__pycache__/containers.cpython-39.pyc | Bin 0 -> 6421 bytes .../rich/__pycache__/control.cpython-39.pyc | Bin 0 -> 6832 bytes .../__pycache__/default_styles.cpython-39.pyc | Bin 0 -> 5140 bytes .../rich/__pycache__/diagnose.cpython-39.pyc | Bin 0 -> 1176 bytes .../rich/__pycache__/emoji.cpython-39.pyc | Bin 0 -> 3199 bytes .../rich/__pycache__/errors.cpython-39.pyc | Bin 0 -> 1666 bytes .../__pycache__/file_proxy.cpython-39.pyc | Bin 0 -> 2240 bytes .../rich/__pycache__/filesize.cpython-39.pyc | Bin 0 -> 2609 bytes .../__pycache__/highlighter.cpython-39.pyc | Bin 0 -> 6013 bytes .../rich/__pycache__/json.cpython-39.pyc | Bin 0 -> 4700 bytes .../rich/__pycache__/jupyter.cpython-39.pyc | Bin 0 -> 3991 bytes .../rich/__pycache__/layout.cpython-39.pyc | Bin 0 -> 14690 bytes .../rich/__pycache__/live.cpython-39.pyc | Bin 0 -> 11282 bytes .../__pycache__/live_render.cpython-39.pyc | Bin 0 -> 3387 bytes .../rich/__pycache__/logging.cpython-39.pyc | Bin 0 -> 9695 bytes .../rich/__pycache__/markup.cpython-39.pyc | Bin 0 -> 5920 bytes .../rich/__pycache__/measure.cpython-39.pyc | Bin 0 -> 4992 bytes .../rich/__pycache__/padding.cpython-39.pyc | Bin 0 -> 4403 bytes .../rich/__pycache__/pager.cpython-39.pyc | Bin 0 -> 1450 bytes .../rich/__pycache__/palette.cpython-39.pyc | Bin 0 -> 3685 bytes .../rich/__pycache__/panel.cpython-39.pyc | Bin 0 -> 6418 bytes .../rich/__pycache__/pretty.cpython-39.pyc | Bin 0 -> 27055 bytes .../rich/__pycache__/progress.cpython-39.pyc | Bin 0 -> 50130 bytes .../__pycache__/progress_bar.cpython-39.pyc | Bin 0 -> 6614 bytes .../rich/__pycache__/prompt.cpython-39.pyc | Bin 0 -> 11354 bytes .../rich/__pycache__/protocol.cpython-39.pyc | Bin 0 -> 1336 bytes .../rich/__pycache__/region.cpython-39.pyc | Bin 0 -> 522 bytes .../rich/__pycache__/repr.cpython-39.pyc | Bin 0 -> 4109 bytes .../rich/__pycache__/rule.cpython-39.pyc | Bin 0 -> 3698 bytes .../rich/__pycache__/scope.cpython-39.pyc | Bin 0 -> 2960 bytes .../rich/__pycache__/screen.cpython-39.pyc | Bin 0 -> 1819 bytes .../rich/__pycache__/segment.cpython-39.pyc | Bin 0 -> 20492 bytes .../rich/__pycache__/spinner.cpython-39.pyc | Bin 0 -> 4340 bytes .../rich/__pycache__/status.cpython-39.pyc | Bin 0 -> 4572 bytes .../rich/__pycache__/style.cpython-39.pyc | Bin 0 -> 20600 bytes .../rich/__pycache__/styled.cpython-39.pyc | Bin 0 -> 1685 bytes .../rich/__pycache__/syntax.cpython-39.pyc | Bin 0 -> 20312 bytes .../rich/__pycache__/table.cpython-39.pyc | Bin 0 -> 29368 bytes .../__pycache__/terminal_theme.cpython-39.pyc | Bin 0 -> 2964 bytes .../rich/__pycache__/text.cpython-39.pyc | Bin 0 -> 39563 bytes .../rich/__pycache__/theme.cpython-39.pyc | Bin 0 -> 4677 bytes .../rich/__pycache__/themes.cpython-39.pyc | Bin 0 -> 290 bytes .../rich/__pycache__/traceback.cpython-39.pyc | Bin 0 -> 19414 bytes .../rich/__pycache__/tree.cpython-39.pyc | Bin 0 -> 7218 bytes .../pip/_vendor/rich/_cell_widths.py | 451 + .../pip/_vendor/rich/_emoji_codes.py | 3610 +++++++ .../pip/_vendor/rich/_emoji_replace.py | 32 + .../pip/_vendor/rich/_extension.py | 10 + .../pip/_vendor/rich/_inspect.py | 222 + .../pip/_vendor/rich/_log_render.py | 94 + .../site-packages/pip/_vendor/rich/_loop.py | 43 + .../pip/_vendor/rich/_lru_cache.py | 38 + .../pip/_vendor/rich/_palettes.py | 309 + .../site-packages/pip/_vendor/rich/_pick.py | 17 + .../site-packages/pip/_vendor/rich/_ratio.py | 160 + .../pip/_vendor/rich/_spinners.py | 482 + .../site-packages/pip/_vendor/rich/_stack.py | 16 + .../site-packages/pip/_vendor/rich/_timer.py | 19 + .../pip/_vendor/rich/_win32_console.py | 630 ++ .../pip/_vendor/rich/_windows.py | 72 + .../pip/_vendor/rich/_windows_renderer.py | 53 + .../site-packages/pip/_vendor/rich/_wrap.py | 55 + .../site-packages/pip/_vendor/rich/abc.py | 33 + .../site-packages/pip/_vendor/rich/align.py | 311 + .../site-packages/pip/_vendor/rich/ansi.py | 237 + .../site-packages/pip/_vendor/rich/bar.py | 94 + .../site-packages/pip/_vendor/rich/box.py | 483 + .../site-packages/pip/_vendor/rich/cells.py | 140 + .../site-packages/pip/_vendor/rich/color.py | 615 ++ .../pip/_vendor/rich/color_triplet.py | 38 + .../site-packages/pip/_vendor/rich/columns.py | 187 + .../site-packages/pip/_vendor/rich/console.py | 2531 +++++ .../pip/_vendor/rich/constrain.py | 37 + .../pip/_vendor/rich/containers.py | 167 + .../site-packages/pip/_vendor/rich/control.py | 175 + .../pip/_vendor/rich/default_styles.py | 183 + .../pip/_vendor/rich/diagnose.py | 35 + .../site-packages/pip/_vendor/rich/emoji.py | 96 + .../site-packages/pip/_vendor/rich/errors.py | 34 + .../pip/_vendor/rich/file_proxy.py | 54 + .../pip/_vendor/rich/filesize.py | 89 + .../pip/_vendor/rich/highlighter.py | 173 + .../site-packages/pip/_vendor/rich/json.py | 140 + .../site-packages/pip/_vendor/rich/jupyter.py | 98 + .../site-packages/pip/_vendor/rich/layout.py | 445 + .../site-packages/pip/_vendor/rich/live.py | 365 + .../pip/_vendor/rich/live_render.py | 113 + .../site-packages/pip/_vendor/rich/logging.py | 280 + .../site-packages/pip/_vendor/rich/markup.py | 245 + .../site-packages/pip/_vendor/rich/measure.py | 151 + .../site-packages/pip/_vendor/rich/padding.py | 141 + .../site-packages/pip/_vendor/rich/pager.py | 34 + .../site-packages/pip/_vendor/rich/palette.py | 100 + .../site-packages/pip/_vendor/rich/panel.py | 251 + .../site-packages/pip/_vendor/rich/pretty.py | 991 ++ .../pip/_vendor/rich/progress.py | 1600 ++++ .../pip/_vendor/rich/progress_bar.py | 216 + .../site-packages/pip/_vendor/rich/prompt.py | 376 + .../pip/_vendor/rich/protocol.py | 42 + .../site-packages/pip/_vendor/rich/region.py | 10 + .../site-packages/pip/_vendor/rich/repr.py | 152 + .../site-packages/pip/_vendor/rich/rule.py | 115 + .../site-packages/pip/_vendor/rich/scope.py | 86 + .../site-packages/pip/_vendor/rich/screen.py | 54 + .../site-packages/pip/_vendor/rich/segment.py | 723 ++ .../site-packages/pip/_vendor/rich/spinner.py | 134 + .../site-packages/pip/_vendor/rich/status.py | 132 + .../site-packages/pip/_vendor/rich/style.py | 785 ++ .../site-packages/pip/_vendor/rich/styled.py | 42 + .../site-packages/pip/_vendor/rich/syntax.py | 769 ++ .../site-packages/pip/_vendor/rich/table.py | 996 ++ .../pip/_vendor/rich/terminal_theme.py | 153 + .../site-packages/pip/_vendor/rich/text.py | 1285 +++ .../site-packages/pip/_vendor/rich/theme.py | 112 + .../site-packages/pip/_vendor/rich/themes.py | 5 + .../pip/_vendor/rich/traceback.py | 677 ++ .../site-packages/pip/_vendor/rich/tree.py | 251 + .../site-packages/pip/_vendor/six.py | 998 ++ .../pip/_vendor/tenacity/__init__.py | 517 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 16276 bytes .../__pycache__/_asyncio.cpython-39.pyc | Bin 0 -> 2591 bytes .../__pycache__/_utils.cpython-39.pyc | Bin 0 -> 1228 bytes .../tenacity/__pycache__/after.cpython-39.pyc | Bin 0 -> 1207 bytes .../__pycache__/before.cpython-39.pyc | Bin 0 -> 1095 bytes .../__pycache__/before_sleep.cpython-39.pyc | Bin 0 -> 1387 bytes .../tenacity/__pycache__/nap.cpython-39.pyc | Bin 0 -> 1189 bytes .../tenacity/__pycache__/retry.cpython-39.pyc | Bin 0 -> 8777 bytes .../tenacity/__pycache__/stop.cpython-39.pyc | Bin 0 -> 4241 bytes .../__pycache__/tornadoweb.cpython-39.pyc | Bin 0 -> 1741 bytes .../tenacity/__pycache__/wait.cpython-39.pyc | Bin 0 -> 7953 bytes .../pip/_vendor/tenacity/_asyncio.py | 92 + .../pip/_vendor/tenacity/_utils.py | 68 + .../pip/_vendor/tenacity/after.py | 46 + .../pip/_vendor/tenacity/before.py | 41 + .../pip/_vendor/tenacity/before_sleep.py | 58 + .../site-packages/pip/_vendor/tenacity/nap.py | 43 + .../pip/_vendor/tenacity/retry.py | 213 + .../pip/_vendor/tenacity/stop.py | 96 + .../pip/_vendor/tenacity/tornadoweb.py | 59 + .../pip/_vendor/tenacity/wait.py | 191 + .../pip/_vendor/tomli/__init__.py | 11 + .../tomli/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 352 bytes .../tomli/__pycache__/_parser.cpython-39.pyc | Bin 0 -> 16598 bytes .../tomli/__pycache__/_re.cpython-39.pyc | Bin 0 -> 2831 bytes .../tomli/__pycache__/_types.cpython-39.pyc | Bin 0 -> 322 bytes .../pip/_vendor/tomli/_parser.py | 691 ++ .../site-packages/pip/_vendor/tomli/_re.py | 107 + .../site-packages/pip/_vendor/tomli/_types.py | 10 + .../pip/_vendor/typing_extensions.py | 1960 ++++ .../pip/_vendor/urllib3/__init__.py | 85 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2186 bytes .../__pycache__/_collections.cpython-39.pyc | Bin 0 -> 10781 bytes .../__pycache__/_version.cpython-39.pyc | Bin 0 -> 210 bytes .../__pycache__/connection.cpython-39.pyc | Bin 0 -> 13679 bytes .../__pycache__/connectionpool.cpython-39.pyc | Bin 0 -> 25359 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 11643 bytes .../urllib3/__pycache__/fields.cpython-39.pyc | Bin 0 -> 8158 bytes .../__pycache__/filepost.cpython-39.pyc | Bin 0 -> 2759 bytes .../__pycache__/poolmanager.cpython-39.pyc | Bin 0 -> 15178 bytes .../__pycache__/request.cpython-39.pyc | Bin 0 -> 5622 bytes .../__pycache__/response.cpython-39.pyc | Bin 0 -> 20782 bytes .../pip/_vendor/urllib3/_collections.py | 337 + .../pip/_vendor/urllib3/_version.py | 2 + .../pip/_vendor/urllib3/connection.py | 567 ++ .../pip/_vendor/urllib3/connectionpool.py | 1108 +++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 196 bytes .../_appengine_environ.cpython-39.pyc | Bin 0 -> 1416 bytes .../__pycache__/appengine.cpython-39.pyc | Bin 0 -> 8269 bytes .../__pycache__/ntlmpool.cpython-39.pyc | Bin 0 -> 3623 bytes .../__pycache__/pyopenssl.cpython-39.pyc | Bin 0 -> 15600 bytes .../securetransport.cpython-39.pyc | Bin 0 -> 21922 bytes .../contrib/__pycache__/socks.cpython-39.pyc | Bin 0 -> 5632 bytes .../urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 213 bytes .../__pycache__/bindings.cpython-39.pyc | Bin 0 -> 10705 bytes .../__pycache__/low_level.cpython-39.pyc | Bin 0 -> 9173 bytes .../contrib/_securetransport/bindings.py | 519 + .../contrib/_securetransport/low_level.py | 397 + .../pip/_vendor/urllib3/contrib/appengine.py | 314 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 130 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 511 + .../urllib3/contrib/securetransport.py | 922 ++ .../pip/_vendor/urllib3/contrib/socks.py | 216 + .../pip/_vendor/urllib3/exceptions.py | 323 + .../pip/_vendor/urllib3/fields.py | 274 + .../pip/_vendor/urllib3/filepost.py | 98 + .../pip/_vendor/urllib3/packages/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 197 bytes .../packages/__pycache__/six.cpython-39.pyc | Bin 0 -> 27580 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 207 bytes .../__pycache__/makefile.cpython-39.pyc | Bin 0 -> 1305 bytes .../urllib3/packages/backports/makefile.py | 51 + .../pip/_vendor/urllib3/packages/six.py | 1077 +++ .../pip/_vendor/urllib3/poolmanager.py | 537 ++ .../pip/_vendor/urllib3/request.py | 170 + .../pip/_vendor/urllib3/response.py | 818 ++ .../pip/_vendor/urllib3/util/__init__.py | 49 + .../util/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 1106 bytes .../__pycache__/connection.cpython-39.pyc | Bin 0 -> 3438 bytes .../util/__pycache__/proxy.cpython-39.pyc | Bin 0 -> 1342 bytes .../util/__pycache__/queue.cpython-39.pyc | Bin 0 -> 1061 bytes .../util/__pycache__/request.cpython-39.pyc | Bin 0 -> 3350 bytes .../util/__pycache__/response.cpython-39.pyc | Bin 0 -> 2346 bytes .../util/__pycache__/retry.cpython-39.pyc | Bin 0 -> 16253 bytes .../util/__pycache__/ssl_.cpython-39.pyc | Bin 0 -> 11330 bytes .../ssl_match_hostname.cpython-39.pyc | Bin 0 -> 3260 bytes .../__pycache__/ssltransport.cpython-39.pyc | Bin 0 -> 7476 bytes .../util/__pycache__/timeout.cpython-39.pyc | Bin 0 -> 8944 bytes .../util/__pycache__/url.cpython-39.pyc | Bin 0 -> 10669 bytes .../util/__pycache__/wait.cpython-39.pyc | Bin 0 -> 3129 bytes .../pip/_vendor/urllib3/util/connection.py | 149 + .../pip/_vendor/urllib3/util/proxy.py | 57 + .../pip/_vendor/urllib3/util/queue.py | 22 + .../pip/_vendor/urllib3/util/request.py | 137 + .../pip/_vendor/urllib3/util/response.py | 107 + .../pip/_vendor/urllib3/util/retry.py | 620 ++ .../pip/_vendor/urllib3/util/ssl_.py | 495 + .../urllib3/util/ssl_match_hostname.py | 159 + .../pip/_vendor/urllib3/util/ssltransport.py | 221 + .../pip/_vendor/urllib3/util/timeout.py | 268 + .../pip/_vendor/urllib3/util/url.py | 432 + .../pip/_vendor/urllib3/util/wait.py | 153 + .../site-packages/pip/_vendor/vendor.txt | 24 + .../pip/_vendor/webencodings/__init__.py | 342 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 9720 bytes .../__pycache__/labels.cpython-39.pyc | Bin 0 -> 3834 bytes .../__pycache__/mklabels.cpython-39.pyc | Bin 0 -> 1904 bytes .../__pycache__/tests.cpython-39.pyc | Bin 0 -> 5068 bytes .../__pycache__/x_user_defined.cpython-39.pyc | Bin 0 -> 2664 bytes .../pip/_vendor/webencodings/labels.py | 231 + .../pip/_vendor/webencodings/mklabels.py | 59 + .../pip/_vendor/webencodings/tests.py | 153 + .../_vendor/webencodings/x_user_defined.py | 325 + .../lib/python3.9/site-packages/pip/py.typed | 4 + .../site-packages/pkg_resources/__init__.py | 3288 +++++++ .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 100436 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 190 bytes .../__pycache__/appdirs.cpython-39.pyc | Bin 0 -> 20507 bytes .../__pycache__/pyparsing.cpython-39.pyc | Bin 0 -> 201344 bytes .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/packaging/__about__.py | 27 + .../_vendor/packaging/__init__.py | 26 + .../__pycache__/__about__.cpython-39.pyc | Bin 0 -> 706 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 552 bytes .../__pycache__/_compat.cpython-39.pyc | Bin 0 -> 1150 bytes .../__pycache__/_structures.cpython-39.pyc | Bin 0 -> 2904 bytes .../__pycache__/_typing.cpython-39.pyc | Bin 0 -> 1495 bytes .../__pycache__/markers.cpython-39.pyc | Bin 0 -> 9311 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 0 -> 4088 bytes .../__pycache__/specifiers.cpython-39.pyc | Bin 0 -> 20587 bytes .../packaging/__pycache__/tags.cpython-39.pyc | Bin 0 -> 17266 bytes .../__pycache__/utils.cpython-39.pyc | Bin 0 -> 1657 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 13324 bytes .../_vendor/packaging/_compat.py | 38 + .../_vendor/packaging/_structures.py | 86 + .../_vendor/packaging/_typing.py | 48 + .../_vendor/packaging/markers.py | 328 + .../_vendor/packaging/requirements.py | 145 + .../_vendor/packaging/specifiers.py | 863 ++ .../pkg_resources/_vendor/packaging/tags.py | 751 ++ .../pkg_resources/_vendor/packaging/utils.py | 65 + .../_vendor/packaging/version.py | 535 ++ .../pkg_resources/_vendor/pyparsing.py | 5742 +++++++++++ .../pkg_resources/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2879 bytes .../__pycache__/setup.cpython-39.pyc | Bin 0 -> 318 bytes .../data/my-test-package-source/setup.py | 6 + .../setuptools-58.1.0.dist-info/INSTALLER | 1 + .../setuptools-58.1.0.dist-info/LICENSE | 19 + .../setuptools-58.1.0.dist-info/METADATA | 119 + .../setuptools-58.1.0.dist-info/RECORD | 296 + .../setuptools-58.1.0.dist-info/REQUESTED | 0 .../setuptools-58.1.0.dist-info/WHEEL | 5 + .../entry_points.txt | 56 + .../setuptools-58.1.0.dist-info/top_level.txt | 3 + .../site-packages/setuptools/__init__.py | 242 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 8539 bytes .../_deprecation_warning.cpython-39.pyc | Bin 0 -> 549 bytes .../__pycache__/_imp.cpython-39.pyc | Bin 0 -> 2084 bytes .../__pycache__/archive_util.cpython-39.pyc | Bin 0 -> 5813 bytes .../__pycache__/build_meta.cpython-39.pyc | Bin 0 -> 9072 bytes .../__pycache__/config.cpython-39.pyc | Bin 0 -> 20825 bytes .../__pycache__/dep_util.cpython-39.pyc | Bin 0 -> 856 bytes .../__pycache__/depends.cpython-39.pyc | Bin 0 -> 5248 bytes .../__pycache__/dist.cpython-39.pyc | Bin 0 -> 36446 bytes .../__pycache__/errors.cpython-39.pyc | Bin 0 -> 849 bytes .../__pycache__/extension.cpython-39.pyc | Bin 0 -> 1943 bytes .../__pycache__/glob.cpython-39.pyc | Bin 0 -> 3693 bytes .../__pycache__/installer.cpython-39.pyc | Bin 0 -> 2770 bytes .../__pycache__/launch.cpython-39.pyc | Bin 0 -> 900 bytes .../__pycache__/monkey.cpython-39.pyc | Bin 0 -> 4612 bytes .../__pycache__/msvc.cpython-39.pyc | Bin 0 -> 42838 bytes .../__pycache__/namespaces.cpython-39.pyc | Bin 0 -> 3599 bytes .../__pycache__/package_index.cpython-39.pyc | Bin 0 -> 32635 bytes .../__pycache__/py34compat.cpython-39.pyc | Bin 0 -> 479 bytes .../__pycache__/sandbox.cpython-39.pyc | Bin 0 -> 15755 bytes .../__pycache__/unicode_utils.cpython-39.pyc | Bin 0 -> 1113 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 323 bytes .../__pycache__/wheel.cpython-39.pyc | Bin 0 -> 7279 bytes .../windows_support.cpython-39.pyc | Bin 0 -> 1022 bytes .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_distutils/__init__.py | 15 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 457 bytes .../__pycache__/_msvccompiler.cpython-39.pyc | Bin 0 -> 13812 bytes .../__pycache__/archive_util.cpython-39.pyc | Bin 0 -> 6644 bytes .../__pycache__/bcppcompiler.cpython-39.pyc | Bin 0 -> 6555 bytes .../__pycache__/ccompiler.cpython-39.pyc | Bin 0 -> 33423 bytes .../_distutils/__pycache__/cmd.cpython-39.pyc | Bin 0 -> 13983 bytes .../__pycache__/config.cpython-39.pyc | Bin 0 -> 3586 bytes .../__pycache__/core.cpython-39.pyc | Bin 0 -> 6711 bytes .../cygwinccompiler.cpython-39.pyc | Bin 0 -> 8791 bytes .../__pycache__/debug.cpython-39.pyc | Bin 0 -> 253 bytes .../__pycache__/dep_util.cpython-39.pyc | Bin 0 -> 2773 bytes .../__pycache__/dir_util.cpython-39.pyc | Bin 0 -> 5874 bytes .../__pycache__/dist.cpython-39.pyc | Bin 0 -> 34444 bytes .../__pycache__/errors.cpython-39.pyc | Bin 0 -> 5309 bytes .../__pycache__/extension.cpython-39.pyc | Bin 0 -> 6974 bytes .../__pycache__/fancy_getopt.cpython-39.pyc | Bin 0 -> 10682 bytes .../__pycache__/file_util.cpython-39.pyc | Bin 0 -> 6040 bytes .../__pycache__/filelist.cpython-39.pyc | Bin 0 -> 10832 bytes .../_distutils/__pycache__/log.cpython-39.pyc | Bin 0 -> 2372 bytes .../__pycache__/msvc9compiler.cpython-39.pyc | Bin 0 -> 17569 bytes .../__pycache__/msvccompiler.cpython-39.pyc | Bin 0 -> 14764 bytes .../__pycache__/py35compat.cpython-39.pyc | Bin 0 -> 629 bytes .../__pycache__/py38compat.cpython-39.pyc | Bin 0 -> 424 bytes .../__pycache__/spawn.cpython-39.pyc | Bin 0 -> 2900 bytes .../__pycache__/sysconfig.cpython-39.pyc | Bin 0 -> 12584 bytes .../__pycache__/text_file.cpython-39.pyc | Bin 0 -> 8498 bytes .../__pycache__/unixccompiler.cpython-39.pyc | Bin 0 -> 6874 bytes .../__pycache__/util.cpython-39.pyc | Bin 0 -> 14237 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 7398 bytes .../versionpredicate.cpython-39.pyc | Bin 0 -> 5182 bytes .../setuptools/_distutils/_msvccompiler.py | 561 ++ .../setuptools/_distutils/archive_util.py | 256 + .../setuptools/_distutils/bcppcompiler.py | 393 + .../setuptools/_distutils/ccompiler.py | 1123 +++ .../setuptools/_distutils/cmd.py | 403 + .../setuptools/_distutils/command/__init__.py | 31 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 532 bytes .../command/__pycache__/bdist.cpython-39.pyc | Bin 0 -> 3662 bytes .../__pycache__/bdist_dumb.cpython-39.pyc | Bin 0 -> 3645 bytes .../__pycache__/bdist_msi.cpython-39.pyc | Bin 0 -> 19827 bytes .../__pycache__/bdist_rpm.cpython-39.pyc | Bin 0 -> 12282 bytes .../__pycache__/bdist_wininst.cpython-39.pyc | Bin 0 -> 8602 bytes .../command/__pycache__/build.cpython-39.pyc | Bin 0 -> 3934 bytes .../__pycache__/build_clib.cpython-39.pyc | Bin 0 -> 4857 bytes .../__pycache__/build_ext.cpython-39.pyc | Bin 0 -> 16269 bytes .../__pycache__/build_py.cpython-39.pyc | Bin 0 -> 9852 bytes .../__pycache__/build_scripts.cpython-39.pyc | Bin 0 -> 4017 bytes .../command/__pycache__/check.cpython-39.pyc | Bin 0 -> 4966 bytes .../command/__pycache__/clean.cpython-39.pyc | Bin 0 -> 2139 bytes .../command/__pycache__/config.cpython-39.pyc | Bin 0 -> 10269 bytes .../__pycache__/install.cpython-39.pyc | Bin 0 -> 13881 bytes .../__pycache__/install_data.cpython-39.pyc | Bin 0 -> 2342 bytes .../install_egg_info.cpython-39.pyc | Bin 0 -> 3077 bytes .../install_headers.cpython-39.pyc | Bin 0 -> 1767 bytes .../__pycache__/install_lib.cpython-39.pyc | Bin 0 -> 5139 bytes .../install_scripts.cpython-39.pyc | Bin 0 -> 2190 bytes .../__pycache__/py37compat.cpython-39.pyc | Bin 0 -> 1033 bytes .../__pycache__/register.cpython-39.pyc | Bin 0 -> 8510 bytes .../command/__pycache__/sdist.cpython-39.pyc | Bin 0 -> 14537 bytes .../command/__pycache__/upload.cpython-39.pyc | Bin 0 -> 5260 bytes .../setuptools/_distutils/command/bdist.py | 143 + .../_distutils/command/bdist_dumb.py | 123 + .../_distutils/command/bdist_msi.py | 749 ++ .../_distutils/command/bdist_rpm.py | 579 ++ .../_distutils/command/bdist_wininst.py | 377 + .../setuptools/_distutils/command/build.py | 157 + .../_distutils/command/build_clib.py | 209 + .../_distutils/command/build_ext.py | 757 ++ .../setuptools/_distutils/command/build_py.py | 392 + .../_distutils/command/build_scripts.py | 152 + .../setuptools/_distutils/command/check.py | 148 + .../setuptools/_distutils/command/clean.py | 76 + .../setuptools/_distutils/command/config.py | 344 + .../setuptools/_distutils/command/install.py | 678 ++ .../_distutils/command/install_data.py | 79 + .../_distutils/command/install_egg_info.py | 77 + .../_distutils/command/install_headers.py | 47 + .../_distutils/command/install_lib.py | 217 + .../_distutils/command/install_scripts.py | 60 + .../_distutils/command/py37compat.py | 30 + .../setuptools/_distutils/command/register.py | 304 + .../setuptools/_distutils/command/sdist.py | 494 + .../setuptools/_distutils/command/upload.py | 214 + .../setuptools/_distutils/config.py | 130 + .../setuptools/_distutils/core.py | 234 + .../setuptools/_distutils/cygwinccompiler.py | 414 + .../setuptools/_distutils/debug.py | 5 + .../setuptools/_distutils/dep_util.py | 92 + .../setuptools/_distutils/dir_util.py | 210 + .../setuptools/_distutils/dist.py | 1257 +++ .../setuptools/_distutils/errors.py | 97 + .../setuptools/_distutils/extension.py | 240 + .../setuptools/_distutils/fancy_getopt.py | 457 + .../setuptools/_distutils/file_util.py | 238 + .../setuptools/_distutils/filelist.py | 355 + .../setuptools/_distutils/log.py | 77 + .../setuptools/_distutils/msvc9compiler.py | 788 ++ .../setuptools/_distutils/msvccompiler.py | 643 ++ .../setuptools/_distutils/py35compat.py | 19 + .../setuptools/_distutils/py38compat.py | 7 + .../setuptools/_distutils/spawn.py | 106 + .../setuptools/_distutils/sysconfig.py | 578 ++ .../setuptools/_distutils/text_file.py | 286 + .../setuptools/_distutils/unixccompiler.py | 332 + .../setuptools/_distutils/util.py | 535 ++ .../setuptools/_distutils/version.py | 347 + .../setuptools/_distutils/versionpredicate.py | 166 + .../site-packages/setuptools/_imp.py | 82 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 187 bytes .../__pycache__/ordered_set.cpython-39.pyc | Bin 0 -> 16381 bytes .../__pycache__/pyparsing.cpython-39.pyc | Bin 0 -> 201341 bytes .../_vendor/more_itertools/__init__.py | 4 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 268 bytes .../__pycache__/more.cpython-39.pyc | Bin 0 -> 110013 bytes .../__pycache__/recipes.cpython-39.pyc | Bin 0 -> 17933 bytes .../setuptools/_vendor/more_itertools/more.py | 3825 ++++++++ .../_vendor/more_itertools/recipes.py | 620 ++ .../setuptools/_vendor/ordered_set.py | 488 + .../setuptools/_vendor/packaging/__about__.py | 27 + .../setuptools/_vendor/packaging/__init__.py | 26 + .../__pycache__/__about__.cpython-39.pyc | Bin 0 -> 703 bytes .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 549 bytes .../__pycache__/_compat.cpython-39.pyc | Bin 0 -> 1147 bytes .../__pycache__/_structures.cpython-39.pyc | Bin 0 -> 2901 bytes .../__pycache__/_typing.cpython-39.pyc | Bin 0 -> 1492 bytes .../__pycache__/markers.cpython-39.pyc | Bin 0 -> 9305 bytes .../__pycache__/requirements.cpython-39.pyc | Bin 0 -> 4082 bytes .../__pycache__/specifiers.cpython-39.pyc | Bin 0 -> 20584 bytes .../packaging/__pycache__/tags.cpython-39.pyc | Bin 0 -> 17263 bytes .../__pycache__/utils.cpython-39.pyc | Bin 0 -> 1654 bytes .../__pycache__/version.cpython-39.pyc | Bin 0 -> 13321 bytes .../setuptools/_vendor/packaging/_compat.py | 38 + .../_vendor/packaging/_structures.py | 86 + .../setuptools/_vendor/packaging/_typing.py | 48 + .../setuptools/_vendor/packaging/markers.py | 328 + .../_vendor/packaging/requirements.py | 145 + .../_vendor/packaging/specifiers.py | 863 ++ .../setuptools/_vendor/packaging/tags.py | 751 ++ .../setuptools/_vendor/packaging/utils.py | 65 + .../setuptools/_vendor/packaging/version.py | 535 ++ .../setuptools/_vendor/pyparsing.py | 5742 +++++++++++ .../site-packages/setuptools/archive_util.py | 205 + .../site-packages/setuptools/build_meta.py | 281 + .../site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 8 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 376 bytes .../command/__pycache__/alias.cpython-39.pyc | Bin 0 -> 2370 bytes .../__pycache__/bdist_egg.cpython-39.pyc | Bin 0 -> 13036 bytes .../__pycache__/bdist_rpm.cpython-39.pyc | Bin 0 -> 1583 bytes .../__pycache__/build_clib.cpython-39.pyc | Bin 0 -> 2467 bytes .../__pycache__/build_ext.cpython-39.pyc | Bin 0 -> 9826 bytes .../__pycache__/build_py.cpython-39.pyc | Bin 0 -> 7817 bytes .../__pycache__/develop.cpython-39.pyc | Bin 0 -> 6136 bytes .../__pycache__/dist_info.cpython-39.pyc | Bin 0 -> 1394 bytes .../__pycache__/easy_install.cpython-39.pyc | Bin 0 -> 63587 bytes .../__pycache__/egg_info.cpython-39.pyc | Bin 0 -> 21977 bytes .../__pycache__/install.cpython-39.pyc | Bin 0 -> 4035 bytes .../install_egg_info.cpython-39.pyc | Bin 0 -> 2426 bytes .../__pycache__/install_lib.cpython-39.pyc | Bin 0 -> 4133 bytes .../install_scripts.cpython-39.pyc | Bin 0 -> 2421 bytes .../__pycache__/py36compat.cpython-39.pyc | Bin 0 -> 4588 bytes .../__pycache__/register.cpython-39.pyc | Bin 0 -> 844 bytes .../command/__pycache__/rotate.cpython-39.pyc | Bin 0 -> 2503 bytes .../__pycache__/saveopts.cpython-39.pyc | Bin 0 -> 922 bytes .../command/__pycache__/sdist.cpython-39.pyc | Bin 0 -> 6463 bytes .../command/__pycache__/setopt.cpython-39.pyc | Bin 0 -> 4673 bytes .../command/__pycache__/test.cpython-39.pyc | Bin 0 -> 8028 bytes .../command/__pycache__/upload.cpython-39.pyc | Bin 0 -> 817 bytes .../__pycache__/upload_docs.cpython-39.pyc | Bin 0 -> 6160 bytes .../site-packages/setuptools/command/alias.py | 78 + .../setuptools/command/bdist_egg.py | 456 + .../setuptools/command/bdist_rpm.py | 40 + .../setuptools/command/build_clib.py | 101 + .../setuptools/command/build_ext.py | 328 + .../setuptools/command/build_py.py | 232 + .../setuptools/command/develop.py | 193 + .../setuptools/command/dist_info.py | 36 + .../setuptools/command/easy_install.py | 2290 +++++ .../setuptools/command/egg_info.py | 734 ++ .../setuptools/command/install.py | 125 + .../setuptools/command/install_egg_info.py | 62 + .../setuptools/command/install_lib.py | 122 + .../setuptools/command/install_scripts.py | 69 + .../setuptools/command/launcher manifest.xml | 15 + .../setuptools/command/py36compat.py | 134 + .../setuptools/command/register.py | 18 + .../setuptools/command/rotate.py | 64 + .../setuptools/command/saveopts.py | 22 + .../site-packages/setuptools/command/sdist.py | 189 + .../setuptools/command/setopt.py | 149 + .../site-packages/setuptools/command/test.py | 252 + .../setuptools/command/upload.py | 17 + .../setuptools/command/upload_docs.py | 202 + .../site-packages/setuptools/config.py | 749 ++ .../site-packages/setuptools/dep_util.py | 25 + .../site-packages/setuptools/depends.py | 175 + .../site-packages/setuptools/dist.py | 1150 +++ .../site-packages/setuptools/errors.py | 16 + .../site-packages/setuptools/extension.py | 55 + .../setuptools/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 2918 bytes .../site-packages/setuptools/glob.py | 167 + .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/installer.py | 97 + .../site-packages/setuptools/launch.py | 36 + .../site-packages/setuptools/monkey.py | 177 + .../site-packages/setuptools/msvc.py | 1805 ++++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1119 +++ .../site-packages/setuptools/py34compat.py | 13 + .../site-packages/setuptools/sandbox.py | 530 + .../setuptools/script (dev).tmpl | 6 + .../site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/unicode_utils.py | 42 + .../site-packages/setuptools/version.py | 6 + .../site-packages/setuptools/wheel.py | 213 + .../setuptools/windows_support.py | 29 + .../uWSGI-2.0.20.dist-info/INSTALLER | 1 + .../uWSGI-2.0.20.dist-info/LICENSE | 355 + .../uWSGI-2.0.20.dist-info/METADATA | 26 + .../uWSGI-2.0.20.dist-info/RECORD | 10 + .../uWSGI-2.0.20.dist-info/REQUESTED | 0 .../uWSGI-2.0.20.dist-info/WHEEL | 5 + .../uWSGI-2.0.20.dist-info/top_level.txt | 1 + .../site-packages/uwsgidecorators.py | 419 + .../site-packages/werkzeug/__init__.py | 6 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 351 bytes .../__pycache__/_internal.cpython-39.pyc | Bin 0 -> 17111 bytes .../__pycache__/_reloader.cpython-39.pyc | Bin 0 -> 12267 bytes .../__pycache__/datastructures.cpython-39.pyc | Bin 0 -> 105953 bytes .../__pycache__/exceptions.cpython-39.pyc | Bin 0 -> 28161 bytes .../__pycache__/formparser.cpython-39.pyc | Bin 0 -> 13023 bytes .../werkzeug/__pycache__/http.cpython-39.pyc | Bin 0 -> 37297 bytes .../werkzeug/__pycache__/local.cpython-39.pyc | Bin 0 -> 18086 bytes .../__pycache__/routing.cpython-39.pyc | Bin 0 -> 73661 bytes .../__pycache__/security.cpython-39.pyc | Bin 0 -> 4855 bytes .../__pycache__/serving.cpython-39.pyc | Bin 0 -> 29719 bytes .../werkzeug/__pycache__/test.cpython-39.pyc | Bin 0 -> 38994 bytes .../__pycache__/testapp.cpython-39.pyc | Bin 0 -> 9541 bytes .../werkzeug/__pycache__/urls.cpython-39.pyc | Bin 0 -> 32672 bytes .../__pycache__/user_agent.cpython-39.pyc | Bin 0 -> 1832 bytes .../werkzeug/__pycache__/utils.cpython-39.pyc | Bin 0 -> 21642 bytes .../werkzeug/__pycache__/wsgi.cpython-39.pyc | Bin 0 -> 30262 bytes .../site-packages/werkzeug/_internal.py | 548 ++ .../site-packages/werkzeug/_reloader.py | 446 + .../site-packages/werkzeug/datastructures.py | 3037 ++++++ .../site-packages/werkzeug/datastructures.pyi | 921 ++ .../site-packages/werkzeug/debug/__init__.py | 504 + .../debug/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 13221 bytes .../debug/__pycache__/console.cpython-39.pyc | Bin 0 -> 8057 bytes .../debug/__pycache__/repr.cpython-39.pyc | Bin 0 -> 8872 bytes .../debug/__pycache__/tbtools.cpython-39.pyc | Bin 0 -> 11138 bytes .../site-packages/werkzeug/debug/console.py | 216 + .../site-packages/werkzeug/debug/repr.py | 284 + .../werkzeug/debug/shared/ICON_LICENSE.md | 6 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 359 + .../werkzeug/debug/shared/less.png | Bin 0 -> 191 bytes .../werkzeug/debug/shared/more.png | Bin 0 -> 200 bytes .../werkzeug/debug/shared/style.css | 150 + .../site-packages/werkzeug/debug/tbtools.py | 418 + .../site-packages/werkzeug/exceptions.py | 882 ++ .../site-packages/werkzeug/formparser.py | 455 + .../python3.9/site-packages/werkzeug/http.py | 1371 +++ .../python3.9/site-packages/werkzeug/local.py | 532 ++ .../werkzeug/middleware/__init__.py | 22 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 696 bytes .../__pycache__/dispatcher.cpython-39.pyc | Bin 0 -> 2755 bytes .../__pycache__/http_proxy.cpython-39.pyc | Bin 0 -> 6800 bytes .../__pycache__/lint.cpython-39.pyc | Bin 0 -> 12701 bytes .../__pycache__/profiler.cpython-39.pyc | Bin 0 -> 4948 bytes .../__pycache__/proxy_fix.cpython-39.pyc | Bin 0 -> 6172 bytes .../__pycache__/shared_data.cpython-39.pyc | Bin 0 -> 9105 bytes .../werkzeug/middleware/dispatcher.py | 78 + .../werkzeug/middleware/http_proxy.py | 230 + .../site-packages/werkzeug/middleware/lint.py | 420 + .../werkzeug/middleware/profiler.py | 139 + .../werkzeug/middleware/proxy_fix.py | 187 + .../werkzeug/middleware/shared_data.py | 280 + .../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 -> 184 bytes .../__pycache__/multipart.cpython-39.pyc | Bin 0 -> 6535 bytes .../sansio/__pycache__/request.cpython-39.pyc | Bin 0 -> 17127 bytes .../__pycache__/response.cpython-39.pyc | Bin 0 -> 22635 bytes .../sansio/__pycache__/utils.cpython-39.pyc | Bin 0 -> 3888 bytes .../werkzeug/sansio/multipart.py | 260 + .../site-packages/werkzeug/sansio/request.py | 547 ++ .../site-packages/werkzeug/sansio/response.py | 704 ++ .../site-packages/werkzeug/sansio/utils.py | 142 + .../site-packages/werkzeug/security.py | 140 + .../site-packages/werkzeug/serving.py | 1091 +++ .../python3.9/site-packages/werkzeug/test.py | 1325 +++ .../site-packages/werkzeug/testapp.py | 240 + .../python3.9/site-packages/werkzeug/urls.py | 1067 +++ .../site-packages/werkzeug/user_agent.py | 47 + .../python3.9/site-packages/werkzeug/utils.py | 705 ++ .../werkzeug/wrappers/__init__.py | 3 + .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 303 bytes .../__pycache__/request.cpython-39.pyc | Bin 0 -> 20119 bytes .../__pycache__/response.cpython-39.pyc | Bin 0 -> 29100 bytes .../werkzeug/wrappers/request.py | 614 ++ .../werkzeug/wrappers/response.py | 877 ++ .../python3.9/site-packages/werkzeug/wsgi.py | 982 ++ .../wheel-0.37.1.dist-info/INSTALLER | 1 + .../wheel-0.37.1.dist-info/LICENSE.txt | 22 + .../wheel-0.37.1.dist-info/METADATA | 69 + .../wheel-0.37.1.dist-info/RECORD | 41 + .../wheel-0.37.1.dist-info/REQUESTED | 0 .../wheel-0.37.1.dist-info/WHEEL | 6 + .../wheel-0.37.1.dist-info/entry_points.txt | 6 + .../wheel-0.37.1.dist-info/top_level.txt | 1 + .../python3.9/site-packages/wheel/__init__.py | 1 + .../python3.9/site-packages/wheel/__main__.py | 19 + .../wheel/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 196 bytes .../wheel/__pycache__/__main__.cpython-39.pyc | Bin 0 -> 593 bytes .../__pycache__/bdist_wheel.cpython-39.pyc | Bin 0 -> 13141 bytes .../__pycache__/macosx_libfile.cpython-39.pyc | Bin 0 -> 9973 bytes .../wheel/__pycache__/metadata.cpython-39.pyc | Bin 0 -> 3630 bytes .../wheel/__pycache__/pkginfo.cpython-39.pyc | Bin 0 -> 1635 bytes .../wheel/__pycache__/util.cpython-39.pyc | Bin 0 -> 1310 bytes .../__pycache__/wheelfile.cpython-39.pyc | Bin 0 -> 6089 bytes .../site-packages/wheel/bdist_wheel.py | 492 + .../site-packages/wheel/cli/__init__.py | 88 + .../cli/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 3080 bytes .../cli/__pycache__/convert.cpython-39.pyc | Bin 0 -> 6304 bytes .../wheel/cli/__pycache__/pack.cpython-39.pyc | Bin 0 -> 2937 bytes .../cli/__pycache__/unpack.cpython-39.pyc | Bin 0 -> 965 bytes .../site-packages/wheel/cli/convert.py | 269 + .../python3.9/site-packages/wheel/cli/pack.py | 82 + .../site-packages/wheel/cli/unpack.py | 25 + .../site-packages/wheel/macosx_libfile.py | 428 + .../python3.9/site-packages/wheel/metadata.py | 133 + .../python3.9/site-packages/wheel/pkginfo.py | 43 + .../lib/python3.9/site-packages/wheel/util.py | 46 + .../site-packages/wheel/vendored/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 183 bytes .../wheel/vendored/packaging/__init__.py | 0 .../__pycache__/__init__.cpython-39.pyc | Bin 0 -> 193 bytes .../__pycache__/_typing.cpython-39.pyc | Bin 0 -> 1488 bytes .../packaging/__pycache__/tags.cpython-39.pyc | Bin 0 -> 18543 bytes .../wheel/vendored/packaging/_typing.py | 48 + .../wheel/vendored/packaging/tags.py | 866 ++ .../site-packages/wheel/wheelfile.py | 181 + .../zipp-3.8.0.dist-info/INSTALLER | 1 + .../zipp-3.8.0.dist-info/LICENSE | 19 + .../zipp-3.8.0.dist-info/METADATA | 84 + .../site-packages/zipp-3.8.0.dist-info/RECORD | 8 + .../site-packages/zipp-3.8.0.dist-info/WHEEL | 5 + .../zipp-3.8.0.dist-info/top_level.txt | 1 + .../lib/python3.9/site-packages/zipp.py | 312 + zhdo.space/lib64 | 1 + zhdo.space/pyvenv.cfg | 3 + 1726 files changed, 316314 insertions(+) create mode 100644 .envrc create mode 100644 __pycache__/app.cpython-39.pyc create mode 100644 __pycache__/wsgi.cpython-39.pyc create mode 100644 app.py create mode 100644 templates/privacypolicy.html create mode 100644 wsgi.py create mode 100644 zhdo.space.ini create mode 100644 zhdo.space/bin/Activate.ps1 create mode 100644 zhdo.space/bin/activate create mode 100644 zhdo.space/bin/activate.csh create mode 100644 zhdo.space/bin/activate.fish create mode 100755 zhdo.space/bin/flask create mode 100755 zhdo.space/bin/pip create mode 100755 zhdo.space/bin/pip3 create mode 100755 zhdo.space/bin/pip3.10 create mode 100755 zhdo.space/bin/pip3.9 create mode 120000 zhdo.space/bin/python create mode 120000 zhdo.space/bin/python3 create mode 120000 zhdo.space/bin/python3.9 create mode 100755 zhdo.space/bin/uwsgi create mode 100755 zhdo.space/bin/wheel create mode 100644 zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/INSTALLER create mode 100644 zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/LICENSE.rst create mode 100644 zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/METADATA create mode 100644 zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/RECORD create mode 100644 zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/REQUESTED create mode 100644 zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/WHEEL create mode 100644 zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/entry_points.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/top_level.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/INSTALLER create mode 100644 zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst create mode 100644 zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/METADATA create mode 100644 zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/RECORD create mode 100644 zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/WHEEL create mode 100644 zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/top_level.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/INSTALLER create mode 100644 zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst create mode 100644 zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/METADATA create mode 100644 zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/RECORD create mode 100644 zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL create mode 100644 zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/INSTALLER create mode 100644 zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/LICENSE.rst create mode 100644 zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/METADATA create mode 100644 zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/RECORD create mode 100644 zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/WHEEL create mode 100644 zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/top_level.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/__pycache__/uwsgidecorators.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/__pycache__/zipp.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/_distutils_hack/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/_distutils_hack/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/_distutils_hack/__pycache__/override.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/_distutils_hack/override.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/INSTALLER create mode 100644 zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/LICENSE.rst create mode 100644 zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/METADATA create mode 100644 zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/RECORD create mode 100644 zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/WHEEL create mode 100644 zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/top_level.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/_compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/_termui_impl.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/_textwrap.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/_winconsole.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/core.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/decorators.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/exceptions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/formatting.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/globals.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/parser.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/shell_completion.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/termui.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/testing.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/types.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/__pycache__/utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/click/_compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/_termui_impl.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/_textwrap.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/_winconsole.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/core.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/decorators.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/exceptions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/formatting.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/globals.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/parser.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/py.typed create mode 100644 zhdo.space/lib/python3.9/site-packages/click/shell_completion.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/termui.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/testing.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/types.py create mode 100644 zhdo.space/lib/python3.9/site-packages/click/utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/distutils-precedence.pth create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__main__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/__main__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/app.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/blueprints.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/cli.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/config.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/ctx.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/debughelpers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/globals.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/helpers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/logging.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/scaffold.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/sessions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/signals.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/templating.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/testing.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/typing.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/views.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/__pycache__/wrappers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/app.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/blueprints.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/cli.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/config.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/ctx.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/debughelpers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/globals.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/helpers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/json/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/json/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/json/__pycache__/tag.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/json/tag.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/logging.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/py.typed create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/scaffold.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/sessions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/signals.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/templating.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/testing.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/typing.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/views.py create mode 100644 zhdo.space/lib/python3.9/site-packages/flask/wrappers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata-4.11.3.dist-info/INSTALLER create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata-4.11.3.dist-info/LICENSE create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata-4.11.3.dist-info/METADATA create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata-4.11.3.dist-info/RECORD create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata-4.11.3.dist-info/WHEEL create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata-4.11.3.dist-info/top_level.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/__pycache__/_adapters.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/__pycache__/_collections.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/__pycache__/_compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/__pycache__/_functools.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/__pycache__/_itertools.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/__pycache__/_meta.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/__pycache__/_text.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/_adapters.py create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/_collections.py create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/_compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/_functools.py create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/_itertools.py create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/_meta.py create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/_text.py create mode 100644 zhdo.space/lib/python3.9/site-packages/importlib_metadata/py.typed create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/METADATA create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/RECORD create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/WHEEL create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/__pycache__/_json.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/__pycache__/encoding.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/__pycache__/exc.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/__pycache__/serializer.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/__pycache__/signer.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/__pycache__/timed.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/__pycache__/url_safe.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/_json.py create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/encoding.py create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/exc.py create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/py.typed create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/serializer.py create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/signer.py create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/timed.py create mode 100644 zhdo.space/lib/python3.9/site-packages/itsdangerous/url_safe.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/_identifier.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/async_utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/bccache.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/compiler.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/constants.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/debug.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/defaults.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/environment.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/exceptions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/ext.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/filters.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/idtracking.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/lexer.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/loaders.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/meta.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/nativetypes.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/nodes.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/optimizer.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/parser.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/runtime.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/sandbox.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/tests.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/__pycache__/visitor.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/_identifier.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/async_utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/bccache.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/compiler.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/constants.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/debug.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/defaults.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/environment.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/exceptions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/ext.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/filters.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/idtracking.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/lexer.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/loaders.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/meta.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/nativetypes.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/nodes.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/optimizer.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/parser.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/py.typed create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/runtime.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/sandbox.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/tests.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/jinja2/visitor.py create mode 100644 zhdo.space/lib/python3.9/site-packages/markupsafe/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/markupsafe/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/markupsafe/__pycache__/_native.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/markupsafe/_native.py create mode 100644 zhdo.space/lib/python3.9/site-packages/markupsafe/_speedups.c create mode 100755 zhdo.space/lib/python3.9/site-packages/markupsafe/_speedups.cpython-39-x86_64-linux-gnu.so create mode 100644 zhdo.space/lib/python3.9/site-packages/markupsafe/_speedups.pyi create mode 100644 zhdo.space/lib/python3.9/site-packages/markupsafe/py.typed create mode 100644 zhdo.space/lib/python3.9/site-packages/pip-22.1.dist-info/INSTALLER create mode 100644 zhdo.space/lib/python3.9/site-packages/pip-22.1.dist-info/LICENSE.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/pip-22.1.dist-info/METADATA create mode 100644 zhdo.space/lib/python3.9/site-packages/pip-22.1.dist-info/RECORD create mode 100644 zhdo.space/lib/python3.9/site-packages/pip-22.1.dist-info/REQUESTED create mode 100644 zhdo.space/lib/python3.9/site-packages/pip-22.1.dist-info/WHEEL create mode 100644 zhdo.space/lib/python3.9/site-packages/pip-22.1.dist-info/entry_points.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/pip-22.1.dist-info/top_level.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/__main__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/__pycache__/__main__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/__pycache__/build_env.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/__pycache__/cache.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/__pycache__/configuration.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/__pycache__/exceptions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/__pycache__/main.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/__pycache__/pyproject.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/build_env.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cache.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/main.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/parser.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/base_command.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/command_context.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/main.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/main_parser.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/parser.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/progress_bars.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/req_command.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/spinners.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/cli/status_codes.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/cache.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/check.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/completion.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/debug.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/download.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/hash.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/help.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/index.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/install.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/list.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/search.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/show.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/cache.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/check.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/completion.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/configuration.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/debug.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/download.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/freeze.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/hash.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/help.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/index.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/install.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/list.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/search.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/show.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/uninstall.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/commands/wheel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/configuration.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/distributions/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/base.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/distributions/base.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/distributions/installed.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/distributions/sdist.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/distributions/wheel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/exceptions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/index/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/index/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/index/__pycache__/collector.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/index/__pycache__/sources.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/index/collector.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/index/package_finder.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/index/sources.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/locations/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/locations/__pycache__/base.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/locations/_distutils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/locations/_sysconfig.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/locations/base.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/main.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/__pycache__/base.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/base.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/importlib/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/importlib/_compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/importlib/_dists.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/importlib/_envs.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/metadata/pkg_resources.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/__pycache__/candidate.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/__pycache__/format_control.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/__pycache__/index.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/__pycache__/link.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/__pycache__/scheme.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/__pycache__/target_python.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/__pycache__/wheel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/candidate.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/direct_url.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/format_control.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/index.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/link.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/scheme.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/search_scope.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/target_python.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/models/wheel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/__pycache__/auth.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/__pycache__/cache.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/__pycache__/download.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/__pycache__/session.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/__pycache__/utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/auth.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/cache.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/download.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/lazy_wheel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/session.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/network/xmlrpc.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/check.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/build_tracker.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/metadata.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/metadata_editable.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/metadata_legacy.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/wheel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/wheel_editable.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/build/wheel_legacy.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/check.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/freeze.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/install/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/legacy.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/install/editable_legacy.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/install/legacy.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/operations/prepare.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/pyproject.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/req/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/req/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/req/__pycache__/constructors.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_file.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_install.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_set.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/req/constructors.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/req/req_file.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/req/req_install.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/req/req_set.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/__pycache__/base.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/base.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/legacy/resolver.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/reporter.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/resolution/resolvelib/resolver.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/self_outdated_check.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/_log.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/distutils_args.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/inject_securetransport.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/logging.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/misc.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/models.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/urls.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/_log.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/appdirs.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/compatibility_tags.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/datetime.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/deprecation.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/direct_url_helpers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/distutils_args.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/egg_link.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/encoding.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/entrypoints.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/filesystem.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/filetypes.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/glibc.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/hashes.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/inject_securetransport.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/logging.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/misc.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/models.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/packaging.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/subprocess.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/unpacking.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/urls.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/virtualenv.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/utils/wheel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/vcs/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/git.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/vcs/git.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/vcs/subversion.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/vcs/versioncontrol.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_internal/wheel_builder.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/__pycache__/six.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/certifi/core.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/enums.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/langrussianmodel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/metadata/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/metadata/__pycache__/languages.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/metadata/languages.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/chardet/version.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/colorama/win32.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/_backport/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/_backport/misc.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/_backport/shutil.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/_backport/sysconfig.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/_backport/tarfile.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/database.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/index.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/locators.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/markers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/resources.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/t32.exe create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/t64-arm.exe create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/t64.exe create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/util.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/version.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/w32.exe create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/w64-arm.exe create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/w64.exe create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distro/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distro/__main__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distro/__pycache__/__main__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/distro/distro.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/_ihatexml.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/_inputstream.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/_tokenizer.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/_base.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/py.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/_utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/constants.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/base.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/lint.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/optionaltags.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/sanitizer.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/whitespace.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/html5parser.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/serializer.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treeadapters/sax.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/base.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/dom.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/etree.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/base.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/dom.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/etree.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/core.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/codec.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/core.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/intranges.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/package_data.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/msgpack/_version.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/msgpack/ext.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/_manylinux.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/_musllinux.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/markers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/tags.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/packaging/version.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/dirtools.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/meta.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/build.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/check.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/colorlog.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/dirtools.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/envbuild.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/__pycache__/_in_process.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/in_process/_in_process.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/meta.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pep517/wrappers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pkg_resources/py31compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/__main__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/android.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/api.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/macos.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/unix.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/version.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/platformdirs/windows.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__main__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/cmdline.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/console.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/filter.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/filters/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatter.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/_mapping.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/bbcode.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/groff.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/html.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/img.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/irc.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/latex.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/other.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/pangomarkup.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/rtf.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/svg.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/terminal.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/formatters/terminal256.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/lexer.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/lexers/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/lexers/_mapping.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/lexers/python.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/modeline.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/plugin.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/regexopt.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/scanner.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/sphinxext.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/style.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/styles/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/token.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/unistring.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pygments/util.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/__pycache__/actions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/__pycache__/common.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/__pycache__/core.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/__pycache__/exceptions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/__pycache__/helpers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/__pycache__/results.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/__pycache__/testing.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/__pycache__/unicode.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/__pycache__/util.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/actions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/common.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/core.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/diagram/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/exceptions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/helpers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/results.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/testing.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/unicode.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/pyparsing/util.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/api.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/help.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/models.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/__version__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/adapters.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/api.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/auth.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/certs.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/cookies.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/help.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/hooks.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/models.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/packages.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/sessions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/structures.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/requests/utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/compat/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/compat/collections_abc.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/providers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/reporters.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/resolvers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/resolvelib/structs.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__main__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_lru_cache.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_windows_renderer.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/align.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/box.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/color.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/console.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/control.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/json.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/live.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/region.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/status.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/style.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/table.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/text.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_cell_widths.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_emoji_codes.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_emoji_replace.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_extension.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_inspect.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_log_render.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_loop.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_lru_cache.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_palettes.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_pick.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_ratio.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_spinners.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_stack.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_timer.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_win32_console.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_windows.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_windows_renderer.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/_wrap.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/abc.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/align.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/ansi.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/bar.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/box.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/cells.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/color.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/color_triplet.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/columns.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/console.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/constrain.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/containers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/control.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/default_styles.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/diagnose.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/emoji.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/errors.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/file_proxy.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/filesize.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/highlighter.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/json.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/jupyter.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/layout.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/live.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/live_render.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/logging.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/markup.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/measure.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/padding.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/pager.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/palette.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/panel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/pretty.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/progress.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/progress_bar.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/prompt.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/protocol.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/region.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/repr.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/rule.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/scope.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/screen.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/segment.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/spinner.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/status.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/style.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/styled.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/syntax.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/table.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/terminal_theme.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/text.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/theme.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/themes.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/traceback.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/rich/tree.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/six.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/_asyncio.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/_utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/after.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/before.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/before_sleep.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/nap.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/retry.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/stop.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/__pycache__/wait.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/_asyncio.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/_utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/after.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/before.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/before_sleep.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/nap.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/retry.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/stop.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/tornadoweb.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tenacity/wait.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tomli/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tomli/_parser.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tomli/_re.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/tomli/_types.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/typing_extensions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/_version.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/request.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/response.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/proxy.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/ssltransport.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/vendor.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pip/py.typed create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/_typing.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/tags.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/_compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/_typing.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/tags.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/extern/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/tests/data/my-test-package-source/__pycache__/setup.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/pkg_resources/tests/data/my-test-package-source/setup.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools-58.1.0.dist-info/INSTALLER create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools-58.1.0.dist-info/LICENSE create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools-58.1.0.dist-info/METADATA create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools-58.1.0.dist-info/RECORD create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools-58.1.0.dist-info/REQUESTED create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools-58.1.0.dist-info/WHEEL create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools-58.1.0.dist-info/entry_points.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools-58.1.0.dist-info/top_level.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/_imp.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/archive_util.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/build_meta.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/config.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/dep_util.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/depends.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/dist.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/errors.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/extension.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/glob.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/installer.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/launch.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/monkey.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/msvc.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/namespaces.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/package_index.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/py34compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/sandbox.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/unicode_utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/version.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/wheel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/__pycache__/windows_support.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_deprecation_warning.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/_msvccompiler.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/archive_util.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/bcppcompiler.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/ccompiler.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/cmd.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/config.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/core.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/cygwinccompiler.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/debug.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/dep_util.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/dir_util.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/dist.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/errors.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/extension.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/fancy_getopt.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/file_util.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/filelist.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/log.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/msvc9compiler.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/msvccompiler.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/py35compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/py38compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/spawn.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/sysconfig.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/text_file.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/unixccompiler.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/util.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/version.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/__pycache__/versionpredicate.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/_msvccompiler.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/archive_util.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/bcppcompiler.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/ccompiler.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/cmd.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/bdist.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/bdist_msi.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/bdist_wininst.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/build.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/build_clib.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/build_ext.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/build_py.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/build_scripts.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/check.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/clean.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/config.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/install.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/install_data.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/install_egg_info.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/install_headers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/install_lib.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/install_scripts.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/py37compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/register.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/sdist.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/__pycache__/upload.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/bdist.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/bdist_dumb.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/bdist_msi.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/bdist_rpm.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/bdist_wininst.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/build.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/build_clib.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/build_ext.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/build_py.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/build_scripts.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/check.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/clean.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/config.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/install.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/install_data.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/install_egg_info.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/install_headers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/install_lib.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/install_scripts.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/py37compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/register.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/sdist.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/command/upload.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/config.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/core.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/cygwinccompiler.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/debug.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/dep_util.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/dir_util.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/dist.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/errors.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/extension.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/fancy_getopt.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/file_util.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/filelist.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/log.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/msvc9compiler.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/msvccompiler.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/py35compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/py38compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/spawn.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/sysconfig.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/text_file.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/unixccompiler.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/util.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/version.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_distutils/versionpredicate.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_imp.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/__pycache__/ordered_set.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/more_itertools/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/more_itertools/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/more_itertools/__pycache__/more.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/more_itertools/__pycache__/recipes.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/more_itertools/more.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/more_itertools/recipes.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/ordered_set.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/_typing.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/tags.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/_compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/_typing.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/tags.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/archive_util.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/build_meta.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/cli-32.exe create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/cli-64.exe create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/cli.exe create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/alias.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/build_clib.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/build_ext.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/build_py.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/develop.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/dist_info.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/easy_install.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/egg_info.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/install.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/install_lib.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/install_scripts.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/py36compat.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/register.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/rotate.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/saveopts.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/sdist.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/setopt.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/test.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/upload.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/__pycache__/upload_docs.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/alias.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/bdist_egg.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/bdist_rpm.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/build_clib.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/build_ext.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/build_py.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/develop.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/dist_info.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/easy_install.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/egg_info.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/install.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/install_egg_info.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/install_lib.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/install_scripts.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/launcher manifest.xml create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/py36compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/register.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/rotate.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/saveopts.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/sdist.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/setopt.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/test.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/upload.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/command/upload_docs.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/config.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/dep_util.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/depends.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/dist.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/errors.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/extension.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/extern/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/extern/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/glob.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/gui-32.exe create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/gui-64.exe create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/gui.exe create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/installer.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/launch.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/monkey.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/msvc.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/namespaces.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/package_index.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/py34compat.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/sandbox.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/script (dev).tmpl create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/script.tmpl create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/unicode_utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/version.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/wheel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/setuptools/windows_support.py create mode 100644 zhdo.space/lib/python3.9/site-packages/uWSGI-2.0.20.dist-info/INSTALLER create mode 100644 zhdo.space/lib/python3.9/site-packages/uWSGI-2.0.20.dist-info/LICENSE create mode 100644 zhdo.space/lib/python3.9/site-packages/uWSGI-2.0.20.dist-info/METADATA create mode 100644 zhdo.space/lib/python3.9/site-packages/uWSGI-2.0.20.dist-info/RECORD create mode 100644 zhdo.space/lib/python3.9/site-packages/uWSGI-2.0.20.dist-info/REQUESTED create mode 100644 zhdo.space/lib/python3.9/site-packages/uWSGI-2.0.20.dist-info/WHEEL create mode 100644 zhdo.space/lib/python3.9/site-packages/uWSGI-2.0.20.dist-info/top_level.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/uwsgidecorators.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/_internal.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/_reloader.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/datastructures.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/exceptions.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/formparser.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/http.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/local.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/routing.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/security.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/serving.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/test.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/testapp.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/urls.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/user_agent.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/__pycache__/wsgi.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/_internal.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/_reloader.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/datastructures.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/datastructures.pyi create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/__pycache__/console.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/__pycache__/repr.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/console.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/repr.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/shared/ICON_LICENSE.md create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/shared/console.png create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/shared/less.png create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/shared/more.png create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/shared/style.css create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/debug/tbtools.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/exceptions.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/formparser.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/http.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/local.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/lint.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/dispatcher.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/http_proxy.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/lint.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/profiler.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/proxy_fix.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/shared_data.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/py.typed create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/routing.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/request.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/response.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/utils.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/multipart.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/request.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/response.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/security.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/serving.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/test.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/testapp.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/urls.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/user_agent.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/utils.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/request.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/response.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/request.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/response.py create mode 100644 zhdo.space/lib/python3.9/site-packages/werkzeug/wsgi.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/INSTALLER create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/LICENSE.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/METADATA create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/RECORD create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/REQUESTED create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/WHEEL create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/entry_points.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/top_level.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/__main__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/__main__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/bdist_wheel.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/macosx_libfile.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/metadata.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/pkginfo.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/util.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/wheelfile.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/bdist_wheel.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/cli/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/cli/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/cli/__pycache__/convert.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/cli/__pycache__/pack.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/cli/__pycache__/unpack.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/cli/convert.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/cli/pack.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/cli/unpack.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/macosx_libfile.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/metadata.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/pkginfo.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/util.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/vendored/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/vendored/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/vendored/packaging/__init__.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/vendored/packaging/__pycache__/__init__.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/vendored/packaging/__pycache__/_typing.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/vendored/packaging/__pycache__/tags.cpython-39.pyc create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/vendored/packaging/_typing.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/vendored/packaging/tags.py create mode 100644 zhdo.space/lib/python3.9/site-packages/wheel/wheelfile.py create mode 100644 zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/INSTALLER create mode 100644 zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/LICENSE create mode 100644 zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/METADATA create mode 100644 zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/RECORD create mode 100644 zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/WHEEL create mode 100644 zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/top_level.txt create mode 100644 zhdo.space/lib/python3.9/site-packages/zipp.py create mode 120000 zhdo.space/lib64 create mode 100644 zhdo.space/pyvenv.cfg diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..6f06ef9 --- /dev/null +++ b/.envrc @@ -0,0 +1,2 @@ +export FLASK_ENV=development +source zhdo.space/bin/activate diff --git a/__pycache__/app.cpython-39.pyc b/__pycache__/app.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab6ff6a75ccb36593aacfece5dff27f584aea759 GIT binary patch literal 596 zcmZuuy-ve05VrHvx}^~n;sHP`6rmU~R}~TxV(P*GijX2x8ye~)mXjcwfu*dx1B`v8 ztW3N@C(db6i{PyLbUuH+`+R1e*G6DRhc9=h7@<$I*)$tAXW-c_07o246ypG66I;@X z?ZC!JVBySg;0pJ>!R-&s9qzs&$TaIr12Roc>I@MMZ%r(HBizRpZ}Y7;Q>$}@dfpdw zKs{W!7m{U@Ij**~NVw2pE@CBFE*6-M3}@3oGdc&)8~~1?jx{WI`)Y70q)dA$sG|g73c2+l3Dx=ZVALp^uHgML8mQfROmG_Hm{^+ND%N&z1j9HX~ zVc9(K>(#@7GfuO7*lP#wy_ujkN`h`3`>Pp7$%8hNG6fPAi!iKgcxdJ7w8%yMG+j5a db&>oljP&D_7g7w&g`kf_9C%Bs(De7{oyaOhAqU5Em-|i4=wu#vF!RhA0L`hE&EBrfjAnnN)@a zObdbh6y{(CO_rBHRScSpx0n+P3T|=4$LA(y=EcYRX)+gq3<8PdCFZ8a$KPTuD$QHT zP{all1rxti^fU5vQ}we-6Z7=L^NX_et1?pZ^@Hello, World!

" + +@app.route("/privacy") +def privacypolicy(): + return render_template("privacypolicy.html") + +if __name__ == "__main__": + app.run(host='0.0.0.0') diff --git a/templates/privacypolicy.html b/templates/privacypolicy.html new file mode 100644 index 0000000..cf6edcf --- /dev/null +++ b/templates/privacypolicy.html @@ -0,0 +1,222 @@ + + + + + + + +

Privacy Policy for zhdo.space

+ +

+ At zhdo, accessible from zhdo.space, one of our main priorities is the + privacy of our visitors. This Privacy Policy document contains types of + information that is collected and recorded by zhdo and how we use it. +

+ +

+ If you have additional questions or require more information about our + Privacy Policy, do not hesitate to contact us. +

+ +

+ This Privacy Policy applies only to our online activities and is valid for + visitors to our website with regards to the information that they shared + and/or collect in zhdo. This policy is not applicable to any information + collected offline or via channels other than this website. Our Privacy + Policy was created with the help of the + Free Privacy Policy Generator. +

+ +

Consent

+ +

+ By using our website, you hereby consent to our Privacy Policy and agree + to its terms. +

+ +

Information we collect

+ +

+ The personal information that you are asked to provide, and the reasons + why you are asked to provide it, will be made clear to you at the point we + ask you to provide your personal information. +

+

+ If you contact us directly, we may receive additional information about + you such as your name, email address, phone number, the contents of the + message and/or attachments you may send us, and any other information you + may choose to provide. +

+

+ When you register for an Account, we may ask for your contact information, + including items such as name, company name, address, email address, and + telephone number. +

+ +

How we use your information

+ +

We use the information we collect in various ways, including to:

+ +
    +
  • Provide, operate, and maintain our website
  • +
  • Improve, personalize, and expand our website
  • +
  • Understand and analyze how you use our website
  • +
  • Develop new products, services, features, and functionality
  • +
  • + Communicate with you, either directly or through one of our partners, + including for customer service, to provide you with updates and other + information relating to the website, and for marketing and promotional + purposes +
  • +
  • Send you emails
  • +
  • Find and prevent fraud
  • +
+ +

Log Files

+ +

+ zhdo follows a standard procedure of using log files. These files log + visitors when they visit websites. All hosting companies do this and a + part of hosting services' analytics. The information collected by log + files include internet protocol (IP) addresses, browser type, Internet + Service Provider (ISP), date and time stamp, referring/exit pages, and + possibly the number of clicks. These are not linked to any information + that is personally identifiable. The purpose of the information is for + analyzing trends, administering the site, tracking users' movement on the + website, and gathering demographic information. +

+ +

Cookies and Web Beacons

+ +

+ Like any other website, zhdo uses 'cookies'. These cookies are used to + store information including visitors' preferences, and the pages on the + website that the visitor accessed or visited. The information is used to + optimize the users' experience by customizing our web page content based + on visitors' browser type and/or other information. +

+ +

+ For more general information on cookies, please read + the Cookies article on Generate Privacy Policy website. +

+ +

Advertising Partners Privacy Policies

+ +

+ You may consult this list to find the Privacy Policy for each of the + advertising partners of zhdo. +

+ +

+ Third-party ad servers or ad networks uses technologies like cookies, + JavaScript, or Web Beacons that are used in their respective + advertisements and links that appear on zhdo, which are sent directly to + users' browser. They automatically receive your IP address when this + occurs. These technologies are used to measure the effectiveness of their + advertising campaigns and/or to personalize the advertising content that + you see on websites that you visit. +

+ +

+ Note that zhdo has no access to or control over these cookies that are + used by third-party advertisers. +

+ +

Third Party Privacy Policies

+ +

+ zhdo's Privacy Policy does not apply to other advertisers or websites. + Thus, we are advising you to consult the respective Privacy Policies of + these third-party ad servers for more detailed information. It may include + their practices and instructions about how to opt-out of certain options. +

+ +

+ You can choose to disable cookies through your individual browser options. + To know more detailed information about cookie management with specific + web browsers, it can be found at the browsers' respective websites. +

+ +

CCPA Privacy Rights (Do Not Sell My Personal Information)

+ +

+ Under the CCPA, among other rights, California consumers have the right + to: +

+

+ Request that a business that collects a consumer's personal data disclose + the categories and specific pieces of personal data that a business has + collected about consumers. +

+

+ Request that a business delete any personal data about the consumer that a + business has collected. +

+

+ Request that a business that sells a consumer's personal data, not sell + the consumer's personal data. +

+

+ If you make a request, we have one month to respond to you. If you would + like to exercise any of these rights, please contact us. +

+ +

GDPR Data Protection Rights

+ +

+ We would like to make sure you are fully aware of all of your data + protection rights. Every user is entitled to the following: +

+

+ The right to access – You have the right to request copies of your + personal data. We may charge you a small fee for this service. +

+

+ The right to rectification – You have the right to request that we correct + any information you believe is inaccurate. You also have the right to + request that we complete the information you believe is incomplete. +

+

+ The right to erasure – You have the right to request that we erase your + personal data, under certain conditions. +

+

+ The right to restrict processing – You have the right to request that we + restrict the processing of your personal data, under certain conditions. +

+

+ The right to object to processing – You have the right to object to our + processing of your personal data, under certain conditions. +

+

+ The right to data portability – You have the right to request that we + transfer the data that we have collected to another organization, or + directly to you, under certain conditions. +

+

+ If you make a request, we have one month to respond to you. If you would + like to exercise any of these rights, please contact us. +

+ +

Children's Information

+ +

+ Another part of our priority is adding protection for children while using + the internet. We encourage parents and guardians to observe, participate + in, and/or monitor and guide their online activity. +

+ +

+ zhdo does not knowingly collect any Personal Identifiable Information from + children under the age of 13. If you think that your child provided this + kind of information on our website, we strongly encourage you to contact + us immediately and we will do our best efforts to promptly remove such + information from our records. +

+ + diff --git a/wsgi.py b/wsgi.py new file mode 100644 index 0000000..6026b0f --- /dev/null +++ b/wsgi.py @@ -0,0 +1,4 @@ +from app import app + +if __name__ == "__main__": + app.run() diff --git a/zhdo.space.ini b/zhdo.space.ini new file mode 100644 index 0000000..971b87e --- /dev/null +++ b/zhdo.space.ini @@ -0,0 +1,11 @@ +[uwsgi] +module = wsgi:app + +master = true +processes = 5 + +socket = myproject.sock +chmod-socket = 660 +vacuum = true + +die-on-term = true diff --git a/zhdo.space/bin/Activate.ps1 b/zhdo.space/bin/Activate.ps1 new file mode 100644 index 0000000..7bc3e7c --- /dev/null +++ b/zhdo.space/bin/Activate.ps1 @@ -0,0 +1,241 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/zhdo.space/bin/activate b/zhdo.space/bin/activate new file mode 100644 index 0000000..ef80ddb --- /dev/null +++ b/zhdo.space/bin/activate @@ -0,0 +1,66 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null + fi + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="/home/juan/Work/zhdo.space/zhdo.space" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1="(zhdo.space) ${PS1:-}" + export PS1 +fi + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then + hash -r 2> /dev/null +fi diff --git a/zhdo.space/bin/activate.csh b/zhdo.space/bin/activate.csh new file mode 100644 index 0000000..1c7d044 --- /dev/null +++ b/zhdo.space/bin/activate.csh @@ -0,0 +1,25 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/home/juan/Work/zhdo.space/zhdo.space" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = "(zhdo.space) $prompt" +endif + +alias pydoc python -m pydoc + +rehash diff --git a/zhdo.space/bin/activate.fish b/zhdo.space/bin/activate.fish new file mode 100644 index 0000000..bc80c64 --- /dev/null +++ b/zhdo.space/bin/activate.fish @@ -0,0 +1,64 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/); you cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + functions -e fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + + set -e VIRTUAL_ENV + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV "/home/juan/Work/zhdo.space/zhdo.space" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) "(zhdo.space) " (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" +end diff --git a/zhdo.space/bin/flask b/zhdo.space/bin/flask new file mode 100755 index 0000000..c7c6fbe --- /dev/null +++ b/zhdo.space/bin/flask @@ -0,0 +1,8 @@ +#!/home/juan/Work/zhdo.space/zhdo.space/bin/python +# -*- 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/zhdo.space/bin/pip b/zhdo.space/bin/pip new file mode 100755 index 0000000..b8d9f5a --- /dev/null +++ b/zhdo.space/bin/pip @@ -0,0 +1,8 @@ +#!/home/juan/Work/zhdo.space/zhdo.space/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/zhdo.space/bin/pip3 b/zhdo.space/bin/pip3 new file mode 100755 index 0000000..b8d9f5a --- /dev/null +++ b/zhdo.space/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/juan/Work/zhdo.space/zhdo.space/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/zhdo.space/bin/pip3.10 b/zhdo.space/bin/pip3.10 new file mode 100755 index 0000000..b8d9f5a --- /dev/null +++ b/zhdo.space/bin/pip3.10 @@ -0,0 +1,8 @@ +#!/home/juan/Work/zhdo.space/zhdo.space/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/zhdo.space/bin/pip3.9 b/zhdo.space/bin/pip3.9 new file mode 100755 index 0000000..b8d9f5a --- /dev/null +++ b/zhdo.space/bin/pip3.9 @@ -0,0 +1,8 @@ +#!/home/juan/Work/zhdo.space/zhdo.space/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/zhdo.space/bin/python b/zhdo.space/bin/python new file mode 120000 index 0000000..d20baaa --- /dev/null +++ b/zhdo.space/bin/python @@ -0,0 +1 @@ +/usr/lib/python-exec/python3.9/python \ No newline at end of file diff --git a/zhdo.space/bin/python3 b/zhdo.space/bin/python3 new file mode 120000 index 0000000..d8654aa --- /dev/null +++ b/zhdo.space/bin/python3 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/zhdo.space/bin/python3.9 b/zhdo.space/bin/python3.9 new file mode 120000 index 0000000..d8654aa --- /dev/null +++ b/zhdo.space/bin/python3.9 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/zhdo.space/bin/uwsgi b/zhdo.space/bin/uwsgi new file mode 100755 index 0000000000000000000000000000000000000000..56419f5e42374863da0152926a8aa5ea51e0c802 GIT binary patch literal 1447192 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

=;oVDyaTLnbL?)FxpWm(2gtdD?^YEd5z6K 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

6ql*o$90j1K$$#P7l*28;4?~B#-rh>VgnaUs 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

G)X(6b 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 z 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�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

    MQnL` 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

    MmWBa#;!yXd^A5dAN=V<2f&}c5qk}c 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 teu%#%?X>TI^q2pf{dxEI+N(~h?G=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: Werkzeug (>=2.0) +Requires-Dist: Jinja2 (>=3.0) +Requires-Dist: itsdangerous (>=2.0) +Requires-Dist: click (>=8.0) +Requires-Dist: importlib-metadata (>=3.6.0) ; python_version < "3.10" +Provides-Extra: async +Requires-Dist: asgiref (>=3.2) ; extra == 'async' +Provides-Extra: dotenv +Requires-Dist: python-dotenv ; extra == 'dotenv' + +Flask +===== + +Flask is a lightweight `WSGI`_ web application framework. It is designed +to make getting started quick and easy, with the ability to scale up to +complex applications. It began as a simple wrapper around `Werkzeug`_ +and `Jinja`_ and has become one of the most popular Python web +application frameworks. + +Flask offers suggestions, but doesn't enforce any dependencies or +project layout. It is up to the developer to choose the tools and +libraries they want to use. There are many extensions provided by the +community that make adding new functionality easy. + +.. _WSGI: https://wsgi.readthedocs.io/ +.. _Werkzeug: https://werkzeug.palletsprojects.com/ +.. _Jinja: https://jinja.palletsprojects.com/ + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U Flask + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + # save this as app.py + from flask import Flask + + app = Flask(__name__) + + @app.route("/") + def hello(): + return "Hello, World!" + +.. code-block:: text + + $ flask run + * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) + + +Contributing +------------ + +For guidance on setting up a development environment and how to make a +contribution to Flask, see the `contributing guidelines`_. + +.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst + + +Donate +------ + +The Pallets organization develops and supports Flask and the libraries +it uses. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://flask.palletsprojects.com/ +- Changes: https://flask.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/Flask/ +- Source Code: https://github.com/pallets/flask/ +- Issue Tracker: https://github.com/pallets/flask/issues/ +- Website: https://palletsprojects.com/p/flask/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/RECORD b/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/RECORD new file mode 100644 index 0000000..077619f --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/RECORD @@ -0,0 +1,52 @@ +../../../bin/flask,sha256=1lRVtYaoWSjC9ZbYkM4l4oDH_WZkG9tW3ZfTPP0SME0,240 +Flask-2.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Flask-2.1.2.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +Flask-2.1.2.dist-info/METADATA,sha256=V3wRBN5pAKumPcu41b-ePUWUQkdyka_WVPXwMKGvLGQ,3907 +Flask-2.1.2.dist-info/RECORD,, +Flask-2.1.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +Flask-2.1.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +Flask-2.1.2.dist-info/entry_points.txt,sha256=s3MqQpduU25y4dq3ftBYD6bMVdVnbMpZP-sUNw0zw0k,41 +Flask-2.1.2.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6 +flask/__init__.py,sha256=hutpl3wZCIHR-FckBdDZMe_pw89k7llUTj7c7t77cWc,2207 +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=b6_j0OtlrssZ05fMReHNwzSLN3M7mkI9LR8UWuhcm0g,82070 +flask/blueprints.py,sha256=W2C5eFciX2Zq8zJSKQHiQd488Ytcsrt6wcXSZ-rSU7c,23362 +flask/cli.py,sha256=eCZMiAFr6quTZo2pZ5RH2NBS1cQEZqLke9MCloOVIMA,31185 +flask/config.py,sha256=IWqHecH4poDxNEUg4U_ZA1CTlL5BKZDX3ofG4UGYyi0,12584 +flask/ctx.py,sha256=smANecq_Tr3FFi2UMDs3Nn-xYi9GhKrzZvFpkDqXtLM,18336 +flask/debughelpers.py,sha256=parkDxfxxGZZAOGSumyrGLCTKcws86lJ2X3RqikiwUE,6036 +flask/globals.py,sha256=cWd-R2hUH3VqPhnmQNww892tQS6Yjqg_wg8UvW1M7NM,1723 +flask/helpers.py,sha256=qkbHG_6-Ox_uDmmD8ZwA9k4nTI8Q8U5S_6QtXpzZCRg,29266 +flask/json/__init__.py,sha256=jZHbiHKOICmnMttYIhHYrCj2LeHjZY-J7KiYoorjc4I,10394 +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=vFn4R_sDhaWwxH77UGmRUWgE2p9tzj9VqRHG5dvE7wM,32545 +flask/sessions.py,sha256=y0f1WBTQqjebkjtiT6d0G_ejIvllsjzch5sq_NUoXec,15834 +flask/signals.py,sha256=H7QwDciK-dtBxinjKpexpglP0E6k0MJILiFWTItfmqU,2136 +flask/templating.py,sha256=6rcyoV-Z57uBGMB6_xl4LhQJHbF456naf-GU8pjQSPM,5659 +flask/testing.py,sha256=mfyDupACHNQinATGAcrqqDst9Ik4CnNg3rP9gvpUjks,10385 +flask/typing.py,sha256=P1x3WCUYE7ddMNCUVqr04V5EjJy4M0Osz1MfVM0xgMQ,2116 +flask/views.py,sha256=nhq31TRB5Z-z2mjFGZACaaB2Et5XPCmWhWxJxOvLWww,5948 +flask/wrappers.py,sha256=Vgs2HlC8WNUOELQasV-Xad8DFTFwJe3eUltZG9z4Cu8,5675 diff --git a/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/REQUESTED b/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/WHEEL b/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/entry_points.txt b/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/entry_points.txt new file mode 100644 index 0000000..137232d --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +flask = flask.cli:main diff --git a/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/top_level.txt b/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/top_level.txt new file mode 100644 index 0000000..7e10602 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Flask-2.1.2.dist-info/top_level.txt @@ -0,0 +1 @@ +flask diff --git a/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/INSTALLER b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2007 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/METADATA b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/METADATA new file mode 100644 index 0000000..f54bb5c --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/METADATA @@ -0,0 +1,113 @@ +Metadata-Version: 2.1 +Name: Jinja2 +Version: 3.1.2 +Summary: A very fast and expressive template engine. +Home-page: https://palletsprojects.com/p/jinja/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://jinja.palletsprojects.com/ +Project-URL: Changes, https://jinja.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/jinja/ +Project-URL: Issue Tracker, https://github.com/pallets/jinja/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: MarkupSafe (>=2.0) +Provides-Extra: i18n +Requires-Dist: Babel (>=2.7) ; extra == 'i18n' + +Jinja +===== + +Jinja is a fast, expressive, extensible templating engine. Special +placeholders in the template allow writing code similar to Python +syntax. Then the template is passed data to render the final document. + +It includes: + +- Template inheritance and inclusion. +- Define and import macros within templates. +- HTML templates can use autoescaping to prevent XSS from untrusted + user input. +- A sandboxed environment can safely render untrusted templates. +- AsyncIO support for generating templates and calling async + functions. +- I18N support with Babel. +- Templates are compiled to optimized Python code just-in-time and + cached, or can be compiled ahead-of-time. +- Exceptions point to the correct line in templates to make debugging + easier. +- Extensible filters, tests, functions, and even syntax. + +Jinja's philosophy is that while application logic belongs in Python if +possible, it shouldn't make the template designer's job difficult by +restricting functionality too much. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U Jinja2 + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +In A Nutshell +------------- + +.. code-block:: jinja + + {% extends "base.html" %} + {% block title %}Members{% endblock %} + {% block content %} + + {% endblock %} + + +Donate +------ + +The Pallets organization develops and supports Jinja and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://jinja.palletsprojects.com/ +- Changes: https://jinja.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/Jinja2/ +- Source Code: https://github.com/pallets/jinja/ +- Issue Tracker: https://github.com/pallets/jinja/issues/ +- Website: https://palletsprojects.com/p/jinja/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/RECORD b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/RECORD new file mode 100644 index 0000000..b972dd9 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/RECORD @@ -0,0 +1,58 @@ +Jinja2-3.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Jinja2-3.1.2.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +Jinja2-3.1.2.dist-info/METADATA,sha256=PZ6v2SIidMNixR7MRUX9f7ZWsPwtXanknqiZUmRbh4U,3539 +Jinja2-3.1.2.dist-info/RECORD,, +Jinja2-3.1.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +Jinja2-3.1.2.dist-info/entry_points.txt,sha256=zRd62fbqIyfUpsRtU7EVIFyiu1tPwfgO7EvPErnxgTE,59 +Jinja2-3.1.2.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 +jinja2/__init__.py,sha256=8vGduD8ytwgD6GDSqpYc2m3aU-T7PKOAddvVXgGr_Fs,1927 +jinja2/__pycache__/__init__.cpython-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=_zYctNKzRqlk_murTNlzrju1FFJL7Va_Ijqqd7ii2lU,1958 +jinja2/async_utils.py,sha256=dHlbTeaxFPtAOQEYOGYh_PHcDT0rsDaUJAFDl_0XtTg,2472 +jinja2/bccache.py,sha256=mhz5xtLxCcHRAa56azOhphIAe19u1we0ojifNMClDio,14061 +jinja2/compiler.py,sha256=Gs-N8ThJ7OWK4-reKoO8Wh1ZXz95MVphBKNVf75qBr8,72172 +jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 +jinja2/debug.py,sha256=iWJ432RadxJNnaMOPrjIDInz50UEgni3_HKuFXi2vuQ,6299 +jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 +jinja2/environment.py,sha256=6uHIcc7ZblqOMdx_uYNKqRnnwAF0_nzbyeMP9FFtuh4,61349 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=ivr3P7LKbddiXDVez20EflcO3q2aHQwz9P_PgWGHVqE,31502 +jinja2/filters.py,sha256=9js1V-h2RlyW90IhLiBGLM2U-k6SCy2F4BUUMgB3K9Q,53509 +jinja2/idtracking.py,sha256=GfNmadir4oDALVxzn3DL9YInhJDr69ebXeA2ygfuCGA,10704 +jinja2/lexer.py,sha256=DW2nX9zk-6MWp65YR2bqqj0xqCvLtD-u9NWT8AnFRxQ,29726 +jinja2/loaders.py,sha256=BfptfvTVpClUd-leMkHczdyPNYFzp_n7PKOJ98iyHOg,23207 +jinja2/meta.py,sha256=GNPEvifmSaU3CMxlbheBOZjeZ277HThOPUTf1RkppKQ,4396 +jinja2/nativetypes.py,sha256=DXgORDPRmVWgy034H0xL8eF7qYoK3DrMxs-935d0Fzk,4226 +jinja2/nodes.py,sha256=i34GPRAZexXMT6bwuf5SEyvdmS-bRCy9KMjwN5O6pjk,34550 +jinja2/optimizer.py,sha256=tHkMwXxfZkbfA1KmLcqmBMSaz7RLIvvItrJcPoXTyD8,1650 +jinja2/parser.py,sha256=nHd-DFHbiygvfaPtm9rcQXJChZG7DPsWfiEsqfwKerY,39595 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=5CmD5BjbEJxSiDNTFBeKCaq8qU4aYD2v6q2EluyExms,33476 +jinja2/sandbox.py,sha256=Y0xZeXQnH6EX5VjaV2YixESxoepnRbW_3UeQosaBU3M,14584 +jinja2/tests.py,sha256=Am5Z6Lmfr2XaH_npIfJJ8MdXtWsbLjMULZJulTAj30E,5905 +jinja2/utils.py,sha256=u9jXESxGn8ATZNVolwmkjUVu4SA-tLgV0W7PcSfPfdQ,23965 +jinja2/visitor.py,sha256=MH14C6yq24G_KVtWzjwaI7Wg14PCJIYlWW1kpkxYak0,3568 diff --git a/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/WHEEL b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt new file mode 100644 index 0000000..7b9666c --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[babel.extractors] +jinja2 = jinja2.ext:babel_extract[i18n] diff --git a/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/top_level.txt b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/top_level.txt new file mode 100644 index 0000000..7f7afbf --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Jinja2-3.1.2.dist-info/top_level.txt @@ -0,0 +1 @@ +jinja2 diff --git a/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/INSTALLER b/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst b/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2010 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/METADATA b/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/METADATA new file mode 100644 index 0000000..485a5e0 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/METADATA @@ -0,0 +1,101 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 2.1.1 +Summary: Safely add untrusted strings to HTML/XML markup. +Home-page: https://palletsprojects.com/p/markupsafe/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://markupsafe.palletsprojects.com/ +Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/markupsafe/ +Project-URL: Issue Tracker, https://github.com/pallets/markupsafe/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst + +MarkupSafe +========== + +MarkupSafe implements a text object that escapes characters so it is +safe to use in HTML and XML. Characters that have special meanings are +replaced so that they display as the actual characters. This mitigates +injection attacks, meaning untrusted user input can safely be displayed +on a page. + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U MarkupSafe + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +Examples +-------- + +.. code-block:: pycon + + >>> from markupsafe import Markup, escape + + >>> # escape replaces special characters and wraps in Markup + >>> escape("") + Markup('<script>alert(document.cookie);</script>') + + >>> # wrap in Markup to mark text "safe" and prevent escaping + >>> Markup("Hello") + Markup('hello') + + >>> escape(Markup("Hello")) + Markup('hello') + + >>> # Markup is a str subclass + >>> # methods and operators escape their arguments + >>> template = Markup("Hello {name}") + >>> template.format(name='"World"') + Markup('Hello "World"') + + +Donate +------ + +The Pallets organization develops and supports MarkupSafe and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +`please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://markupsafe.palletsprojects.com/ +- Changes: https://markupsafe.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/MarkupSafe/ +- Source Code: https://github.com/pallets/markupsafe/ +- Issue Tracker: https://github.com/pallets/markupsafe/issues/ +- Website: https://palletsprojects.com/p/markupsafe/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/RECORD b/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/RECORD new file mode 100644 index 0000000..5c80498 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/RECORD @@ -0,0 +1,14 @@ +MarkupSafe-2.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-2.1.1.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +MarkupSafe-2.1.1.dist-info/METADATA,sha256=DC93VszmzjLQcrVChRUjtW4XbUwjTdbaplpgdlbFdbs,3242 +MarkupSafe-2.1.1.dist-info/RECORD,, +MarkupSafe-2.1.1.dist-info/WHEEL,sha256=ts1NGDem03kTrzsJp50lKy9cpDxDoGil0Q-wLa_TR_0,148 +MarkupSafe-2.1.1.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=xfaUQkKNRTdYWe6HnnJ2HjguFmS-C_0H6g8-Q9VAfkQ,9284 +markupsafe/__pycache__/__init__.cpython-39.pyc,, +markupsafe/__pycache__/_native.cpython-39.pyc,, +markupsafe/_native.py,sha256=GR86Qvo_GcgKmKreA1WmYN9ud17OFwkww8E-fiW-57s,1713 +markupsafe/_speedups.c,sha256=X2XvQVtIdcK4Usz70BvkzoOfjTCmQlDkkjYSn-swE0g,7083 +markupsafe/_speedups.cpython-39-x86_64-linux-gnu.so,sha256=DCWkK-C94Ojd4_RrL6I_91Jl0DsomXQ8XdhfOpXhKxo,44008 +markupsafe/_speedups.pyi,sha256=vfMCsOgbAXRNLUXkyuyonG8uEWKYU4PDqNuMaDELAYw,229 +markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL b/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL new file mode 100644 index 0000000..ade3730 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.0) +Root-Is-Purelib: false +Tag: cp39-cp39-manylinux_2_17_x86_64 +Tag: cp39-cp39-manylinux2014_x86_64 + diff --git a/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt b/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/INSTALLER b/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/LICENSE.rst b/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/LICENSE.rst new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2007 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/METADATA b/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/METADATA new file mode 100644 index 0000000..7247470 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/METADATA @@ -0,0 +1,128 @@ +Metadata-Version: 2.1 +Name: Werkzeug +Version: 2.1.2 +Summary: The comprehensive WSGI web application library. +Home-page: https://palletsprojects.com/p/werkzeug/ +Author: Armin Ronacher +Author-email: armin.ronacher@active-4.com +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://werkzeug.palletsprojects.com/ +Project-URL: Changes, https://werkzeug.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/werkzeug/ +Project-URL: Issue Tracker, https://github.com/pallets/werkzeug/issues/ +Project-URL: Twitter, https://twitter.com/PalletsTeam +Project-URL: Chat, https://discord.gg/pallets +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.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Provides-Extra: watchdog +Requires-Dist: watchdog ; extra == 'watchdog' + +Werkzeug +======== + +*werkzeug* German noun: "tool". Etymology: *werk* ("work"), *zeug* ("stuff") + +Werkzeug is a comprehensive `WSGI`_ web application library. It began as +a simple collection of various utilities for WSGI applications and has +become one of the most advanced WSGI utility libraries. + +It includes: + +- An interactive debugger that allows inspecting stack traces and + source code in the browser with an interactive interpreter for any + frame in the stack. +- A full-featured request object with objects to interact with + headers, query args, form data, files, and cookies. +- A response object that can wrap other WSGI applications and handle + streaming data. +- A routing system for matching URLs to endpoints and generating URLs + for endpoints, with an extensible system for capturing variables + from URLs. +- HTTP utilities to handle entity tags, cache control, dates, user + agents, cookies, files, and more. +- A threaded WSGI server for use while developing applications + locally. +- A test client for simulating HTTP requests during testing without + requiring running a server. + +Werkzeug doesn't enforce any dependencies. It is up to the developer to +choose a template engine, database adapter, and even how to handle +requests. It can be used to build all sorts of end user applications +such as blogs, wikis, or bulletin boards. + +`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while +providing more structure and patterns for defining powerful +applications. + +.. _WSGI: https://wsgi.readthedocs.io/en/latest/ +.. _Flask: https://www.palletsprojects.com/p/flask/ + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + pip install -U Werkzeug + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + from werkzeug.wrappers import Request, Response + + @Request.application + def application(request): + return Response('Hello, World!') + + if __name__ == '__main__': + from werkzeug.serving import run_simple + run_simple('localhost', 4000, application) + + +Donate +------ + +The Pallets organization develops and supports Werkzeug and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +`please donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://werkzeug.palletsprojects.com/ +- Changes: https://werkzeug.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/Werkzeug/ +- Source Code: https://github.com/pallets/werkzeug/ +- Issue Tracker: https://github.com/pallets/werkzeug/issues/ +- Website: https://palletsprojects.com/p/werkzeug/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/RECORD b/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/RECORD new file mode 100644 index 0000000..aa9e6b2 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/RECORD @@ -0,0 +1,86 @@ +Werkzeug-2.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +Werkzeug-2.1.2.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +Werkzeug-2.1.2.dist-info/METADATA,sha256=vWBYPD9d_Qzl4WAupfJ5Fy_ep7pqMPnGvkSLYiCi4B0,4400 +Werkzeug-2.1.2.dist-info/RECORD,, +Werkzeug-2.1.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +Werkzeug-2.1.2.dist-info/top_level.txt,sha256=QRyj2VjwJoQkrwjwFIOlB8Xg3r9un0NtqVHQF-15xaw,9 +werkzeug/__init__.py,sha256=BtM-3LM8iob4OwPY693-LqZ5RcnDS4iftOqBK28uZ2k,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__/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__/utils.cpython-39.pyc,, +werkzeug/__pycache__/wsgi.cpython-39.pyc,, +werkzeug/_internal.py,sha256=g8PHJz2z39I3x0vwTvTKbXIg0eUQqGF9UtUzDMWT0Qw,16222 +werkzeug/_reloader.py,sha256=lYStlIDduTxBOB8BSozy_44HQ7YT5fup-x3uuac1-2o,14331 +werkzeug/datastructures.py,sha256=Sk5gYGJbgvwpM-5IursyEWwo815RB5NAs2wFcTjHG0M,97018 +werkzeug/datastructures.pyi,sha256=L7MfJjHrEjKuAZ57w5d2eaiUIWYya52crapklFnKUz0,34493 +werkzeug/debug/__init__.py,sha256=Qds7CmReDr13XUaKYvcwnGNBQp6d86ooGV_to2Uw0C0,17730 +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=08mKGZLMsrd2E-0qD82J5knUbI2DomHXUQ5z0550a_o,6082 +werkzeug/debug/repr.py,sha256=Mp911LMRzZUoNvrCLQfKKpQZbNKdIM8VbjzJQjBkdsM,9481 +werkzeug/debug/shared/ICON_LICENSE.md,sha256=DhA6Y1gUl5Jwfg0NFN9Rj4VWITt8tUx0IvdGf0ux9-s,222 +werkzeug/debug/shared/console.png,sha256=bxax6RXXlvOij_KeqvSNX0ojJf83YbnZ7my-3Gx9w2A,507 +werkzeug/debug/shared/debugger.js,sha256=tg42SZs1SVmYWZ-_Fj5ELK5-FLHnGNQrei0K2By8Bw8,10521 +werkzeug/debug/shared/less.png,sha256=-4-kNRaXJSONVLahrQKUxMwXGm9R4OnZ9SxDGpHlIR4,191 +werkzeug/debug/shared/more.png,sha256=GngN7CioHQoV58rH6ojnkYi8c_qED2Aka5FO5UXrReY,200 +werkzeug/debug/shared/style.css,sha256=-xSxzUEZGw_IqlDR5iZxitNl8LQUjBM-_Y4UAvXVH8g,6078 +werkzeug/debug/tbtools.py,sha256=cBsPKCrB0FRT8i5EUdGo0A8MStWSj7O3Jk40r7Ll3ok,12633 +werkzeug/exceptions.py,sha256=5nzjr4AN_J-jtkT2FgDIm8SUiC0tjzWcROXse06H6a8,26498 +werkzeug/formparser.py,sha256=rLEu_ZwVpvqshZg6E4Qiv36QsmzmCytTijBeGX3dDGk,16056 +werkzeug/http.py,sha256=RUwj0JM1Em3LHyqyXSJOkdtBOT24mJlGFbklqo3PWDY,44602 +werkzeug/local.py,sha256=cj0M4BzMGdg_CD-H3osv9Zf9by4qY-BzAD68bxp979Q,18343 +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=L4ISeRPhFbrMWt8CFHHExyvuWxE3CyqbfD5hTQKkVjA,13966 +werkzeug/middleware/profiler.py,sha256=QkXk7cqnaPnF8wQu-5SyPCIOT3_kdABUBorQOghVNOA,4899 +werkzeug/middleware/proxy_fix.py,sha256=l7LC_LDu0Yd4SvUxS5SFigAJMzcIOGm6LNKl9IXJBSU,6974 +werkzeug/middleware/shared_data.py,sha256=fXjrEkuqxUVLG1DLrOdQLc96QQdjftCBZ1oM5oK89h4,9528 +werkzeug/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +werkzeug/routing.py,sha256=zopf1P3MG-atd33YdBwIO49AnJ7nem5SKQig5FIhKEI,84346 +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=BRjBk_mCPjSJzwNVvBgmrJGk3QxA9pYfsgzFki28bxc,8751 +werkzeug/sansio/request.py,sha256=6xhrNJAqScdbBF5i7HN-Y_1XjJ04wQtBKOsZuCy0AYw,20176 +werkzeug/sansio/response.py,sha256=zvCq9HSBBZGBd5Gg412BY9RZIwnKsJl5Kzfd3Kl9sSo,26098 +werkzeug/sansio/utils.py,sha256=V5v-UUnX8pm4RehP9Tt_NiUSOJGJGUvKjlW0eOIQldM,4164 +werkzeug/security.py,sha256=vrBofh4WZZoUo1eAdJ6F1DrzVRlYauGS2CUDYpbQKj8,4658 +werkzeug/serving.py,sha256=aL-dIwzwO_-UuUs0cKwYFOynUWVmYcaDjz713Wy_BHE,38337 +werkzeug/test.py,sha256=7Ur4IinGCk9k5WCNk6x-mr2JrnupvKRXt6n-qNfo9oE,47841 +werkzeug/testapp.py,sha256=p-2lMyvaHXzP1lau0tUAJTbW4STogoMpXFyCkeRBkAI,9397 +werkzeug/urls.py,sha256=Q9Si-eVh7yxk3rwkzrwGRm146FXVXgg9lBP3k0HUfVM,36600 +werkzeug/user_agent.py,sha256=WclZhpvgLurMF45hsioSbS75H1Zb4iMQGKN3_yZ2oKo,1420 +werkzeug/utils.py,sha256=5HGm_5WSKBTVVl8IgvA-b-jL7gjT-LHWXH0ZKzCCI0I,24932 +werkzeug/wrappers/__init__.py,sha256=kGyK7rOud3qCxll_jFyW15YarJhj1xtdf3ocx9ZheB8,120 +werkzeug/wrappers/__pycache__/__init__.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/request.cpython-39.pyc,, +werkzeug/wrappers/__pycache__/response.cpython-39.pyc,, +werkzeug/wrappers/request.py,sha256=UQ559KkGS0Po6HTBgvKMlk1_AsNw5zstzm8o_dRrfdQ,23415 +werkzeug/wrappers/response.py,sha256=c2HUXrrt5Sf8-XEB1fUXxm6jp7Lu80KR0A_tbQFvw1Q,34750 +werkzeug/wsgi.py,sha256=L7s5-Rlt7BRVEZ1m81MaenGfMDP7yL3p1Kxt9Yssqzg,33727 diff --git a/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/WHEEL b/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/top_level.txt b/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/top_level.txt new file mode 100644 index 0000000..6fe8da8 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/Werkzeug-2.1.2.dist-info/top_level.txt @@ -0,0 +1 @@ +werkzeug diff --git a/zhdo.space/lib/python3.9/site-packages/__pycache__/uwsgidecorators.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/__pycache__/uwsgidecorators.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8cf20b0b7e990daad089b918b345dd2da91ff090 GIT binary patch literal 14170 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 btn?Wa#ub;+t-AFK^-EQ+UO)fp=7s+PFntOf literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/_distutils_hack/__init__.py b/zhdo.space/lib/python3.9/site-packages/_distutils_hack/__init__.py new file mode 100644 index 0000000..5f40996 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/_distutils_hack/__init__.py @@ -0,0 +1,128 @@ +import sys +import os +import re +import importlib +import warnings + + +is_pypy = '__pypy__' in sys.builtin_module_names + + +warnings.filterwarnings('ignore', + r'.+ distutils\b.+ deprecated', + DeprecationWarning) + + +def warn_distutils_present(): + if 'distutils' not in sys.modules: + return + if is_pypy and sys.version_info < (3, 7): + # PyPy for 3.6 unconditionally imports distutils, so bypass the warning + # https://foss.heptapod.net/pypy/pypy/-/blob/be829135bc0d758997b3566062999ee8b23872b4/lib-python/3/site.py#L250 + return + warnings.warn( + "Distutils was imported before Setuptools, but importing Setuptools " + "also replaces the `distutils` module in `sys.modules`. This may lead " + "to undesirable behaviors or errors. To avoid these issues, avoid " + "using distutils directly, ensure that setuptools is installed in the " + "traditional way (e.g. not an editable install), and/or make sure " + "that setuptools is always imported before distutils.") + + +def clear_distutils(): + if 'distutils' not in sys.modules: + return + warnings.warn("Setuptools is replacing distutils.") + mods = [name for name in sys.modules if re.match(r'distutils\b', name)] + for name in mods: + del sys.modules[name] + + +def enabled(): + """ + Allow selection of distutils by environment variable. + """ + which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'stdlib') + return which == 'local' + + +def ensure_local_distutils(): + clear_distutils() + distutils = importlib.import_module('setuptools._distutils') + distutils.__name__ = 'distutils' + sys.modules['distutils'] = distutils + + # sanity check that submodules load as expected + core = importlib.import_module('distutils.core') + assert '_distutils' in core.__file__, core.__file__ + + +def do_override(): + """ + Ensure that the local copy of distutils is preferred over stdlib. + + See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401 + for more motivation. + """ + if enabled(): + warn_distutils_present() + ensure_local_distutils() + + +class DistutilsMetaFinder: + def find_spec(self, fullname, path, target=None): + if path is not None: + return + + method_name = 'spec_for_{fullname}'.format(**locals()) + method = getattr(self, method_name, lambda: None) + return method() + + def spec_for_distutils(self): + import importlib.abc + import importlib.util + + class DistutilsLoader(importlib.abc.Loader): + + def create_module(self, spec): + return importlib.import_module('setuptools._distutils') + + def exec_module(self, module): + pass + + return importlib.util.spec_from_loader('distutils', DistutilsLoader()) + + def spec_for_pip(self): + """ + Ensure stdlib distutils when running under pip. + See pypa/pip#8761 for rationale. + """ + if self.pip_imported_during_build(): + return + clear_distutils() + self.spec_for_distutils = lambda: None + + @staticmethod + def pip_imported_during_build(): + """ + Detect if pip is being imported in a build script. Ref #2355. + """ + import traceback + return any( + frame.f_globals['__file__'].endswith('setup.py') + for frame, line in traceback.walk_stack(None) + ) + + +DISTUTILS_FINDER = DistutilsMetaFinder() + + +def add_shim(): + sys.meta_path.insert(0, DISTUTILS_FINDER) + + +def remove_shim(): + try: + sys.meta_path.remove(DISTUTILS_FINDER) + except ValueError: + pass diff --git a/zhdo.space/lib/python3.9/site-packages/_distutils_hack/__pycache__/__init__.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/_distutils_hack/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c18321c2ddf5a175748fdf5b5c8249b5ec9a2470 GIT binary patch literal 5104 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.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: colorama ; platform_system == "Windows" +Requires-Dist: importlib-metadata ; python_version < "3.8" + +\$ click\_ +========== + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U click + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + import click + + @click.command() + @click.option("--count", default=1, help="Number of greetings.") + @click.option("--name", prompt="Your name", help="The person to greet.") + def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo(f"Hello, {name}!") + + if __name__ == '__main__': + hello() + +.. code-block:: text + + $ python hello.py --count=3 + Your name: Click + Hello, Click! + Hello, Click! + Hello, Click! + + +Donate +------ + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://click.palletsprojects.com/ +- Changes: https://click.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/click/ +- Source Code: https://github.com/pallets/click +- Issue Tracker: https://github.com/pallets/click/issues +- Website: https://palletsprojects.com/p/click +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff --git a/zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/RECORD b/zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/RECORD new file mode 100644 index 0000000..3ca86f8 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/RECORD @@ -0,0 +1,39 @@ +click-8.1.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.1.3.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click-8.1.3.dist-info/METADATA,sha256=tFJIX5lOjx7c5LjZbdTPFVDJSgyv9F74XY0XCPp_gnc,3247 +click-8.1.3.dist-info/RECORD,, +click-8.1.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +click-8.1.3.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click/__init__.py,sha256=rQBLutqg-z6m8nOzivIfigDn_emijB_dKv9BZ2FNi5s,3138 +click/__pycache__/__init__.cpython-39.pyc,, +click/__pycache__/_compat.cpython-39.pyc,, +click/__pycache__/_termui_impl.cpython-39.pyc,, +click/__pycache__/_textwrap.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=JIHLYs7Jzz4KT9t-ds4o4jBzLjnwCiJQKqur-5iwCKI,18810 +click/_termui_impl.py,sha256=qK6Cfy4mRFxvxE8dya8RBhLpSC8HjF-lvBc6aNrPdwg,23451 +click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 +click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 +click/core.py,sha256=mz87bYEKzIoNYEa56BFAiOJnvt1Y0L-i7wD4_ZecieE,112782 +click/decorators.py,sha256=yo3zvzgUm5q7h5CXjyV6q3h_PJAiUaem178zXwdWUFI,16350 +click/exceptions.py,sha256=7gDaLGuFZBeCNwY9ERMsF2-Z3R9Fvq09Zc6IZSKjseo,9167 +click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 +click/globals.py,sha256=TP-qM88STzc7f127h35TD_v920FgfOD2EwzqA0oE8XU,1961 +click/parser.py,sha256=cAEt1uQR8gq3-S9ysqbVU-fdAZNvilxw4ReJ_T1OQMk,19044 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=qOp_BeC9esEOSZKyu5G7RIxEUaLsXUX-mTb7hB1r4QY,18018 +click/termui.py,sha256=ACBQVOvFCTSqtD5VREeCAdRtlHd-Imla-Lte4wSfMjA,28355 +click/testing.py,sha256=ptpMYgRY7dVfE3UDgkgwayu9ePw98sQI3D7zZXiCpj4,16063 +click/types.py,sha256=rEb1aZSQKq3ciCMmjpG2Uva9vk498XRL7ThrcK2GRss,35805 +click/utils.py,sha256=33D6E7poH_nrKB-xr-UyDEXnxOcCiQqxuRLtrqeVv6o,18682 diff --git a/zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/WHEEL b/zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/top_level.txt b/zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/click-8.1.3.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/zhdo.space/lib/python3.9/site-packages/click/__init__.py b/zhdo.space/lib/python3.9/site-packages/click/__init__.py new file mode 100644 index 0000000..e3ef423 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/click/__init__.py @@ -0,0 +1,73 @@ +""" +Click is a simple Python module inspired by the stdlib optparse to make +writing command line scripts fun. Unlike other modules, it's based +around a simple API that does not come with too much magic and is +composable. +""" +from .core import Argument as Argument +from .core import BaseCommand as BaseCommand +from .core import Command as Command +from .core import CommandCollection as CommandCollection +from .core import Context as Context +from .core import Group as Group +from .core import MultiCommand as MultiCommand +from .core import Option as Option +from .core import Parameter as Parameter +from .decorators import argument as argument +from .decorators import command as command +from .decorators import confirmation_option as confirmation_option +from .decorators import group as group +from .decorators import help_option as help_option +from .decorators import make_pass_decorator as make_pass_decorator +from .decorators import option as option +from .decorators import pass_context as pass_context +from .decorators import pass_obj as pass_obj +from .decorators import password_option as password_option +from .decorators import version_option as version_option +from .exceptions import Abort as Abort +from .exceptions import BadArgumentUsage as BadArgumentUsage +from .exceptions import BadOptionUsage as BadOptionUsage +from .exceptions import BadParameter as BadParameter +from .exceptions import ClickException as ClickException +from .exceptions import FileError as FileError +from .exceptions import MissingParameter as MissingParameter +from .exceptions import NoSuchOption as NoSuchOption +from .exceptions import UsageError as UsageError +from .formatting import HelpFormatter as HelpFormatter +from .formatting import wrap_text as wrap_text +from .globals import get_current_context as get_current_context +from .parser import OptionParser as OptionParser +from .termui import clear as clear +from .termui import confirm as confirm +from .termui import echo_via_pager as echo_via_pager +from .termui import edit as edit +from .termui import getchar as getchar +from .termui import launch as launch +from .termui import pause as pause +from .termui import progressbar as progressbar +from .termui import prompt as prompt +from .termui import secho as secho +from .termui import style as style +from .termui import unstyle as unstyle +from .types import BOOL as BOOL +from .types import Choice as Choice +from .types import DateTime as DateTime +from .types import File as File +from .types import FLOAT as FLOAT +from .types import FloatRange as FloatRange +from .types import INT as INT +from .types import IntRange as IntRange +from .types import ParamType as ParamType +from .types import Path as Path +from .types import STRING as STRING +from .types import Tuple as Tuple +from .types import UNPROCESSED as UNPROCESSED +from .types import UUID as UUID +from .utils import echo as echo +from .utils import format_filename as format_filename +from .utils import get_app_dir as get_app_dir +from .utils import get_binary_stream as get_binary_stream +from .utils import get_text_stream as get_text_stream +from .utils import open_file as open_file + +__version__ = "8.1.3" diff --git a/zhdo.space/lib/python3.9/site-packages/click/__pycache__/__init__.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/click/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..81802ac8aed1b401a35db885b8833f9bda7cb13b GIT binary patch literal 2618 zcmc)MNmJWM6bEnv-fi|JtU-Yg!e+CDeK$+U0#tySs&`SfrN&m!R^4(Ka+uS6nK{k( z@pVq~73MVWJ+sXx7%2Y!b*t4aJ-01HYil-!KYvdCRzAqbVt-NNlx5Q$0 z3}SYZ-Rw4b&CuLLZb7#|3pzViB^pZy9w00ZoP^dJnf2hc+>#2!Qs!!UaYJpv=_Vf1Tw%^pFI!YKPS z+5m$+>b~*DV2o{`$6=iP#(nEezyy2DedkTWBzxR_?@hrJ`z?AJrr8td8JJ+w4{J4(zbk(7Uk9UPtf29(x15 z5Buy*^Z^{Ox6mahvA5kr?+A|AJLqFLX78d;;Do)0{s^1TsNrJ*C+b;?E%Mxjtz z8c|?);#OwwloL6A#jpa;6TWS@j*o*a<%E$oZfbtPxb|J=RvH1$q8?_~vxXB*YNIT) zw6j75H9Yg_LiR6CaY+#wb|AIk2N6v!jXNi*;(vQ%&16-)oxI%2Ep4s`pQsBDMik!f29QPynE1j7*!HWwK`L8uM za-L62o`(;kGZ#V$PexMVu(WtyHDx`m*lh*=jiWq4=a^W;#zKk8!|b`Lbi?QVZYr%A z3aw3BT7eQ#K$9n*PR#Q$ob=%`)7%cq-*Hqs`7TiQ^L%YTq|*OgdA}Sey1|YEVLw*t zT8oOrzBcS@+}>kP9(!KiW*cvxqhBrgcq^G>$CXD)@r8DLb+pD^@$!`XS#XJO+*8@I zJon=ntsk)f#{pHSQOL}l5~2BUd)*ZonO03Hd^^qOyUsTz!&NjFKVi92P@%B$TyDA- zX;lOBha<3@6&@9rwnKNG!bzge93p{bhx$oRqe`4{X;ma2hc(ZTegh~$;yk>gY&d`%pGIp4oRWRKlIMBjwZWp6n> zqt5iH|J2pkTUYlXpMD`Cy2j+?)wk2L6PoC%hM!zS?)vQF+j;5e^77~qoAK-GQ+|E8 z)b<;$ta*d$`?y!>3@WJzL(_JsVx811JHAl&rjC>p9(J}f%Ex`ERUh@fqUfg>pcteWq8O$ap?Hk}*+yCD`%8^duYrO4 z!VSv8)#?qkk|FOdHHHmH;@J!hJa zpMUd@nEFfyDE_%DR`H9q_`N3l;xB=^E&i<9K|zPYk}rwh`^AtS4oijgqIM!VheK}h pG)1$nuYMbp5AIaLGYo6|A+mK5l`lu{^#H3e*p#5vWfrz literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/click/__pycache__/_compat.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/click/__pycache__/_compat.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6be380c3b97e7a3fdaa92af0e2dbff796e633831 GIT binary patch literal 16057 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

    D9UyJ5Xy&wqbMIk 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 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/click/__pycache__/globals.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/click/__pycache__/globals.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d10c9bd66527dfb86a4457a18ac3ea283981438 GIT binary patch literal 2425 zcmah~-EJF26y8~{9mjG0+7yx$q(K4|qjp_^0AV2nidqODQ>Brr8X-dWAe zI*FC`qU|kj(2Mr6-0%)O#@=$(SKtQDne~RGL}H|!ou9L3zVppF-?HW9h6C;Q8;^&t z798hKoSbh}n0yV7{sTJha1uK`0&h2VCzW1>ID#B_%C|e!UX53{7cWfey*lhvo;tln z*l+N+d5tgd`g4~r^2W33Q_@?q>zkqp?`6KQ<=EY3xy!fS*jdJ%-V%5rdCHu=q8BDa;mj zWMagzxjS1o!v8TcLb3SgyDZk?7v-Uio7Z#{i^SwLB}}H006#4oj`7)nN25J=?mMqY z_Z4&sNmTW+`)jWq%86(nWGrbvkm|5K3%T@l$^vnI7)Qf)dSXJEeByu6)&S`im>jaP z(Cr|Og2VPWmP0`3rziQ;~rGFyXCxe9{?wwV?0wGxhLNf=Mf>!Z2Q#FpBc!U zr{t780h@;o_a2eQBxw}y+sZ{WHeZWY#M>j zAwyQ+;0r7k4EPP}W?#}Y)8S z>4DGy5QDpf47iw#-PS@*Ozs6tgL3q(=;T#xppx^IZ;VmVFf)bwys?{bacqyuo97R1 zxmH7RBL0;Tbyktrup*n#Ijb(&AXkV-s0(^k3Cyvo!SaPVMU_HFEmsg8_5a`ib!695L>NxXCLf| ziJU?Jm`p~dG!|0wKatiWSYeh7n8K$j8KJOwp0z%;M?N*;ms+12+?$pQSQEPikH+b-5}!s59IAoU>h z7JHe{MRCZHU9=eJC}v}jnBCDlvCrxUyB=tKLOlp!Ka&n#A$gbJ_P!nrg->R(PI g&tmZvmYCj#u1=b6jo7~8kqyry+ur8pT6LxR4~q0~(f|Me literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/click/__pycache__/parser.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/click/__pycache__/parser.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5537d32a2d005a70583692ac8b61dd9deef4e660 GIT binary patch literal 13568 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 L)Mux>slxvO?N|OD literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/click/__pycache__/shell_completion.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/click/__pycache__/shell_completion.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..36654aeba110ea1e8cc38b6c209121e514aade42 GIT binary patch literal 16729 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 OnVCh?em_4qx$-|6c7F~4 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/click/__pycache__/types.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/click/__pycache__/types.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0474e0ff2ce864270d71a73120fe93c0ed9fa53a GIT binary patch literal 32956 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 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/click/__pycache__/utils.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/click/__pycache__/utils.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a0301a3936e05bea7e657764912666228d4205f4 GIT binary patch literal 17575 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 P|BBT73kLXPZ65t!4HZc8 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/click/_compat.py b/zhdo.space/lib/python3.9/site-packages/click/_compat.py new file mode 100644 index 0000000..766d286 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/click/_compat.py @@ -0,0 +1,626 @@ +import codecs +import io +import os +import re +import sys +import typing as t +from weakref import WeakKeyDictionary + +CYGWIN = sys.platform.startswith("cygwin") +MSYS2 = sys.platform.startswith("win") and ("GCC" in sys.version) +# Determine local App Engine environment, per Google's own suggestion +APP_ENGINE = "APPENGINE_RUNTIME" in os.environ and "Development/" in os.environ.get( + "SERVER_SOFTWARE", "" +) +WIN = sys.platform.startswith("win") and not APP_ENGINE and not MSYS2 +auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None +_ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]") + + +def get_filesystem_encoding() -> str: + return sys.getfilesystemencoding() or sys.getdefaultencoding() + + +def _make_text_stream( + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if encoding is None: + encoding = get_best_encoding(stream) + if errors is None: + errors = "replace" + return _NonClosingTextIOWrapper( + stream, + encoding, + errors, + line_buffering=True, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def is_ascii_encoding(encoding: str) -> bool: + """Checks if a given encoding is ascii.""" + try: + return codecs.lookup(encoding).name == "ascii" + except LookupError: + return False + + +def get_best_encoding(stream: t.IO) -> str: + """Returns the default stream encoding if not found.""" + rv = getattr(stream, "encoding", None) or sys.getdefaultencoding() + if is_ascii_encoding(rv): + return "utf-8" + return rv + + +class _NonClosingTextIOWrapper(io.TextIOWrapper): + def __init__( + self, + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, + **extra: t.Any, + ) -> None: + self._stream = stream = t.cast( + t.BinaryIO, _FixupStream(stream, force_readable, force_writable) + ) + super().__init__(stream, encoding, errors, **extra) + + def __del__(self) -> None: + try: + self.detach() + except Exception: + pass + + def isatty(self) -> bool: + # https://bitbucket.org/pypy/pypy/issue/1803 + return self._stream.isatty() + + +class _FixupStream: + """The new io interface needs more from streams than streams + traditionally implement. As such, this fix-up code is necessary in + some circumstances. + + The forcing of readable and writable flags are there because some tools + put badly patched objects on sys (one such offender are certain version + of jupyter notebook). + """ + + def __init__( + self, + stream: t.BinaryIO, + force_readable: bool = False, + force_writable: bool = False, + ): + self._stream = stream + self._force_readable = force_readable + self._force_writable = force_writable + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._stream, name) + + def read1(self, size: int) -> bytes: + f = getattr(self._stream, "read1", None) + + if f is not None: + return t.cast(bytes, f(size)) + + return self._stream.read(size) + + def readable(self) -> bool: + if self._force_readable: + return True + x = getattr(self._stream, "readable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.read(0) + except Exception: + return False + return True + + def writable(self) -> bool: + if self._force_writable: + return True + x = getattr(self._stream, "writable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.write("") # type: ignore + except Exception: + try: + self._stream.write(b"") + except Exception: + return False + return True + + def seekable(self) -> bool: + x = getattr(self._stream, "seekable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.seek(self._stream.tell()) + except Exception: + return False + return True + + +def _is_binary_reader(stream: t.IO, default: bool = False) -> bool: + try: + return isinstance(stream.read(0), bytes) + except Exception: + return default + # This happens in some cases where the stream was already + # closed. In this case, we assume the default. + + +def _is_binary_writer(stream: t.IO, default: bool = False) -> bool: + try: + stream.write(b"") + except Exception: + try: + stream.write("") + return False + except Exception: + pass + return default + return True + + +def _find_binary_reader(stream: t.IO) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_reader(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_reader(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _find_binary_writer(stream: t.IO) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_writer(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_writer(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _stream_is_misconfigured(stream: t.TextIO) -> bool: + """A stream is misconfigured if its encoding is ASCII.""" + # If the stream does not have an encoding set, we assume it's set + # to ASCII. This appears to happen in certain unittest + # environments. It's not quite clear what the correct behavior is + # but this at least will force Click to recover somehow. + return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii") + + +def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool: + """A stream attribute is compatible if it is equal to the + desired value or the desired value is unset and the attribute + has a value. + """ + stream_value = getattr(stream, attr, None) + return stream_value == value or (value is None and stream_value is not None) + + +def _is_compatible_text_stream( + stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> bool: + """Check if a stream's encoding and errors attributes are + compatible with the desired values. + """ + return _is_compat_stream_attr( + stream, "encoding", encoding + ) and _is_compat_stream_attr(stream, "errors", errors) + + +def _force_correct_text_stream( + text_stream: t.IO, + encoding: t.Optional[str], + errors: t.Optional[str], + is_binary: t.Callable[[t.IO, bool], bool], + find_binary: t.Callable[[t.IO], t.Optional[t.BinaryIO]], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if is_binary(text_stream, False): + binary_reader = t.cast(t.BinaryIO, text_stream) + else: + text_stream = t.cast(t.TextIO, text_stream) + # If the stream looks compatible, and won't default to a + # misconfigured ascii encoding, return it as-is. + if _is_compatible_text_stream(text_stream, encoding, errors) and not ( + encoding is None and _stream_is_misconfigured(text_stream) + ): + return text_stream + + # Otherwise, get the underlying binary reader. + possible_binary_reader = find_binary(text_stream) + + # If that's not possible, silently use the original reader + # and get mojibake instead of exceptions. + if possible_binary_reader is None: + return text_stream + + binary_reader = possible_binary_reader + + # Default errors to replace instead of strict in order to get + # something that works. + if errors is None: + errors = "replace" + + # Wrap the binary stream in a text stream with the correct + # encoding parameters. + return _make_text_stream( + binary_reader, + encoding, + errors, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def _force_correct_text_reader( + text_reader: t.IO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_reader, + encoding, + errors, + _is_binary_reader, + _find_binary_reader, + force_readable=force_readable, + ) + + +def _force_correct_text_writer( + text_writer: t.IO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_writable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_writer, + encoding, + errors, + _is_binary_writer, + _find_binary_writer, + force_writable=force_writable, + ) + + +def get_binary_stdin() -> t.BinaryIO: + reader = _find_binary_reader(sys.stdin) + if reader is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdin.") + return reader + + +def get_binary_stdout() -> t.BinaryIO: + writer = _find_binary_writer(sys.stdout) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdout.") + return writer + + +def get_binary_stderr() -> t.BinaryIO: + writer = _find_binary_writer(sys.stderr) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stderr.") + return writer + + +def get_text_stdin( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True) + + +def get_text_stdout( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True) + + +def get_text_stderr( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True) + + +def _wrap_io_open( + file: t.Union[str, os.PathLike, int], + mode: str, + encoding: t.Optional[str], + errors: t.Optional[str], +) -> t.IO: + """Handles not passing ``encoding`` and ``errors`` in binary mode.""" + if "b" in mode: + return open(file, mode) + + return open(file, mode, encoding=encoding, errors=errors) + + +def open_stream( + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, +) -> t.Tuple[t.IO, bool]: + binary = "b" in mode + + # Standard streams first. These are simple because they ignore the + # atomic flag. Use fsdecode to handle Path("-"). + if os.fsdecode(filename) == "-": + if any(m in mode for m in ["w", "a", "x"]): + if binary: + return get_binary_stdout(), False + return get_text_stdout(encoding=encoding, errors=errors), False + if binary: + return get_binary_stdin(), False + return get_text_stdin(encoding=encoding, errors=errors), False + + # Non-atomic writes directly go out through the regular open functions. + if not atomic: + return _wrap_io_open(filename, mode, encoding, errors), True + + # Some usability stuff for atomic writes + if "a" in mode: + raise ValueError( + "Appending to an existing file is not supported, because that" + " would involve an expensive `copy`-operation to a temporary" + " file. Open the file in normal `w`-mode and copy explicitly" + " if that's what you're after." + ) + if "x" in mode: + raise ValueError("Use the `overwrite`-parameter instead.") + if "w" not in mode: + raise ValueError("Atomic writes only make sense with `w`-mode.") + + # Atomic writes are more complicated. They work by opening a file + # as a proxy in the same folder and then using the fdopen + # functionality to wrap it in a Python file. Then we wrap it in an + # atomic file that moves the file over on close. + import errno + import random + + try: + perm: t.Optional[int] = os.stat(filename).st_mode + except OSError: + perm = None + + flags = os.O_RDWR | os.O_CREAT | os.O_EXCL + + if binary: + flags |= getattr(os, "O_BINARY", 0) + + while True: + tmp_filename = os.path.join( + os.path.dirname(filename), + f".__atomic-write{random.randrange(1 << 32):08x}", + ) + try: + fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm) + break + except OSError as e: + if e.errno == errno.EEXIST or ( + os.name == "nt" + and e.errno == errno.EACCES + and os.path.isdir(e.filename) + and os.access(e.filename, os.W_OK) + ): + continue + raise + + if perm is not None: + os.chmod(tmp_filename, perm) # in case perm includes bits in umask + + f = _wrap_io_open(fd, mode, encoding, errors) + af = _AtomicFile(f, tmp_filename, os.path.realpath(filename)) + return t.cast(t.IO, af), True + + +class _AtomicFile: + def __init__(self, f: t.IO, tmp_filename: str, real_filename: str) -> None: + self._f = f + self._tmp_filename = tmp_filename + self._real_filename = real_filename + self.closed = False + + @property + def name(self) -> str: + return self._real_filename + + def close(self, delete: bool = False) -> None: + if self.closed: + return + self._f.close() + os.replace(self._tmp_filename, self._real_filename) + self.closed = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._f, name) + + def __enter__(self) -> "_AtomicFile": + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self.close(delete=exc_type is not None) + + def __repr__(self) -> str: + return repr(self._f) + + +def strip_ansi(value: str) -> str: + return _ansi_re.sub("", value) + + +def _is_jupyter_kernel_output(stream: t.IO) -> bool: + while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): + stream = stream._stream + + return stream.__class__.__module__.startswith("ipykernel.") + + +def should_strip_ansi( + stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None +) -> bool: + if color is None: + if stream is None: + stream = sys.stdin + return not isatty(stream) and not _is_jupyter_kernel_output(stream) + return not color + + +# On Windows, wrap the output streams with colorama to support ANSI +# color codes. +# NOTE: double check is needed so mypy does not analyze this on Linux +if sys.platform.startswith("win") and WIN: + from ._winconsole import _get_windows_console_stream + + def _get_argv_encoding() -> str: + import locale + + return locale.getpreferredencoding() + + _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def auto_wrap_for_ansi( + stream: t.TextIO, color: t.Optional[bool] = None + ) -> t.TextIO: + """Support ANSI color and style codes on Windows by wrapping a + stream with colorama. + """ + try: + cached = _ansi_stream_wrappers.get(stream) + except Exception: + cached = None + + if cached is not None: + return cached + + import colorama + + strip = should_strip_ansi(stream, color) + ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) + rv = t.cast(t.TextIO, ansi_wrapper.stream) + _write = rv.write + + def _safe_write(s): + try: + return _write(s) + except BaseException: + ansi_wrapper.reset_all() + raise + + rv.write = _safe_write + + try: + _ansi_stream_wrappers[stream] = rv + except Exception: + pass + + return rv + +else: + + def _get_argv_encoding() -> str: + return getattr(sys.stdin, "encoding", None) or get_filesystem_encoding() + + def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] + ) -> t.Optional[t.TextIO]: + return None + + +def term_len(x: str) -> int: + return len(strip_ansi(x)) + + +def isatty(stream: t.IO) -> bool: + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func( + src_func: t.Callable[[], t.TextIO], wrapper_func: t.Callable[[], t.TextIO] +) -> t.Callable[[], t.TextIO]: + cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def func() -> t.TextIO: + stream = src_func() + try: + rv = cache.get(stream) + except Exception: + rv = None + if rv is not None: + return rv + rv = wrapper_func() + try: + cache[stream] = rv + except Exception: + pass + return rv + + return func + + +_default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin) +_default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout) +_default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr) + + +binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = { + "stdin": get_binary_stdin, + "stdout": get_binary_stdout, + "stderr": get_binary_stderr, +} + +text_streams: t.Mapping[ + str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO] +] = { + "stdin": get_text_stdin, + "stdout": get_text_stdout, + "stderr": get_text_stderr, +} diff --git a/zhdo.space/lib/python3.9/site-packages/click/_termui_impl.py b/zhdo.space/lib/python3.9/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..4b979bc --- /dev/null +++ b/zhdo.space/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 + + fd, filename = tempfile.mkstemp() + # TODO: This never terminates if the passed generator never terminates. + text = "".join(generator) + if not color: + text = strip_ansi(text) + encoding = get_best_encoding(sys.stdout) + with open_stream(filename, "wb")[0] as f: + f.write(text.encode(encoding)) + try: + os.system(f'{cmd} "{filename}"') + finally: + os.close(fd) + os.unlink(filename) + + +def _nullpager( + stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool] +) -> None: + """Simply print unformatted text. This is the ultimate fallback.""" + for text in generator: + if not color: + text = strip_ansi(text) + stream.write(text) + + +class Editor: + def __init__( + self, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + ) -> None: + self.editor = editor + self.env = env + self.require_save = require_save + self.extension = extension + + def get_editor(self) -> str: + if self.editor is not None: + return self.editor + for key in "VISUAL", "EDITOR": + rv = os.environ.get(key) + if rv: + return rv + if WIN: + return "notepad" + for editor in "sensible-editor", "vim", "nano": + if os.system(f"which {editor} >/dev/null 2>&1") == 0: + return editor + return "vi" + + def edit_file(self, filename: str) -> None: + import subprocess + + editor = self.get_editor() + environ: t.Optional[t.Dict[str, str]] = None + + if self.env: + environ = os.environ.copy() + environ.update(self.env) + + try: + c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True) + exit_code = c.wait() + if exit_code != 0: + raise ClickException( + _("{editor}: Editing failed").format(editor=editor) + ) + except OSError as e: + raise ClickException( + _("{editor}: Editing failed: {e}").format(editor=editor, e=e) + ) from e + + def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]: + import tempfile + + if not text: + data = b"" + elif isinstance(text, (bytes, bytearray)): + data = text + else: + if text and not text.endswith("\n"): + text += "\n" + + if WIN: + data = text.replace("\n", "\r\n").encode("utf-8-sig") + else: + data = text.encode("utf-8") + + fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension) + f: t.BinaryIO + + try: + with os.fdopen(fd, "wb") as f: + f.write(data) + + # If the filesystem resolution is 1 second, like Mac OS + # 10.12 Extended, or 2 seconds, like FAT32, and the editor + # closes very fast, require_save can fail. Set the modified + # time to be 2 seconds in the past to work around this. + os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2)) + # Depending on the resolution, the exact value might not be + # recorded, so get the new recorded value. + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save and os.path.getmtime(name) == timestamp: + return None + + with open(name, "rb") as f: + rv = f.read() + + if isinstance(text, (bytes, bytearray)): + return rv + + return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore + finally: + os.unlink(name) + + +def open_url(url: str, wait: bool = False, locate: bool = False) -> int: + import subprocess + + def _unquote_file(url: str) -> str: + from urllib.parse import unquote + + if url.startswith("file://"): + url = unquote(url[7:]) + + return url + + if sys.platform == "darwin": + args = ["open"] + if wait: + args.append("-W") + if locate: + args.append("-R") + args.append(_unquote_file(url)) + null = open("/dev/null", "w") + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url.replace('"', "")) + args = f'explorer /select,"{url}"' + else: + url = url.replace('"', "") + wait_str = "/WAIT" if wait else "" + args = f'start {wait_str} "" "{url}"' + return os.system(args) + elif CYGWIN: + if locate: + url = os.path.dirname(_unquote_file(url).replace('"', "")) + args = f'cygstart "{url}"' + else: + url = url.replace('"', "") + wait_str = "-w" if wait else "" + args = f'cygstart {wait_str} "{url}"' + return os.system(args) + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or "." + else: + url = _unquote_file(url) + c = subprocess.Popen(["xdg-open", url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(("http://", "https://")) and not locate and not wait: + import webbrowser + + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]: + if ch == "\x03": + raise KeyboardInterrupt() + + if ch == "\x04" and not WIN: # Unix-like, Ctrl+D + raise EOFError() + + if ch == "\x1a" and WIN: # Windows, Ctrl+Z + raise EOFError() + + return None + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + yield -1 + + def getchar(echo: bool) -> str: + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + func: t.Callable[[], str] + + if echo: + func = msvcrt.getwche # type: ignore + else: + func = msvcrt.getwch # type: ignore + + rv = func() + + if rv in ("\x00", "\xe0"): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + + _translate_ch_to_exc(rv) + return rv + +else: + import tty + import termios + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + f: t.Optional[t.TextIO] + fd: int + + if not isatty(sys.stdin): + f = open("/dev/tty") + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + + try: + old_settings = termios.tcgetattr(fd) + + try: + tty.setraw(fd) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo: bool) -> str: + with raw_terminal() as fd: + ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace") + + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + + _translate_ch_to_exc(ch) + return ch diff --git a/zhdo.space/lib/python3.9/site-packages/click/_textwrap.py b/zhdo.space/lib/python3.9/site-packages/click/_textwrap.py new file mode 100644 index 0000000..b47dcbd --- /dev/null +++ b/zhdo.space/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/zhdo.space/lib/python3.9/site-packages/click/_winconsole.py b/zhdo.space/lib/python3.9/site-packages/click/_winconsole.py new file mode 100644 index 0000000..6b20df3 --- /dev/null +++ b/zhdo.space/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/zhdo.space/lib/python3.9/site-packages/click/core.py b/zhdo.space/lib/python3.9/site-packages/click/core.py new file mode 100644 index 0000000..5abfb0f --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/click/core.py @@ -0,0 +1,2998 @@ +import enum +import errno +import inspect +import os +import sys +import typing as t +from collections import abc +from contextlib import contextmanager +from contextlib import ExitStack +from functools import partial +from functools import update_wrapper +from gettext import gettext as _ +from gettext import ngettext +from itertools import repeat + +from . import types +from .exceptions import Abort +from .exceptions import BadParameter +from .exceptions import ClickException +from .exceptions import Exit +from .exceptions import MissingParameter +from .exceptions import UsageError +from .formatting import HelpFormatter +from .formatting import join_options +from .globals import pop_context +from .globals import push_context +from .parser import _flag_needs_value +from .parser import OptionParser +from .parser import split_opt +from .termui import confirm +from .termui import prompt +from .termui import style +from .utils import _detect_program_name +from .utils import _expand_args +from .utils import echo +from .utils import make_default_short_help +from .utils import make_str +from .utils import PacifyFlushWrapper + +if t.TYPE_CHECKING: + import typing_extensions as te + from .shell_completion import CompletionItem + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +V = t.TypeVar("V") + + +def _complete_visible_commands( + ctx: "Context", incomplete: str +) -> t.Iterator[t.Tuple[str, "Command"]]: + """List all the subcommands of a group that start with the + incomplete value and aren't hidden. + + :param ctx: Invocation context for the group. + :param incomplete: Value being completed. May be empty. + """ + multi = t.cast(MultiCommand, ctx.command) + + for name in multi.list_commands(ctx): + if name.startswith(incomplete): + command = multi.get_command(ctx, name) + + if command is not None and not command.hidden: + yield name, command + + +def _check_multicommand( + base_command: "MultiCommand", cmd_name: str, cmd: "Command", register: bool = False +) -> None: + if not base_command.chain or not isinstance(cmd, MultiCommand): + return + if register: + hint = ( + "It is not possible to add multi commands as children to" + " another multi command that is in chain mode." + ) + else: + hint = ( + "Found a multi command as subcommand to a multi command" + " that is in chain mode. This is not supported." + ) + raise RuntimeError( + f"{hint}. Command {base_command.name!r} is set to chain and" + f" {cmd_name!r} was added as a subcommand but it in itself is a" + f" multi command. ({cmd_name!r} is a {type(cmd).__name__}" + f" within a chained {type(base_command).__name__} named" + f" {base_command.name!r})." + ) + + +def batch(iterable: t.Iterable[V], batch_size: int) -> t.List[t.Tuple[V, ...]]: + return list(zip(*repeat(iter(iterable), batch_size))) + + +@contextmanager +def augment_usage_errors( + ctx: "Context", param: t.Optional["Parameter"] = None +) -> t.Iterator[None]: + """Context manager that attaches extra information to exceptions.""" + try: + yield + except BadParameter as e: + if e.ctx is None: + e.ctx = ctx + if param is not None and e.param is None: + e.param = param + raise + except UsageError as e: + if e.ctx is None: + e.ctx = ctx + raise + + +def iter_params_for_processing( + invocation_order: t.Sequence["Parameter"], + declaration_order: t.Sequence["Parameter"], +) -> t.List["Parameter"]: + """Given a sequence of parameters in the order as should be considered + for processing and an iterable of parameters that exist, this returns + a list in the correct order as they should be processed. + """ + + def sort_key(item: "Parameter") -> t.Tuple[bool, float]: + try: + idx: float = invocation_order.index(item) + except ValueError: + idx = float("inf") + + return not item.is_eager, idx + + return sorted(declaration_order, key=sort_key) + + +class ParameterSource(enum.Enum): + """This is an :class:`~enum.Enum` that indicates the source of a + parameter's value. + + Use :meth:`click.Context.get_parameter_source` to get the + source for a parameter by name. + + .. versionchanged:: 8.0 + Use :class:`~enum.Enum` and drop the ``validate`` method. + + .. versionchanged:: 8.0 + Added the ``PROMPT`` value. + """ + + COMMANDLINE = enum.auto() + """The value was provided by the command line args.""" + ENVIRONMENT = enum.auto() + """The value was provided with an environment variable.""" + DEFAULT = enum.auto() + """Used the default specified by the parameter.""" + DEFAULT_MAP = enum.auto() + """Used a default provided by :attr:`Context.default_map`.""" + PROMPT = enum.auto() + """Used a prompt to confirm a default or provide a value.""" + + +class Context: + """The context is a special internal object that holds state relevant + for the script execution at every single level. It's normally invisible + to commands unless they opt-in to getting access to it. + + The context is useful as it can pass internal objects around and can + control special execution features such as reading data from + environment variables. + + A context can be used as context manager in which case it will call + :meth:`close` on teardown. + + :param command: the command class for this context. + :param parent: the parent context. + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it is usually + the name of the script, for commands below it it's + the name of the script. + :param obj: an arbitrary object of user data. + :param auto_envvar_prefix: the prefix to use for automatic environment + variables. If this is `None` then reading + from environment variables is disabled. This + does not affect manually set environment + variables which are always read. + :param default_map: a dictionary (like object) with default values + for parameters. + :param terminal_width: the width of the terminal. The default is + inherit from parent context. If no context + defines the terminal width then auto + detection will be applied. + :param max_content_width: the maximum width for content rendered by + Click (this currently only affects help + pages). This defaults to 80 characters if + not overridden. In other words: even if the + terminal is larger than that, Click will not + format things wider than 80 characters by + default. In addition to that, formatters might + add some safety mapping on the right. + :param resilient_parsing: if this flag is enabled then Click will + parse without any interactivity or callback + invocation. Default values will also be + ignored. This is useful for implementing + things such as completion support. + :param allow_extra_args: if this is set to `True` then extra arguments + at the end will not raise an error and will be + kept on the context. The default is to inherit + from the command. + :param allow_interspersed_args: if this is set to `False` then options + and arguments cannot be mixed. The + default is to inherit from the command. + :param ignore_unknown_options: instructs click to ignore options it does + not know and keeps them for later + processing. + :param help_option_names: optionally a list of strings that define how + the default help parameter is named. The + default is ``['--help']``. + :param token_normalize_func: an optional function that is used to + normalize tokens (options, choices, + etc.). This for instance can be used to + implement case insensitive behavior. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are used in texts that Click prints which is by + default not the case. This for instance would affect + help output. + :param show_default: Show the default value for commands. If this + value is not set, it defaults to the value from the parent + context. ``Command.show_default`` overrides this default for the + specific command. + + .. versionchanged:: 8.1 + The ``show_default`` parameter is overridden by + ``Command.show_default``, instead of the other way around. + + .. versionchanged:: 8.0 + The ``show_default`` parameter defaults to the value from the + parent context. + + .. versionchanged:: 7.1 + Added the ``show_default`` parameter. + + .. versionchanged:: 4.0 + Added the ``color``, ``ignore_unknown_options``, and + ``max_content_width`` parameters. + + .. versionchanged:: 3.0 + Added the ``allow_extra_args`` and ``allow_interspersed_args`` + parameters. + + .. versionchanged:: 2.0 + Added the ``resilient_parsing``, ``help_option_names``, and + ``token_normalize_func`` parameters. + """ + + #: The formatter class to create with :meth:`make_formatter`. + #: + #: .. versionadded:: 8.0 + formatter_class: t.Type["HelpFormatter"] = HelpFormatter + + def __init__( + self, + command: "Command", + parent: t.Optional["Context"] = None, + info_name: t.Optional[str] = None, + obj: t.Optional[t.Any] = None, + auto_envvar_prefix: t.Optional[str] = None, + default_map: t.Optional[t.Dict[str, t.Any]] = None, + terminal_width: t.Optional[int] = None, + max_content_width: t.Optional[int] = None, + resilient_parsing: bool = False, + allow_extra_args: t.Optional[bool] = None, + allow_interspersed_args: t.Optional[bool] = None, + ignore_unknown_options: t.Optional[bool] = None, + help_option_names: t.Optional[t.List[str]] = None, + token_normalize_func: t.Optional[t.Callable[[str], str]] = None, + color: t.Optional[bool] = None, + show_default: t.Optional[bool] = None, + ) -> None: + #: the parent context or `None` if none exists. + self.parent = parent + #: the :class:`Command` for this context. + self.command = command + #: the descriptive information name + self.info_name = info_name + #: Map of parameter names to their parsed values. Parameters + #: with ``expose_value=False`` are not stored. + self.params: t.Dict[str, t.Any] = {} + #: the leftover arguments. + self.args: t.List[str] = [] + #: protected arguments. These are arguments that are prepended + #: to `args` when certain parsing scenarios are encountered but + #: must be never propagated to another arguments. This is used + #: to implement nested parsing. + self.protected_args: t.List[str] = [] + #: the collected prefixes of the command's options. + self._opt_prefixes: t.Set[str] = set(parent._opt_prefixes) if parent else set() + + if obj is None and parent is not None: + obj = parent.obj + + #: the user object stored. + self.obj: t.Any = obj + self._meta: t.Dict[str, t.Any] = getattr(parent, "meta", {}) + + #: A dictionary (-like object) with defaults for parameters. + if ( + default_map is None + and info_name is not None + and parent is not None + and parent.default_map is not None + ): + default_map = parent.default_map.get(info_name) + + self.default_map: t.Optional[t.Dict[str, t.Any]] = default_map + + #: This flag indicates if a subcommand is going to be executed. A + #: group callback can use this information to figure out if it's + #: being executed directly or because the execution flow passes + #: onwards to a subcommand. By default it's None, but it can be + #: the name of the subcommand to execute. + #: + #: If chaining is enabled this will be set to ``'*'`` in case + #: any commands are executed. It is however not possible to + #: figure out which ones. If you require this knowledge you + #: should use a :func:`result_callback`. + self.invoked_subcommand: t.Optional[str] = None + + if terminal_width is None and parent is not None: + terminal_width = parent.terminal_width + + #: The width of the terminal (None is autodetection). + self.terminal_width: t.Optional[int] = terminal_width + + if max_content_width is None and parent is not None: + max_content_width = parent.max_content_width + + #: The maximum width of formatted content (None implies a sensible + #: default which is 80 for most things). + self.max_content_width: t.Optional[int] = max_content_width + + if allow_extra_args is None: + allow_extra_args = command.allow_extra_args + + #: Indicates if the context allows extra args or if it should + #: fail on parsing. + #: + #: .. versionadded:: 3.0 + self.allow_extra_args = allow_extra_args + + if allow_interspersed_args is None: + allow_interspersed_args = command.allow_interspersed_args + + #: Indicates if the context allows mixing of arguments and + #: options or not. + #: + #: .. versionadded:: 3.0 + self.allow_interspersed_args: bool = allow_interspersed_args + + if ignore_unknown_options is None: + ignore_unknown_options = command.ignore_unknown_options + + #: Instructs click to ignore options that a command does not + #: understand and will store it on the context for later + #: processing. This is primarily useful for situations where you + #: want to call into external programs. Generally this pattern is + #: strongly discouraged because it's not possibly to losslessly + #: forward all arguments. + #: + #: .. versionadded:: 4.0 + self.ignore_unknown_options: bool = ignore_unknown_options + + if help_option_names is None: + if parent is not None: + help_option_names = parent.help_option_names + else: + help_option_names = ["--help"] + + #: The names for the help options. + self.help_option_names: t.List[str] = help_option_names + + if token_normalize_func is None and parent is not None: + token_normalize_func = parent.token_normalize_func + + #: An optional normalization function for tokens. This is + #: options, choices, commands etc. + self.token_normalize_func: t.Optional[ + t.Callable[[str], str] + ] = token_normalize_func + + #: Indicates if resilient parsing is enabled. In that case Click + #: will do its best to not cause any failures and default values + #: will be ignored. Useful for completion. + self.resilient_parsing: bool = resilient_parsing + + # If there is no envvar prefix yet, but the parent has one and + # the command on this level has a name, we can expand the envvar + # prefix automatically. + if auto_envvar_prefix is None: + if ( + parent is not None + and parent.auto_envvar_prefix is not None + and self.info_name is not None + ): + auto_envvar_prefix = ( + f"{parent.auto_envvar_prefix}_{self.info_name.upper()}" + ) + else: + auto_envvar_prefix = auto_envvar_prefix.upper() + + if auto_envvar_prefix is not None: + auto_envvar_prefix = auto_envvar_prefix.replace("-", "_") + + self.auto_envvar_prefix: t.Optional[str] = auto_envvar_prefix + + if color is None and parent is not None: + color = parent.color + + #: Controls if styling output is wanted or not. + self.color: t.Optional[bool] = color + + if show_default is None and parent is not None: + show_default = parent.show_default + + #: Show option default values when formatting help text. + self.show_default: t.Optional[bool] = show_default + + self._close_callbacks: t.List[t.Callable[[], t.Any]] = [] + self._depth = 0 + self._parameter_source: t.Dict[str, ParameterSource] = {} + self._exit_stack = ExitStack() + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire CLI + structure. + + .. code-block:: python + + with Context(cli) as ctx: + info = ctx.to_info_dict() + + .. versionadded:: 8.0 + """ + return { + "command": self.command.to_info_dict(self), + "info_name": self.info_name, + "allow_extra_args": self.allow_extra_args, + "allow_interspersed_args": self.allow_interspersed_args, + "ignore_unknown_options": self.ignore_unknown_options, + "auto_envvar_prefix": self.auto_envvar_prefix, + } + + def __enter__(self) -> "Context": + self._depth += 1 + push_context(self) + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self._depth -= 1 + if self._depth == 0: + self.close() + pop_context() + + @contextmanager + def scope(self, cleanup: bool = True) -> t.Iterator["Context"]: + """This helper method can be used with the context object to promote + it to the current thread local (see :func:`get_current_context`). + The default behavior of this is to invoke the cleanup functions which + can be disabled by setting `cleanup` to `False`. The cleanup + functions are typically used for things such as closing file handles. + + If the cleanup is intended the context object can also be directly + used as a context manager. + + Example usage:: + + with ctx.scope(): + assert get_current_context() is ctx + + This is equivalent:: + + with ctx: + assert get_current_context() is ctx + + .. versionadded:: 5.0 + + :param cleanup: controls if the cleanup functions should be run or + not. The default is to run these functions. In + some situations the context only wants to be + temporarily pushed in which case this can be disabled. + Nested pushes automatically defer the cleanup. + """ + if not cleanup: + self._depth += 1 + try: + with self as rv: + yield rv + finally: + if not cleanup: + self._depth -= 1 + + @property + def meta(self) -> t.Dict[str, t.Any]: + """This is a dictionary which is shared with all the contexts + that are nested. It exists so that click utilities can store some + state here if they need to. It is however the responsibility of + that code to manage this dictionary well. + + The keys are supposed to be unique dotted strings. For instance + module paths are a good choice for it. What is stored in there is + irrelevant for the operation of click. However what is important is + that code that places data here adheres to the general semantics of + the system. + + Example usage:: + + LANG_KEY = f'{__name__}.lang' + + def set_language(value): + ctx = get_current_context() + ctx.meta[LANG_KEY] = value + + def get_language(): + return get_current_context().meta.get(LANG_KEY, 'en_US') + + .. versionadded:: 5.0 + """ + return self._meta + + def make_formatter(self) -> HelpFormatter: + """Creates the :class:`~click.HelpFormatter` for the help and + usage output. + + To quickly customize the formatter class used without overriding + this method, set the :attr:`formatter_class` attribute. + + .. versionchanged:: 8.0 + Added the :attr:`formatter_class` attribute. + """ + return self.formatter_class( + width=self.terminal_width, max_width=self.max_content_width + ) + + def with_resource(self, context_manager: t.ContextManager[V]) -> V: + """Register a resource as if it were used in a ``with`` + statement. The resource will be cleaned up when the context is + popped. + + Uses :meth:`contextlib.ExitStack.enter_context`. It calls the + resource's ``__enter__()`` method and returns the result. When + the context is popped, it closes the stack, which calls the + resource's ``__exit__()`` method. + + To register a cleanup function for something that isn't a + context manager, use :meth:`call_on_close`. Or use something + from :mod:`contextlib` to turn it into a context manager first. + + .. code-block:: python + + @click.group() + @click.option("--name") + @click.pass_context + def cli(ctx): + ctx.obj = ctx.with_resource(connect_db(name)) + + :param context_manager: The context manager to enter. + :return: Whatever ``context_manager.__enter__()`` returns. + + .. versionadded:: 8.0 + """ + return self._exit_stack.enter_context(context_manager) + + def call_on_close(self, f: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]: + """Register a function to be called when the context tears down. + + This can be used to close resources opened during the script + execution. Resources that support Python's context manager + protocol which would be used in a ``with`` statement should be + registered with :meth:`with_resource` instead. + + :param f: The function to execute on teardown. + """ + return self._exit_stack.callback(f) + + def close(self) -> None: + """Invoke all close callbacks registered with + :meth:`call_on_close`, and exit all context managers entered + with :meth:`with_resource`. + """ + self._exit_stack.close() + # In case the context is reused, create a new exit stack. + self._exit_stack = ExitStack() + + @property + def command_path(self) -> str: + """The computed command path. This is used for the ``usage`` + information on the help page. It's automatically created by + combining the info names of the chain of contexts to the root. + """ + rv = "" + if self.info_name is not None: + rv = self.info_name + if self.parent is not None: + parent_command_path = [self.parent.command_path] + + if isinstance(self.parent.command, Command): + for param in self.parent.command.get_params(self): + parent_command_path.extend(param.get_usage_pieces(self)) + + rv = f"{' '.join(parent_command_path)} {rv}" + return rv.lstrip() + + def find_root(self) -> "Context": + """Finds the outermost context.""" + node = self + while node.parent is not None: + node = node.parent + return node + + def find_object(self, object_type: t.Type[V]) -> t.Optional[V]: + """Finds the closest object of a given type.""" + node: t.Optional["Context"] = self + + while node is not None: + if isinstance(node.obj, object_type): + return node.obj + + node = node.parent + + return None + + def ensure_object(self, object_type: t.Type[V]) -> V: + """Like :meth:`find_object` but sets the innermost object to a + new instance of `object_type` if it does not exist. + """ + rv = self.find_object(object_type) + if rv is None: + self.obj = rv = object_type() + return rv + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[False]" = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def lookup_default(self, name: str, call: bool = True) -> t.Optional[t.Any]: + """Get the default for a parameter from :attr:`default_map`. + + :param name: Name of the parameter. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + if self.default_map is not None: + value = self.default_map.get(name) + + if call and callable(value): + return value() + + return value + + return None + + def fail(self, message: str) -> "te.NoReturn": + """Aborts the execution of the program with a specific error + message. + + :param message: the error message to fail with. + """ + raise UsageError(message, self) + + def abort(self) -> "te.NoReturn": + """Aborts the script.""" + raise Abort() + + def exit(self, code: int = 0) -> "te.NoReturn": + """Exits the application with a given exit code.""" + raise Exit(code) + + def get_usage(self) -> str: + """Helper method to get formatted usage string for the current + context and command. + """ + return self.command.get_usage(self) + + def get_help(self) -> str: + """Helper method to get formatted help page for the current + context and command. + """ + return self.command.get_help(self) + + def _make_sub_context(self, command: "Command") -> "Context": + """Create a new context of the same type as this context, but + for a new command. + + :meta private: + """ + return type(self)(command, info_name=command.name, parent=self) + + def invoke( + __self, # noqa: B902 + __callback: t.Union["Command", t.Callable[..., t.Any]], + *args: t.Any, + **kwargs: t.Any, + ) -> t.Any: + """Invokes a command callback in exactly the way it expects. There + are two ways to invoke this method: + + 1. the first argument can be a callback and all other arguments and + keyword arguments are forwarded directly to the function. + 2. the first argument is a click command object. In that case all + arguments are forwarded as well but proper click parameters + (options and click arguments) must be keyword arguments and Click + will fill in defaults. + + Note that before Click 3.2 keyword arguments were not properly filled + in against the intention of this code and no context was created. For + more information about this change and why it was done in a bugfix + release see :ref:`upgrade-to-3.2`. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if :meth:`forward` is called at multiple levels. + """ + if isinstance(__callback, Command): + other_cmd = __callback + + if other_cmd.callback is None: + raise TypeError( + "The given command does not have a callback that can be invoked." + ) + else: + __callback = other_cmd.callback + + ctx = __self._make_sub_context(other_cmd) + + for param in other_cmd.params: + if param.name not in kwargs and param.expose_value: + kwargs[param.name] = param.type_cast_value( # type: ignore + ctx, param.get_default(ctx) + ) + + # Track all kwargs as params, so that forward() will pass + # them on in subsequent calls. + ctx.params.update(kwargs) + else: + ctx = __self + + with augment_usage_errors(__self): + with ctx: + return __callback(*args, **kwargs) + + def forward( + __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any # noqa: B902 + ) -> t.Any: + """Similar to :meth:`invoke` but fills in default keyword + arguments from the current context if the other command expects + it. This cannot invoke callbacks directly, only other commands. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if ``forward`` is called at multiple levels. + """ + # Can only forward to other commands, not direct callbacks. + if not isinstance(__cmd, Command): + raise TypeError("Callback is not a command.") + + for param in __self.params: + if param not in kwargs: + kwargs[param] = __self.params[param] + + return __self.invoke(__cmd, *args, **kwargs) + + def set_parameter_source(self, name: str, source: ParameterSource) -> None: + """Set the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + :param name: The name of the parameter. + :param source: A member of :class:`~click.core.ParameterSource`. + """ + self._parameter_source[name] = source + + def get_parameter_source(self, name: str) -> t.Optional[ParameterSource]: + """Get the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + This can be useful for determining when a user specified a value + on the command line that is the same as the default value. It + will be :attr:`~click.core.ParameterSource.DEFAULT` only if the + value was actually taken from the default. + + :param name: The name of the parameter. + :rtype: ParameterSource + + .. versionchanged:: 8.0 + Returns ``None`` if the parameter was not provided from any + source. + """ + return self._parameter_source.get(name) + + +class BaseCommand: + """The base command implements the minimal API contract of commands. + Most code will never use this as it does not implement a lot of useful + functionality but it can act as the direct subclass of alternative + parsing methods that do not depend on the Click parser. + + For instance, this can be used to bridge Click and other systems like + argparse or docopt. + + Because base commands do not implement a lot of the API that other + parts of Click take for granted, they are not supported for all + operations. For instance, they cannot be used with the decorators + usually and they have no built-in callback system. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + """ + + #: The context class to create with :meth:`make_context`. + #: + #: .. versionadded:: 8.0 + context_class: t.Type[Context] = Context + #: the default for the :attr:`Context.allow_extra_args` flag. + allow_extra_args = False + #: the default for the :attr:`Context.allow_interspersed_args` flag. + allow_interspersed_args = True + #: the default for the :attr:`Context.ignore_unknown_options` flag. + ignore_unknown_options = False + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.Dict[str, t.Any]] = None, + ) -> None: + #: the name the command thinks it has. Upon registering a command + #: on a :class:`Group` the group will default the command name + #: with this information. You should instead use the + #: :class:`Context`\'s :attr:`~Context.info_name` attribute. + self.name = name + + if context_settings is None: + context_settings = {} + + #: an optional dictionary with defaults passed to the context. + self.context_settings: t.Dict[str, t.Any] = context_settings + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire structure + below this command. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + :param ctx: A :class:`Context` representing this command. + + .. versionadded:: 8.0 + """ + return {"name": self.name} + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def get_usage(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get usage") + + def get_help(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get help") + + def make_context( + self, + info_name: t.Optional[str], + args: t.List[str], + parent: t.Optional[Context] = None, + **extra: t.Any, + ) -> Context: + """This function when given an info name and arguments will kick + off the parsing and create a new :class:`Context`. It does not + invoke the actual command callback though. + + To quickly customize the context class used without overriding + this method, set the :attr:`context_class` attribute. + + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it's usually + the name of the script, for commands below it it's + the name of the command. + :param args: the arguments to parse as list of strings. + :param parent: the parent context if available. + :param extra: extra keyword arguments forwarded to the context + constructor. + + .. versionchanged:: 8.0 + Added the :attr:`context_class` attribute. + """ + for key, value in self.context_settings.items(): + if key not in extra: + extra[key] = value + + ctx = self.context_class( + self, info_name=info_name, parent=parent, **extra # type: ignore + ) + + with ctx.scope(cleanup=False): + self.parse_args(ctx, args) + return ctx + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + """Given a context and a list of arguments this creates the parser + and parses the arguments, then modifies the context as necessary. + This is automatically invoked by :meth:`make_context`. + """ + raise NotImplementedError("Base commands do not know how to parse arguments.") + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the command. The default + implementation is raising a not implemented error. + """ + raise NotImplementedError("Base commands are not invokable by default") + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of chained multi-commands. + + Any command could be part of a chained multi-command, so sibling + commands are valid at any point during command completion. Other + command classes will return more completions. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + while ctx.parent is not None: + ctx = ctx.parent + + if isinstance(ctx.command, MultiCommand) and ctx.command.chain: + results.extend( + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + if name not in ctx.protected_args + ) + + return results + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: "te.Literal[True]" = True, + **extra: t.Any, + ) -> "te.NoReturn": + ... + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = ..., + **extra: t.Any, + ) -> t.Any: + ... + + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = True, + windows_expand_args: bool = True, + **extra: t.Any, + ) -> t.Any: + """This is the way to invoke a script with all the bells and + whistles as a command line application. This will always terminate + the application after a call. If this is not wanted, ``SystemExit`` + needs to be caught. + + This method is also available by directly calling the instance of + a :class:`Command`. + + :param args: the arguments that should be used for parsing. If not + provided, ``sys.argv[1:]`` is used. + :param prog_name: the program name that should be used. By default + the program name is constructed by taking the file + name from ``sys.argv[0]``. + :param complete_var: the environment variable that controls the + bash completion support. The default is + ``"__COMPLETE"`` with prog_name in + uppercase. + :param standalone_mode: the default behavior is to invoke the script + in standalone mode. Click will then + handle exceptions and convert them into + error messages and the function will never + return but shut down the interpreter. If + this is set to `False` they will be + propagated to the caller and the return + value of this function is the return value + of :meth:`invoke`. + :param windows_expand_args: Expand glob patterns, user dir, and + env vars in command line args on Windows. + :param extra: extra keyword arguments are forwarded to the context + constructor. See :class:`Context` for more information. + + .. versionchanged:: 8.0.1 + Added the ``windows_expand_args`` parameter to allow + disabling command line arg expansion on Windows. + + .. versionchanged:: 8.0 + When taking arguments from ``sys.argv`` on Windows, glob + patterns, user dir, and env vars are expanded. + + .. versionchanged:: 3.0 + Added the ``standalone_mode`` parameter. + """ + if args is None: + args = sys.argv[1:] + + if os.name == "nt" and windows_expand_args: + args = _expand_args(args) + else: + args = list(args) + + if prog_name is None: + prog_name = _detect_program_name() + + # Process shell completion requests and exit early. + self._main_shell_completion(extra, prog_name, complete_var) + + try: + try: + with self.make_context(prog_name, args, **extra) as ctx: + rv = self.invoke(ctx) + if not standalone_mode: + return rv + # it's not safe to `ctx.exit(rv)` here! + # note that `rv` may actually contain data like "1" which + # has obvious effects + # more subtle case: `rv=[None, None]` can come out of + # chained commands which all returned `None` -- so it's not + # even always obvious that `rv` indicates success/failure + # by its truthiness/falsiness + ctx.exit() + except (EOFError, KeyboardInterrupt): + echo(file=sys.stderr) + raise Abort() from None + except ClickException as e: + if not standalone_mode: + raise + e.show() + sys.exit(e.exit_code) + except OSError as e: + if e.errno == errno.EPIPE: + sys.stdout = t.cast(t.TextIO, PacifyFlushWrapper(sys.stdout)) + sys.stderr = t.cast(t.TextIO, PacifyFlushWrapper(sys.stderr)) + sys.exit(1) + else: + raise + except Exit as e: + if standalone_mode: + sys.exit(e.exit_code) + else: + # in non-standalone mode, return the exit code + # note that this is only reached if `self.invoke` above raises + # an Exit explicitly -- thus bypassing the check there which + # would return its result + # the results of non-standalone execution may therefore be + # somewhat ambiguous: if there are codepaths which lead to + # `ctx.exit(1)` and to `return 1`, the caller won't be able to + # tell the difference between the two + return e.exit_code + except Abort: + if not standalone_mode: + raise + echo(_("Aborted!"), file=sys.stderr) + sys.exit(1) + + def _main_shell_completion( + self, + ctx_args: t.Dict[str, t.Any], + prog_name: str, + complete_var: t.Optional[str] = None, + ) -> None: + """Check if the shell is asking for tab completion, process + that, then exit early. Called from :meth:`main` before the + program is invoked. + + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. Defaults to + ``_{PROG_NAME}_COMPLETE``. + """ + if complete_var is None: + complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").upper() + + instruction = os.environ.get(complete_var) + + if not instruction: + return + + from .shell_completion import shell_complete + + rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) + sys.exit(rv) + + def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: + """Alias for :meth:`main`.""" + return self.main(*args, **kwargs) + + +class Command(BaseCommand): + """Commands are the basic building block of command line interfaces in + Click. A basic command handles command line parsing and might dispatch + more parsing to commands nested below it. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + :param callback: the callback to invoke. This is optional. + :param params: the parameters to register with this command. This can + be either :class:`Option` or :class:`Argument` objects. + :param help: the help string to use for this command. + :param epilog: like the help string but it's printed at the end of the + help page after everything else. + :param short_help: the short help to use for this command. This is + shown on the command listing of the parent command. + :param add_help_option: by default each command registers a ``--help`` + option. This can be disabled by this parameter. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is disabled by default. + If enabled this will add ``--help`` as argument + if no arguments are passed + :param hidden: hide this command from help outputs. + + :param deprecated: issues a message indicating that + the command is deprecated. + + .. versionchanged:: 8.1 + ``help``, ``epilog``, and ``short_help`` are stored unprocessed, + all formatting is done when outputting help text, not at init, + and is done even if not using the ``@command`` decorator. + + .. versionchanged:: 8.0 + Added a ``repr`` showing the command name. + + .. versionchanged:: 7.1 + Added the ``no_args_is_help`` parameter. + + .. versionchanged:: 2.0 + Added the ``context_settings`` parameter. + """ + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.Dict[str, t.Any]] = None, + callback: t.Optional[t.Callable[..., t.Any]] = None, + params: t.Optional[t.List["Parameter"]] = None, + help: t.Optional[str] = None, + epilog: t.Optional[str] = None, + short_help: t.Optional[str] = None, + options_metavar: t.Optional[str] = "[OPTIONS]", + add_help_option: bool = True, + no_args_is_help: bool = False, + hidden: bool = False, + deprecated: bool = False, + ) -> None: + super().__init__(name, context_settings) + #: the callback to execute when the command fires. This might be + #: `None` in which case nothing happens. + self.callback = callback + #: the list of parameters for this command in the order they + #: should show up in the help page and execute. Eager parameters + #: will automatically be handled before non eager ones. + self.params: t.List["Parameter"] = params or [] + self.help = help + self.epilog = epilog + self.options_metavar = options_metavar + self.short_help = short_help + self.add_help_option = add_help_option + self.no_args_is_help = no_args_is_help + self.hidden = hidden + self.deprecated = deprecated + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + info_dict.update( + params=[param.to_info_dict() for param in self.get_params(ctx)], + help=self.help, + epilog=self.epilog, + short_help=self.short_help, + hidden=self.hidden, + deprecated=self.deprecated, + ) + return info_dict + + def get_usage(self, ctx: Context) -> str: + """Formats the usage line into a string and returns it. + + Calls :meth:`format_usage` internally. + """ + formatter = ctx.make_formatter() + self.format_usage(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_params(self, ctx: Context) -> t.List["Parameter"]: + rv = self.params + help_option = self.get_help_option(ctx) + + if help_option is not None: + rv = [*rv, help_option] + + return rv + + def format_usage(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the usage line into the formatter. + + This is a low-level method called by :meth:`get_usage`. + """ + pieces = self.collect_usage_pieces(ctx) + formatter.write_usage(ctx.command_path, " ".join(pieces)) + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + """Returns all the pieces that go into the usage line and returns + it as a list of strings. + """ + rv = [self.options_metavar] if self.options_metavar else [] + + for param in self.get_params(ctx): + rv.extend(param.get_usage_pieces(ctx)) + + return rv + + def get_help_option_names(self, ctx: Context) -> t.List[str]: + """Returns the names for the help option.""" + all_names = set(ctx.help_option_names) + for param in self.params: + all_names.difference_update(param.opts) + all_names.difference_update(param.secondary_opts) + return list(all_names) + + def get_help_option(self, ctx: Context) -> t.Optional["Option"]: + """Returns the help option object.""" + help_options = self.get_help_option_names(ctx) + + if not help_options or not self.add_help_option: + return None + + def show_help(ctx: Context, param: "Parameter", value: str) -> None: + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + return Option( + help_options, + is_flag=True, + is_eager=True, + expose_value=False, + callback=show_help, + help=_("Show this message and exit."), + ) + + def make_parser(self, ctx: Context) -> OptionParser: + """Creates the underlying option parser for this command.""" + parser = OptionParser(ctx) + for param in self.get_params(ctx): + param.add_to_parser(parser, ctx) + return parser + + def get_help(self, ctx: Context) -> str: + """Formats the help into a string and returns it. + + Calls :meth:`format_help` internally. + """ + formatter = ctx.make_formatter() + self.format_help(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_short_help_str(self, limit: int = 45) -> str: + """Gets short help for the command or makes it by shortening the + long help string. + """ + if self.short_help: + text = inspect.cleandoc(self.short_help) + elif self.help: + text = make_default_short_help(self.help, limit) + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + return text.strip() + + def format_help(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help into the formatter if it exists. + + This is a low-level method called by :meth:`get_help`. + + This calls the following methods: + + - :meth:`format_usage` + - :meth:`format_help_text` + - :meth:`format_options` + - :meth:`format_epilog` + """ + self.format_usage(ctx, formatter) + self.format_help_text(ctx, formatter) + self.format_options(ctx, formatter) + self.format_epilog(ctx, formatter) + + def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help text to the formatter if it exists.""" + text = self.help if self.help is not None else "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + if text: + text = inspect.cleandoc(text).partition("\f")[0] + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(text) + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes all the options into the formatter if they exist.""" + opts = [] + for param in self.get_params(ctx): + rv = param.get_help_record(ctx) + if rv is not None: + opts.append(rv) + + if opts: + with formatter.section(_("Options")): + formatter.write_dl(opts) + + def format_epilog(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the epilog into the formatter if it exists.""" + if self.epilog: + epilog = inspect.cleandoc(self.epilog) + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(epilog) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + parser = self.make_parser(ctx) + opts, args, param_order = parser.parse_args(args=args) + + for param in iter_params_for_processing(param_order, self.get_params(ctx)): + value, args = param.handle_parse_result(ctx, opts, args) + + if args and not ctx.allow_extra_args and not ctx.resilient_parsing: + ctx.fail( + ngettext( + "Got unexpected extra argument ({args})", + "Got unexpected extra arguments ({args})", + len(args), + ).format(args=" ".join(map(str, args))) + ) + + ctx.args = args + ctx._opt_prefixes.update(parser._opt_prefixes) + return args + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the attached callback (if it exists) + in the right way. + """ + if self.deprecated: + message = _( + "DeprecationWarning: The command {name!r} is deprecated." + ).format(name=self.name) + echo(style(message, fg="red"), err=True) + + if self.callback is not None: + return ctx.invoke(self.callback, **ctx.params) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options and chained multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + if incomplete and not incomplete[0].isalnum(): + for param in self.get_params(ctx): + if ( + not isinstance(param, Option) + or param.hidden + or ( + not param.multiple + and ctx.get_parameter_source(param.name) # type: ignore + is ParameterSource.COMMANDLINE + ) + ): + continue + + results.extend( + CompletionItem(name, help=param.help) + for name in [*param.opts, *param.secondary_opts] + if name.startswith(incomplete) + ) + + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class MultiCommand(Command): + """A multi command is the basic implementation of a command that + dispatches to subcommands. The most common version is the + :class:`Group`. + + :param invoke_without_command: this controls how the multi command itself + is invoked. By default it's only invoked + if a subcommand is provided. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is enabled by default if + `invoke_without_command` is disabled or disabled + if it's enabled. If enabled this will add + ``--help`` as argument if no arguments are + passed. + :param subcommand_metavar: the string that is used in the documentation + to indicate the subcommand place. + :param chain: if this is set to `True` chaining of multiple subcommands + is enabled. This restricts the form of commands in that + they cannot have optional arguments but it allows + multiple commands to be chained together. + :param result_callback: The result callback to attach to this multi + command. This can be set or changed later with the + :meth:`result_callback` decorator. + """ + + allow_extra_args = True + allow_interspersed_args = False + + def __init__( + self, + name: t.Optional[str] = None, + invoke_without_command: bool = False, + no_args_is_help: t.Optional[bool] = None, + subcommand_metavar: t.Optional[str] = None, + chain: bool = False, + result_callback: t.Optional[t.Callable[..., t.Any]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if no_args_is_help is None: + no_args_is_help = not invoke_without_command + + self.no_args_is_help = no_args_is_help + self.invoke_without_command = invoke_without_command + + if subcommand_metavar is None: + if chain: + subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..." + else: + subcommand_metavar = "COMMAND [ARGS]..." + + self.subcommand_metavar = subcommand_metavar + self.chain = chain + # The result callback that is stored. This can be set or + # overridden with the :func:`result_callback` decorator. + self._result_callback = result_callback + + if self.chain: + for param in self.params: + if isinstance(param, Argument) and not param.required: + raise RuntimeError( + "Multi commands in chain mode cannot have" + " optional arguments." + ) + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + commands = {} + + for name in self.list_commands(ctx): + command = self.get_command(ctx, name) + + if command is None: + continue + + sub_ctx = ctx._make_sub_context(command) + + with sub_ctx.scope(cleanup=False): + commands[name] = command.to_info_dict(sub_ctx) + + info_dict.update(commands=commands, chain=self.chain) + return info_dict + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + rv = super().collect_usage_pieces(ctx) + rv.append(self.subcommand_metavar) + return rv + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + super().format_options(ctx, formatter) + self.format_commands(ctx, formatter) + + def result_callback(self, replace: bool = False) -> t.Callable[[F], F]: + """Adds a result callback to the command. By default if a + result callback is already registered this will chain them but + this can be disabled with the `replace` parameter. The result + callback is invoked with the return value of the subcommand + (or the list of return values from all subcommands if chaining + is enabled) as well as the parameters as they would be passed + to the main callback. + + Example:: + + @click.group() + @click.option('-i', '--input', default=23) + def cli(input): + return 42 + + @cli.result_callback() + def process_result(result, input): + return result + input + + :param replace: if set to `True` an already existing result + callback will be removed. + + .. versionchanged:: 8.0 + Renamed from ``resultcallback``. + + .. versionadded:: 3.0 + """ + + def decorator(f: F) -> F: + old_callback = self._result_callback + + if old_callback is None or replace: + self._result_callback = f + return f + + def function(__value, *args, **kwargs): # type: ignore + inner = old_callback(__value, *args, **kwargs) # type: ignore + return f(inner, *args, **kwargs) + + self._result_callback = rv = update_wrapper(t.cast(F, function), f) + return rv + + return decorator + + def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None: + """Extra format methods for multi methods that adds all the commands + after the options. + """ + commands = [] + for subcommand in self.list_commands(ctx): + cmd = self.get_command(ctx, subcommand) + # What is this, the tool lied about a command. Ignore it + if cmd is None: + continue + if cmd.hidden: + continue + + commands.append((subcommand, cmd)) + + # allow for 3 times the default spacing + if len(commands): + limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands) + + rows = [] + for subcommand, cmd in commands: + help = cmd.get_short_help_str(limit) + rows.append((subcommand, help)) + + if rows: + with formatter.section(_("Commands")): + formatter.write_dl(rows) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + rest = super().parse_args(ctx, args) + + if self.chain: + ctx.protected_args = rest + ctx.args = [] + elif rest: + ctx.protected_args, ctx.args = rest[:1], rest[1:] + + return ctx.args + + def invoke(self, ctx: Context) -> t.Any: + def _process_result(value: t.Any) -> t.Any: + if self._result_callback is not None: + value = ctx.invoke(self._result_callback, value, **ctx.params) + return value + + if not ctx.protected_args: + if self.invoke_without_command: + # No subcommand was invoked, so the result callback is + # invoked with the group return value for regular + # groups, or an empty list for chained groups. + with ctx: + rv = super().invoke(ctx) + return _process_result([] if self.chain else rv) + ctx.fail(_("Missing command.")) + + # Fetch args back out + args = [*ctx.protected_args, *ctx.args] + ctx.args = [] + ctx.protected_args = [] + + # If we're not in chain mode, we only allow the invocation of a + # single command but we also inform the current context about the + # name of the command to invoke. + if not self.chain: + # Make sure the context is entered so we do not clean up + # resources until the result processor has worked. + with ctx: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + ctx.invoked_subcommand = cmd_name + super().invoke(ctx) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) + with sub_ctx: + return _process_result(sub_ctx.command.invoke(sub_ctx)) + + # In chain mode we create the contexts step by step, but after the + # base command has been invoked. Because at that point we do not + # know the subcommands yet, the invoked subcommand attribute is + # set to ``*`` to inform the command that subcommands are executed + # but nothing else. + with ctx: + ctx.invoked_subcommand = "*" if args else None + super().invoke(ctx) + + # Otherwise we make every single context and invoke them in a + # chain. In that case the return value to the result processor + # is the list of all invoked subcommand's results. + contexts = [] + while args: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + sub_ctx = cmd.make_context( + cmd_name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + ) + contexts.append(sub_ctx) + args, sub_ctx.args = sub_ctx.args, [] + + rv = [] + for sub_ctx in contexts: + with sub_ctx: + rv.append(sub_ctx.command.invoke(sub_ctx)) + return _process_result(rv) + + def resolve_command( + self, ctx: Context, args: t.List[str] + ) -> t.Tuple[t.Optional[str], t.Optional[Command], t.List[str]]: + cmd_name = make_str(args[0]) + original_cmd_name = cmd_name + + # Get the command + cmd = self.get_command(ctx, cmd_name) + + # If we can't find the command but there is a normalization + # function available, we try with that one. + if cmd is None and ctx.token_normalize_func is not None: + cmd_name = ctx.token_normalize_func(cmd_name) + cmd = self.get_command(ctx, cmd_name) + + # If we don't find the command we want to show an error message + # to the user that it was not provided. However, there is + # something else we should do: if the first argument looks like + # an option we want to kick off parsing again for arguments to + # resolve things like --help which now should go to the main + # place. + if cmd is None and not ctx.resilient_parsing: + if split_opt(cmd_name)[0]: + self.parse_args(ctx, ctx.args) + ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name)) + return cmd_name if cmd else None, cmd, args[1:] + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + """Given a context and a command name, this returns a + :class:`Command` object if it exists or returns `None`. + """ + raise NotImplementedError + + def list_commands(self, ctx: Context) -> t.List[str]: + """Returns a list of subcommand names in the order they should + appear. + """ + return [] + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options, subcommands, and chained + multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results = [ + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + ] + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class Group(MultiCommand): + """A group allows a command to have subcommands attached. This is + the most common way to implement nesting in Click. + + :param name: The name of the group command. + :param commands: A dict mapping names to :class:`Command` objects. + Can also be a list of :class:`Command`, which will use + :attr:`Command.name` to create the dict. + :param attrs: Other command arguments described in + :class:`MultiCommand`, :class:`Command`, and + :class:`BaseCommand`. + + .. versionchanged:: 8.0 + The ``commmands`` argument can be a list of command objects. + """ + + #: If set, this is used by the group's :meth:`command` decorator + #: as the default :class:`Command` class. This is useful to make all + #: subcommands use a custom command class. + #: + #: .. versionadded:: 8.0 + command_class: t.Optional[t.Type[Command]] = None + + #: If set, this is used by the group's :meth:`group` decorator + #: as the default :class:`Group` class. This is useful to make all + #: subgroups use a custom group class. + #: + #: If set to the special value :class:`type` (literally + #: ``group_class = type``), this group's class will be used as the + #: default class. This makes a custom group class continue to make + #: custom groups. + #: + #: .. versionadded:: 8.0 + group_class: t.Optional[t.Union[t.Type["Group"], t.Type[type]]] = None + # Literal[type] isn't valid, so use Type[type] + + def __init__( + self, + name: t.Optional[str] = None, + commands: t.Optional[t.Union[t.Dict[str, Command], t.Sequence[Command]]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if commands is None: + commands = {} + elif isinstance(commands, abc.Sequence): + commands = {c.name: c for c in commands if c.name is not None} + + #: The registered subcommands by their exported names. + self.commands: t.Dict[str, Command] = commands + + def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: + """Registers another :class:`Command` with this group. If the name + is not provided, the name of the command is used. + """ + name = name or cmd.name + if name is None: + raise TypeError("Command has no name.") + _check_multicommand(self, name, cmd, register=True) + self.commands[name] = cmd + + @t.overload + def command(self, __func: t.Callable[..., t.Any]) -> Command: + ... + + @t.overload + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], Command]: + ... + + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], Command], Command]: + """A shortcut decorator for declaring and attaching a command to + the group. This takes the same arguments as :func:`command` and + immediately registers the created command with this group by + calling :meth:`add_command`. + + To customize the command class used, set the + :attr:`command_class` attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`command_class` attribute. + """ + from .decorators import command + + if self.command_class and kwargs.get("cls") is None: + kwargs["cls"] = self.command_class + + func: t.Optional[t.Callable] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'command(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + def decorator(f: t.Callable[..., t.Any]) -> Command: + cmd: Command = command(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + @t.overload + def group(self, __func: t.Callable[..., t.Any]) -> "Group": + ... + + @t.overload + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], "Group"]: + ... + + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], "Group"], "Group"]: + """A shortcut decorator for declaring and attaching a group to + the group. This takes the same arguments as :func:`group` and + immediately registers the created group with this group by + calling :meth:`add_command`. + + To customize the group class used, set the :attr:`group_class` + attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`group_class` attribute. + """ + from .decorators import group + + func: t.Optional[t.Callable] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'group(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.group_class is not None and kwargs.get("cls") is None: + if self.group_class is type: + kwargs["cls"] = type(self) + else: + kwargs["cls"] = self.group_class + + def decorator(f: t.Callable[..., t.Any]) -> "Group": + cmd: Group = group(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + return self.commands.get(cmd_name) + + def list_commands(self, ctx: Context) -> t.List[str]: + return sorted(self.commands) + + +class CommandCollection(MultiCommand): + """A command collection is a multi command that merges multiple multi + commands together into one. This is a straightforward implementation + that accepts a list of different multi commands as sources and + provides all the commands for each of them. + """ + + def __init__( + self, + name: t.Optional[str] = None, + sources: t.Optional[t.List[MultiCommand]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + #: The list of registered multi commands. + self.sources: t.List[MultiCommand] = sources or [] + + def add_source(self, multi_cmd: MultiCommand) -> None: + """Adds a new multi command to the chain dispatcher.""" + self.sources.append(multi_cmd) + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + for source in self.sources: + rv = source.get_command(ctx, cmd_name) + + if rv is not None: + if self.chain: + _check_multicommand(self, cmd_name, rv) + + return rv + + return None + + def list_commands(self, ctx: Context) -> t.List[str]: + rv: t.Set[str] = set() + + for source in self.sources: + rv.update(source.list_commands(ctx)) + + return sorted(rv) + + +def _check_iter(value: t.Any) -> t.Iterator[t.Any]: + """Check if the value is iterable but not a string. Raises a type + error, or return an iterator over the value. + """ + if isinstance(value, str): + raise TypeError + + return iter(value) + + +class Parameter: + r"""A parameter to a command comes in two versions: they are either + :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently + not supported by design as some of the internals for parsing are + intentionally not finalized. + + Some settings are supported by both options and arguments. + + :param param_decls: the parameter declarations for this option or + argument. This is a list of flags or argument + names. + :param type: the type that should be used. Either a :class:`ParamType` + or a Python type. The later is converted into the former + automatically if supported. + :param required: controls if this is optional or not. + :param default: the default value if omitted. This can also be a callable, + in which case it's invoked when the default is needed + without any arguments. + :param callback: A function to further process or validate the value + after type conversion. It is called as ``f(ctx, param, value)`` + and must return the value. It is called for all sources, + including prompts. + :param nargs: the number of arguments to match. If not ``1`` the return + value is a tuple instead of single value. The default for + nargs is ``1`` (except if the type is a tuple, then it's + the arity of the tuple). If ``nargs=-1``, all remaining + parameters are collected. + :param metavar: how the value is represented in the help page. + :param expose_value: if this is `True` then the value is passed onwards + to the command callback and stored on the context, + otherwise it's skipped. + :param is_eager: eager values are processed before non eager ones. This + should not be set for arguments or it will inverse the + order of processing. + :param envvar: a string or list of strings that are environment variables + that should be checked. + :param shell_complete: A function that returns custom shell + completions. Used instead of the param's type completion if + given. Takes ``ctx, param, incomplete`` and must return a list + of :class:`~click.shell_completion.CompletionItem` or a list of + strings. + + .. versionchanged:: 8.0 + ``process_value`` validates required parameters and bounded + ``nargs``, and invokes the parameter callback before returning + the value. This allows the callback to validate prompts. + ``full_process_value`` is removed. + + .. versionchanged:: 8.0 + ``autocompletion`` is renamed to ``shell_complete`` and has new + semantics described above. The old name is deprecated and will + be removed in 8.1, until then it will be wrapped to match the + new requirements. + + .. versionchanged:: 8.0 + For ``multiple=True, nargs>1``, the default must be a list of + tuples. + + .. versionchanged:: 8.0 + Setting a default is no longer required for ``nargs>1``, it will + default to ``None``. ``multiple=True`` or ``nargs=-1`` will + default to ``()``. + + .. versionchanged:: 7.1 + Empty environment variables are ignored rather than taking the + empty string value. This makes it possible for scripts to clear + variables if they can't unset them. + + .. versionchanged:: 2.0 + Changed signature for parameter callback to also be passed the + parameter. The old callback format will still work, but it will + raise a warning to give you a chance to migrate the code easier. + """ + + param_type_name = "parameter" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + required: bool = False, + default: t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]] = None, + callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]] = None, + nargs: t.Optional[int] = None, + multiple: bool = False, + metavar: t.Optional[str] = None, + expose_value: bool = True, + is_eager: bool = False, + envvar: t.Optional[t.Union[str, t.Sequence[str]]] = None, + shell_complete: t.Optional[ + t.Callable[ + [Context, "Parameter", str], + t.Union[t.List["CompletionItem"], t.List[str]], + ] + ] = None, + ) -> None: + self.name, self.opts, self.secondary_opts = self._parse_decls( + param_decls or (), expose_value + ) + self.type = types.convert_type(type, default) + + # Default nargs to what the type tells us if we have that + # information available. + if nargs is None: + if self.type.is_composite: + nargs = self.type.arity + else: + nargs = 1 + + self.required = required + self.callback = callback + self.nargs = nargs + self.multiple = multiple + self.expose_value = expose_value + self.default = default + self.is_eager = is_eager + self.metavar = metavar + self.envvar = envvar + self._custom_shell_complete = shell_complete + + if __debug__: + if self.type.is_composite and nargs != self.type.arity: + raise ValueError( + f"'nargs' must be {self.type.arity} (or None) for" + f" type {self.type!r}, but it was {nargs}." + ) + + # Skip no default or callable default. + check_default = default if not callable(default) else None + + if check_default is not None: + if multiple: + try: + # Only check the first value against nargs. + check_default = next(_check_iter(check_default), None) + except TypeError: + raise ValueError( + "'default' must be a list when 'multiple' is true." + ) from None + + # Can be None for multiple with empty default. + if nargs != 1 and check_default is not None: + try: + _check_iter(check_default) + except TypeError: + if multiple: + message = ( + "'default' must be a list of lists when 'multiple' is" + " true and 'nargs' != 1." + ) + else: + message = "'default' must be a list when 'nargs' != 1." + + raise ValueError(message) from None + + if nargs > 1 and len(check_default) != nargs: + subject = "item length" if multiple else "length" + raise ValueError( + f"'default' {subject} must match nargs={nargs}." + ) + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + return { + "name": self.name, + "param_type_name": self.param_type_name, + "opts": self.opts, + "secondary_opts": self.secondary_opts, + "type": self.type.to_info_dict(), + "required": self.required, + "nargs": self.nargs, + "multiple": self.multiple, + "default": self.default, + "envvar": self.envvar, + } + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + raise NotImplementedError() + + @property + def human_readable_name(self) -> str: + """Returns the human readable name of this parameter. This is the + same as the name for options, but the metavar for arguments. + """ + return self.name # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + + metavar = self.type.get_metavar(self) + + if metavar is None: + metavar = self.type.name.upper() + + if self.nargs != 1: + metavar += "..." + + return metavar + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + """Get the default for the parameter. Tries + :meth:`Context.lookup_default` first, then the local default. + + :param ctx: Current context. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0.2 + Type casting is no longer performed when getting a default. + + .. versionchanged:: 8.0.1 + Type casting can fail in resilient parsing mode. Invalid + defaults will not prevent showing help text. + + .. versionchanged:: 8.0 + Looks at ``ctx.default_map`` first. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + value = ctx.lookup_default(self.name, call=False) # type: ignore + + if value is None: + value = self.default + + if call and callable(value): + value = value() + + return value + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + raise NotImplementedError() + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, t.Any] + ) -> t.Tuple[t.Any, ParameterSource]: + value = opts.get(self.name) # type: ignore + source = ParameterSource.COMMANDLINE + + if value is None: + value = self.value_from_envvar(ctx) + source = ParameterSource.ENVIRONMENT + + if value is None: + value = ctx.lookup_default(self.name) # type: ignore + source = ParameterSource.DEFAULT_MAP + + if value is None: + value = self.get_default(ctx) + source = ParameterSource.DEFAULT + + return value, source + + def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any: + """Convert and validate a value against the option's + :attr:`type`, :attr:`multiple`, and :attr:`nargs`. + """ + if value is None: + return () if self.multiple or self.nargs == -1 else None + + def check_iter(value: t.Any) -> t.Iterator: + try: + return _check_iter(value) + except TypeError: + # This should only happen when passing in args manually, + # the parser should construct an iterable when parsing + # the command line. + raise BadParameter( + _("Value must be an iterable."), ctx=ctx, param=self + ) from None + + if self.nargs == 1 or self.type.is_composite: + convert: t.Callable[[t.Any], t.Any] = partial( + self.type, param=self, ctx=ctx + ) + elif self.nargs == -1: + + def convert(value: t.Any) -> t.Tuple: + return tuple(self.type(x, self, ctx) for x in check_iter(value)) + + else: # nargs > 1 + + def convert(value: t.Any) -> t.Tuple: + value = tuple(check_iter(value)) + + if len(value) != self.nargs: + raise BadParameter( + ngettext( + "Takes {nargs} values but 1 was given.", + "Takes {nargs} values but {len} were given.", + len(value), + ).format(nargs=self.nargs, len=len(value)), + ctx=ctx, + param=self, + ) + + return tuple(self.type(x, self, ctx) for x in value) + + if self.multiple: + return tuple(convert(x) for x in check_iter(value)) + + return convert(value) + + def value_is_missing(self, value: t.Any) -> bool: + if value is None: + return True + + if (self.nargs != 1 or self.multiple) and value == (): + return True + + return False + + def process_value(self, ctx: Context, value: t.Any) -> t.Any: + value = self.type_cast_value(ctx, value) + + if self.required and self.value_is_missing(value): + raise MissingParameter(ctx=ctx, param=self) + + if self.callback is not None: + value = self.callback(ctx, self, value) + + return value + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + if self.envvar is None: + return None + + if isinstance(self.envvar, str): + rv = os.environ.get(self.envvar) + + if rv: + return rv + else: + for envvar in self.envvar: + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is not None and self.nargs != 1: + rv = self.type.split_envvar_value(rv) + + return rv + + def handle_parse_result( + self, ctx: Context, opts: t.Mapping[str, t.Any], args: t.List[str] + ) -> t.Tuple[t.Any, t.List[str]]: + with augment_usage_errors(ctx, param=self): + value, source = self.consume_value(ctx, opts) + ctx.set_parameter_source(self.name, source) # type: ignore + + try: + value = self.process_value(ctx, value) + except Exception: + if not ctx.resilient_parsing: + raise + + value = None + + if self.expose_value: + ctx.params[self.name] = value # type: ignore + + return value, args + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + pass + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [] + + def get_error_hint(self, ctx: Context) -> str: + """Get a stringified version of the param for use in error messages to + indicate which param caused the error. + """ + hint_list = self.opts or [self.human_readable_name] + return " / ".join(f"'{x}'" for x in hint_list) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. If a + ``shell_complete`` function was given during init, it is used. + Otherwise, the :attr:`type` + :meth:`~click.types.ParamType.shell_complete` function is used. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + if self._custom_shell_complete is not None: + results = self._custom_shell_complete(ctx, self, incomplete) + + if results and isinstance(results[0], str): + from click.shell_completion import CompletionItem + + results = [CompletionItem(c) for c in results] + + return t.cast(t.List["CompletionItem"], results) + + return self.type.shell_complete(ctx, self, incomplete) + + +class Option(Parameter): + """Options are usually optional values on the command line and + have some extra features that arguments don't have. + + All other parameters are passed onwards to the parameter constructor. + + :param show_default: Show the default value for this option in its + help text. Values are not shown by default, unless + :attr:`Context.show_default` is ``True``. If this value is a + string, it shows that string in parentheses instead of the + actual value. This is particularly useful for dynamic options. + For single option boolean flags, the default remains hidden if + its value is ``False``. + :param show_envvar: Controls if an environment variable should be + shown on the help page. Normally, environment variables are not + shown. + :param prompt: If set to ``True`` or a non empty string then the + user will be prompted for input. If set to ``True`` the prompt + will be the option name capitalized. + :param confirmation_prompt: Prompt a second time to confirm the + value if it was prompted for. Can be set to a string instead of + ``True`` to customize the message. + :param prompt_required: If set to ``False``, the user will be + prompted for input only when the option was specified as a flag + without a value. + :param hide_input: If this is ``True`` then the input on the prompt + will be hidden from the user. This is useful for password input. + :param is_flag: forces this option to act as a flag. The default is + auto detection. + :param flag_value: which value should be used for this flag if it's + enabled. This is set to a boolean automatically if + the option string contains a slash to mark two options. + :param multiple: if this is set to `True` then the argument is accepted + multiple times and recorded. This is similar to ``nargs`` + in how it works but supports arbitrary number of + arguments. + :param count: this flag makes an option increment an integer. + :param allow_from_autoenv: if this is enabled then the value of this + parameter will be pulled from an environment + variable in case a prefix is defined on the + context. + :param help: the help string. + :param hidden: hide this option from help outputs. + + .. versionchanged:: 8.1.0 + Help text indentation is cleaned here instead of only in the + ``@option`` decorator. + + .. versionchanged:: 8.1.0 + The ``show_default`` parameter overrides + ``Context.show_default``. + + .. versionchanged:: 8.1.0 + The default of a single option boolean flag is not shown if the + default value is ``False``. + + .. versionchanged:: 8.0.1 + ``type`` is detected from ``flag_value`` if given. + """ + + param_type_name = "option" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + show_default: t.Union[bool, str, None] = None, + prompt: t.Union[bool, str] = False, + confirmation_prompt: t.Union[bool, str] = False, + prompt_required: bool = True, + hide_input: bool = False, + is_flag: t.Optional[bool] = None, + flag_value: t.Optional[t.Any] = None, + multiple: bool = False, + count: bool = False, + allow_from_autoenv: bool = True, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + help: t.Optional[str] = None, + hidden: bool = False, + show_choices: bool = True, + show_envvar: bool = False, + **attrs: t.Any, + ) -> None: + if help: + help = inspect.cleandoc(help) + + default_is_missing = "default" not in attrs + super().__init__(param_decls, type=type, multiple=multiple, **attrs) + + if prompt is True: + if self.name is None: + raise TypeError("'name' is required with 'prompt=True'.") + + prompt_text: t.Optional[str] = self.name.replace("_", " ").capitalize() + elif prompt is False: + prompt_text = None + else: + prompt_text = prompt + + self.prompt = prompt_text + self.confirmation_prompt = confirmation_prompt + self.prompt_required = prompt_required + self.hide_input = hide_input + self.hidden = hidden + + # If prompt is enabled but not required, then the option can be + # used as a flag to indicate using prompt or flag_value. + self._flag_needs_value = self.prompt is not None and not self.prompt_required + + if is_flag is None: + if flag_value is not None: + # Implicitly a flag because flag_value was set. + is_flag = True + elif self._flag_needs_value: + # Not a flag, but when used as a flag it shows a prompt. + is_flag = False + else: + # Implicitly a flag because flag options were given. + is_flag = bool(self.secondary_opts) + elif is_flag is False and not self._flag_needs_value: + # Not a flag, and prompt is not enabled, can be used as a + # flag if flag_value is set. + self._flag_needs_value = flag_value is not None + + if is_flag and default_is_missing and not self.required: + self.default: t.Union[t.Any, t.Callable[[], t.Any]] = False + + if flag_value is None: + flag_value = not self.default + + if is_flag and type is None: + # Re-guess the type from the flag value instead of the + # default. + self.type = types.convert_type(None, flag_value) + + self.is_flag: bool = is_flag + self.is_bool_flag = is_flag and isinstance(self.type, types.BoolParamType) + self.flag_value: t.Any = flag_value + + # Counting + self.count = count + if count: + if type is None: + self.type = types.IntRange(min=0) + if default_is_missing: + self.default = 0 + + self.allow_from_autoenv = allow_from_autoenv + self.help = help + self.show_default = show_default + self.show_choices = show_choices + self.show_envvar = show_envvar + + if __debug__: + if self.nargs == -1: + raise TypeError("nargs=-1 is not supported for options.") + + if self.prompt and self.is_flag and not self.is_bool_flag: + raise TypeError("'prompt' is not valid for non-boolean flag.") + + if not self.is_bool_flag and self.secondary_opts: + raise TypeError("Secondary flag is not valid for non-boolean flag.") + + if self.is_bool_flag and self.hide_input and self.prompt is not None: + raise TypeError( + "'prompt' with 'hide_input' is not valid for boolean flag." + ) + + if self.count: + if self.multiple: + raise TypeError("'count' is not valid with 'multiple'.") + + if self.is_flag: + raise TypeError("'count' is not valid with 'is_flag'.") + + if self.multiple and self.is_flag: + raise TypeError("'multiple' is not valid with 'is_flag', use 'count'.") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + help=self.help, + prompt=self.prompt, + is_flag=self.is_flag, + flag_value=self.flag_value, + count=self.count, + hidden=self.hidden, + ) + return info_dict + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + opts = [] + secondary_opts = [] + name = None + possible_names = [] + + for decl in decls: + if decl.isidentifier(): + if name is not None: + raise TypeError(f"Name '{name}' defined twice") + name = decl + else: + split_char = ";" if decl[:1] == "/" else "/" + if split_char in decl: + first, second = decl.split(split_char, 1) + first = first.rstrip() + if first: + possible_names.append(split_opt(first)) + opts.append(first) + second = second.lstrip() + if second: + secondary_opts.append(second.lstrip()) + if first == second: + raise ValueError( + f"Boolean option {decl!r} cannot use the" + " same flag for true/false." + ) + else: + possible_names.append(split_opt(decl)) + opts.append(decl) + + if name is None and possible_names: + possible_names.sort(key=lambda x: -len(x[0])) # group long options first + name = possible_names[0][1].replace("-", "_").lower() + if not name.isidentifier(): + name = None + + if name is None: + if not expose_value: + return None, opts, secondary_opts + raise TypeError("Could not determine name for option") + + if not opts and not secondary_opts: + raise TypeError( + f"No options defined but a name was passed ({name})." + " Did you mean to declare an argument instead? Did" + f" you mean to pass '--{name}'?" + ) + + return name, opts, secondary_opts + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + if self.multiple: + action = "append" + elif self.count: + action = "count" + else: + action = "store" + + if self.is_flag: + action = f"{action}_const" + + if self.is_bool_flag and self.secondary_opts: + parser.add_option( + obj=self, opts=self.opts, dest=self.name, action=action, const=True + ) + parser.add_option( + obj=self, + opts=self.secondary_opts, + dest=self.name, + action=action, + const=False, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + const=self.flag_value, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + nargs=self.nargs, + ) + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + if self.hidden: + return None + + any_prefix_is_slash = False + + def _write_opts(opts: t.Sequence[str]) -> str: + nonlocal any_prefix_is_slash + + rv, any_slashes = join_options(opts) + + if any_slashes: + any_prefix_is_slash = True + + if not self.is_flag and not self.count: + rv += f" {self.make_metavar()}" + + return rv + + rv = [_write_opts(self.opts)] + + if self.secondary_opts: + rv.append(_write_opts(self.secondary_opts)) + + help = self.help or "" + extra = [] + + if self.show_envvar: + envvar = self.envvar + + if envvar is None: + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + + if envvar is not None: + var_str = ( + envvar + if isinstance(envvar, str) + else ", ".join(str(d) for d in envvar) + ) + extra.append(_("env var: {var}").format(var=var_str)) + + # Temporarily enable resilient parsing to avoid type casting + # failing for the default. Might be possible to extend this to + # help formatting in general. + resilient = ctx.resilient_parsing + ctx.resilient_parsing = True + + try: + default_value = self.get_default(ctx, call=False) + finally: + ctx.resilient_parsing = resilient + + show_default = False + show_default_is_str = False + + if self.show_default is not None: + if isinstance(self.show_default, str): + show_default_is_str = show_default = True + else: + show_default = self.show_default + elif ctx.show_default is not None: + show_default = ctx.show_default + + if show_default_is_str or (show_default and (default_value is not None)): + if show_default_is_str: + default_string = f"({self.show_default})" + elif isinstance(default_value, (list, tuple)): + default_string = ", ".join(str(d) for d in default_value) + elif inspect.isfunction(default_value): + default_string = _("(dynamic)") + elif self.is_bool_flag and self.secondary_opts: + # For boolean flags that have distinct True/False opts, + # use the opt without prefix instead of the value. + default_string = split_opt( + (self.opts if self.default else self.secondary_opts)[0] + )[1] + elif self.is_bool_flag and not self.secondary_opts and not default_value: + default_string = "" + else: + default_string = str(default_value) + + if default_string: + extra.append(_("default: {default}").format(default=default_string)) + + if ( + isinstance(self.type, types._NumberRangeBase) + # skip count with default range type + and not (self.count and self.type.min == 0 and self.type.max is None) + ): + range_str = self.type._describe_range() + + if range_str: + extra.append(range_str) + + if self.required: + extra.append(_("required")) + + if extra: + extra_str = "; ".join(extra) + help = f"{help} [{extra_str}]" if help else f"[{extra_str}]" + + return ("; " if any_prefix_is_slash else " / ").join(rv), help + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + # If we're a non boolean flag our default is more complex because + # we need to look at all flags in the same group to figure out + # if we're the default one in which case we return the flag + # value as default. + if self.is_flag and not self.is_bool_flag: + for param in ctx.command.params: + if param.name == self.name and param.default: + return param.flag_value # type: ignore + + return None + + return super().get_default(ctx, call=call) + + def prompt_for_value(self, ctx: Context) -> t.Any: + """This is an alternative flow that can be activated in the full + value processing if a value does not exist. It will prompt the + user until a valid value exists and then returns the processed + value as result. + """ + assert self.prompt is not None + + # Calculate the default before prompting anything to be stable. + default = self.get_default(ctx) + + # If this is a prompt for a flag we need to handle this + # differently. + if self.is_bool_flag: + return confirm(self.prompt, default) + + return prompt( + self.prompt, + default=default, + type=self.type, + hide_input=self.hide_input, + show_choices=self.show_choices, + confirmation_prompt=self.confirmation_prompt, + value_proc=lambda x: self.process_value(ctx, x), + ) + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + rv = super().resolve_envvar_value(ctx) + + if rv is not None: + return rv + + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is None: + return None + + value_depth = (self.nargs != 1) + bool(self.multiple) + + if value_depth > 0: + rv = self.type.split_envvar_value(rv) + + if self.multiple and self.nargs != 1: + rv = batch(rv, self.nargs) + + return rv + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, "Parameter"] + ) -> t.Tuple[t.Any, ParameterSource]: + value, source = super().consume_value(ctx, opts) + + # The parser will emit a sentinel value if the option can be + # given as a flag without a value. This is different from None + # to distinguish from the flag not being given at all. + if value is _flag_needs_value: + if self.prompt is not None and not ctx.resilient_parsing: + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + else: + value = self.flag_value + source = ParameterSource.COMMANDLINE + + elif ( + self.multiple + and value is not None + and any(v is _flag_needs_value for v in value) + ): + value = [self.flag_value if v is _flag_needs_value else v for v in value] + source = ParameterSource.COMMANDLINE + + # The value wasn't set, or used the param's default, prompt if + # prompting is enabled. + elif ( + source in {None, ParameterSource.DEFAULT} + and self.prompt is not None + and (self.required or self.prompt_required) + and not ctx.resilient_parsing + ): + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + + return value, source + + +class Argument(Parameter): + """Arguments are positional parameters to a command. They generally + provide fewer features than options but can have infinite ``nargs`` + and are required by default. + + All parameters are passed onwards to the parameter constructor. + """ + + param_type_name = "argument" + + def __init__( + self, + param_decls: t.Sequence[str], + required: t.Optional[bool] = None, + **attrs: t.Any, + ) -> None: + if required is None: + if attrs.get("default") is not None: + required = False + else: + required = attrs.get("nargs", 1) > 0 + + if "multiple" in attrs: + raise TypeError("__init__() got an unexpected keyword argument 'multiple'.") + + super().__init__(param_decls, required=required, **attrs) + + if __debug__: + if self.default is not None and self.nargs == -1: + raise TypeError("'default' is not supported for nargs=-1.") + + @property + def human_readable_name(self) -> str: + if self.metavar is not None: + return self.metavar + return self.name.upper() # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + var = self.type.get_metavar(self) + if not var: + var = self.name.upper() # type: ignore + if not self.required: + var = f"[{var}]" + if self.nargs != 1: + var += "..." + return var + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + if not decls: + if not expose_value: + return None, [], [] + raise TypeError("Could not determine name for argument") + if len(decls) == 1: + name = arg = decls[0] + name = name.replace("-", "_").lower() + else: + raise TypeError( + "Arguments take exactly one parameter declaration, got" + f" {len(decls)}." + ) + return name, [arg], [] + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [self.make_metavar()] + + def get_error_hint(self, ctx: Context) -> str: + return f"'{self.make_metavar()}'" + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + parser.add_argument(dest=self.name, nargs=self.nargs, obj=self) diff --git a/zhdo.space/lib/python3.9/site-packages/click/decorators.py b/zhdo.space/lib/python3.9/site-packages/click/decorators.py new file mode 100644 index 0000000..28618dc --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/click/decorators.py @@ -0,0 +1,497 @@ +import inspect +import types +import typing as t +from functools import update_wrapper +from gettext import gettext as _ + +from .core import Argument +from .core import Command +from .core import Context +from .core import Group +from .core import Option +from .core import Parameter +from .globals import get_current_context +from .utils import echo + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +FC = t.TypeVar("FC", bound=t.Union[t.Callable[..., t.Any], Command]) + + +def pass_context(f: F) -> F: + """Marks a callback as wanting to receive the current context + object as first argument. + """ + + def new_func(*args, **kwargs): # type: ignore + return f(get_current_context(), *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def pass_obj(f: F) -> F: + """Similar to :func:`pass_context`, but only pass the object on the + context onwards (:attr:`Context.obj`). This is useful if that object + represents the state of a nested system. + """ + + def new_func(*args, **kwargs): # type: ignore + return f(get_current_context().obj, *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def make_pass_decorator( + object_type: t.Type, ensure: bool = False +) -> "t.Callable[[F], F]": + """Given an object type this creates a decorator that will work + similar to :func:`pass_obj` but instead of passing the object of the + current context, it will find the innermost context of type + :func:`object_type`. + + This generates a decorator that works roughly like this:: + + from functools import update_wrapper + + def decorator(f): + @pass_context + def new_func(ctx, *args, **kwargs): + obj = ctx.find_object(object_type) + return ctx.invoke(f, obj, *args, **kwargs) + return update_wrapper(new_func, f) + return decorator + + :param object_type: the type of the object to pass. + :param ensure: if set to `True`, a new object will be created and + remembered on the context if it's not there yet. + """ + + def decorator(f: F) -> F: + def new_func(*args, **kwargs): # type: ignore + ctx = get_current_context() + + if ensure: + obj = ctx.ensure_object(object_type) + else: + obj = ctx.find_object(object_type) + + if obj is None: + raise RuntimeError( + "Managed to invoke callback without a context" + f" object of type {object_type.__name__!r}" + " existing." + ) + + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + return decorator + + +def pass_meta_key( + key: str, *, doc_description: t.Optional[str] = None +) -> "t.Callable[[F], F]": + """Create a decorator that passes a key from + :attr:`click.Context.meta` as the first argument to the decorated + function. + + :param key: Key in ``Context.meta`` to pass. + :param doc_description: Description of the object being passed, + inserted into the decorator's docstring. Defaults to "the 'key' + key from Context.meta". + + .. versionadded:: 8.0 + """ + + def decorator(f: F) -> F: + def new_func(*args, **kwargs): # type: ignore + ctx = get_current_context() + obj = ctx.meta[key] + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + if doc_description is None: + doc_description = f"the {key!r} key from :attr:`click.Context.meta`" + + decorator.__doc__ = ( + f"Decorator that passes {doc_description} as the first argument" + " to the decorated function." + ) + return decorator + + +CmdType = t.TypeVar("CmdType", bound=Command) + + +@t.overload +def command( + __func: t.Callable[..., t.Any], +) -> Command: + ... + + +@t.overload +def command( + name: t.Optional[str] = None, + **attrs: t.Any, +) -> t.Callable[..., Command]: + ... + + +@t.overload +def command( + name: t.Optional[str] = None, + cls: t.Type[CmdType] = ..., + **attrs: t.Any, +) -> t.Callable[..., CmdType]: + ... + + +def command( + name: t.Union[str, t.Callable[..., t.Any], None] = None, + cls: t.Optional[t.Type[Command]] = None, + **attrs: t.Any, +) -> t.Union[Command, t.Callable[..., Command]]: + r"""Creates a new :class:`Command` and uses the decorated function as + callback. This will also automatically attach all decorated + :func:`option`\s and :func:`argument`\s as parameters to the command. + + The name of the command defaults to the name of the function with + underscores replaced by dashes. If you want to change that, you can + pass the intended name as the first argument. + + All keyword arguments are forwarded to the underlying command class. + For the ``params`` argument, any decorated params are appended to + the end of the list. + + Once decorated the function turns into a :class:`Command` instance + that can be invoked as a command line utility or be attached to a + command :class:`Group`. + + :param name: the name of the command. This defaults to the function + name with underscores replaced by dashes. + :param cls: the command class to instantiate. This defaults to + :class:`Command`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.1 + The ``params`` argument can be used. Decorated params are + appended to the end of the list. + """ + + func: t.Optional[t.Callable[..., t.Any]] = None + + if callable(name): + func = name + name = None + assert cls is None, "Use 'command(cls=cls)(callable)' to specify a class." + assert not attrs, "Use 'command(**kwargs)(callable)' to provide arguments." + + if cls is None: + cls = Command + + def decorator(f: t.Callable[..., t.Any]) -> Command: + if isinstance(f, Command): + raise TypeError("Attempted to convert a callback into a command twice.") + + attr_params = attrs.pop("params", None) + params = attr_params if attr_params is not None else [] + + try: + decorator_params = f.__click_params__ # type: ignore + except AttributeError: + pass + else: + del f.__click_params__ # type: ignore + params.extend(reversed(decorator_params)) + + if attrs.get("help") is None: + attrs["help"] = f.__doc__ + + cmd = cls( # type: ignore[misc] + name=name or f.__name__.lower().replace("_", "-"), # type: ignore[arg-type] + callback=f, + params=params, + **attrs, + ) + cmd.__doc__ = f.__doc__ + return cmd + + if func is not None: + return decorator(func) + + return decorator + + +@t.overload +def group( + __func: t.Callable[..., t.Any], +) -> Group: + ... + + +@t.overload +def group( + name: t.Optional[str] = None, + **attrs: t.Any, +) -> t.Callable[[F], Group]: + ... + + +def group( + name: t.Union[str, t.Callable[..., t.Any], None] = None, **attrs: t.Any +) -> t.Union[Group, t.Callable[[F], Group]]: + """Creates a new :class:`Group` with a function as callback. This + works otherwise the same as :func:`command` just that the `cls` + parameter is set to :class:`Group`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + """ + if attrs.get("cls") is None: + attrs["cls"] = Group + + if callable(name): + grp: t.Callable[[F], Group] = t.cast(Group, command(**attrs)) + return grp(name) + + return t.cast(Group, command(name, **attrs)) + + +def _param_memo(f: FC, param: Parameter) -> None: + if isinstance(f, Command): + f.params.append(param) + else: + if not hasattr(f, "__click_params__"): + f.__click_params__ = [] # type: ignore + + f.__click_params__.append(param) # type: ignore + + +def argument(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]: + """Attaches an argument to the command. All positional arguments are + passed as parameter declarations to :class:`Argument`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Argument` instance manually + and attaching it to the :attr:`Command.params` list. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + """ + + def decorator(f: FC) -> FC: + ArgumentClass = attrs.pop("cls", None) or Argument + _param_memo(f, ArgumentClass(param_decls, **attrs)) + return f + + return decorator + + +def option(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]: + """Attaches an option to the command. All positional arguments are + passed as parameter declarations to :class:`Option`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Option` instance manually + and attaching it to the :attr:`Command.params` list. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + """ + + def decorator(f: FC) -> FC: + # Issue 926, copy attrs, so pre-defined options can re-use the same cls= + option_attrs = attrs.copy() + OptionClass = option_attrs.pop("cls", None) or Option + _param_memo(f, OptionClass(param_decls, **option_attrs)) + return f + + return decorator + + +def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--yes`` option which shows a prompt before continuing if + not passed. If the prompt is declined, the program will exit. + + :param param_decls: One or more option names. Defaults to the single + value ``"--yes"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value: + ctx.abort() + + if not param_decls: + param_decls = ("--yes",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("callback", callback) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("prompt", "Do you want to continue?") + kwargs.setdefault("help", "Confirm the action without prompting.") + return option(*param_decls, **kwargs) + + +def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--password`` option which prompts for a password, hiding + input and asking to enter the value again for confirmation. + + :param param_decls: One or more option names. Defaults to the single + value ``"--password"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + if not param_decls: + param_decls = ("--password",) + + kwargs.setdefault("prompt", True) + kwargs.setdefault("confirmation_prompt", True) + kwargs.setdefault("hide_input", True) + return option(*param_decls, **kwargs) + + +def version_option( + version: t.Optional[str] = None, + *param_decls: str, + package_name: t.Optional[str] = None, + prog_name: t.Optional[str] = None, + message: t.Optional[str] = None, + **kwargs: t.Any, +) -> t.Callable[[FC], FC]: + """Add a ``--version`` option which immediately prints the version + number and exits the program. + + If ``version`` is not provided, Click will try to detect it using + :func:`importlib.metadata.version` to get the version for the + ``package_name``. On Python < 3.8, the ``importlib_metadata`` + backport must be installed. + + If ``package_name`` is not provided, Click will try to detect it by + inspecting the stack frames. This will be used to detect the + version, so it must match the name of the installed package. + + :param version: The version number to show. If not provided, Click + will try to detect it. + :param param_decls: One or more option names. Defaults to the single + value ``"--version"``. + :param package_name: The package name to detect the version from. If + not provided, Click will try to detect it. + :param prog_name: The name of the CLI to show in the message. If not + provided, it will be detected from the command. + :param message: The message to show. The values ``%(prog)s``, + ``%(package)s``, and ``%(version)s`` are available. Defaults to + ``"%(prog)s, version %(version)s"``. + :param kwargs: Extra arguments are passed to :func:`option`. + :raise RuntimeError: ``version`` could not be detected. + + .. versionchanged:: 8.0 + Add the ``package_name`` parameter, and the ``%(package)s`` + value for messages. + + .. versionchanged:: 8.0 + Use :mod:`importlib.metadata` instead of ``pkg_resources``. The + version is detected based on the package name, not the entry + point name. The Python package name must match the installed + package name, or be passed with ``package_name=``. + """ + if message is None: + message = _("%(prog)s, version %(version)s") + + if version is None and package_name is None: + frame = inspect.currentframe() + f_back = frame.f_back if frame is not None else None + f_globals = f_back.f_globals if f_back is not None else None + # break reference cycle + # https://docs.python.org/3/library/inspect.html#the-interpreter-stack + del frame + + if f_globals is not None: + package_name = f_globals.get("__name__") + + if package_name == "__main__": + package_name = f_globals.get("__package__") + + if package_name: + package_name = package_name.partition(".")[0] + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + nonlocal prog_name + nonlocal version + + if prog_name is None: + prog_name = ctx.find_root().info_name + + if version is None and package_name is not None: + metadata: t.Optional[types.ModuleType] + + try: + from importlib import metadata # type: ignore + except ImportError: + # Python < 3.8 + import importlib_metadata as metadata # type: ignore + + try: + version = metadata.version(package_name) # type: ignore + except metadata.PackageNotFoundError: # type: ignore + raise RuntimeError( + f"{package_name!r} is not installed. Try passing" + " 'package_name' instead." + ) from None + + if version is None: + raise RuntimeError( + f"Could not determine the version for {package_name!r} automatically." + ) + + echo( + t.cast(str, message) + % {"prog": prog_name, "package": package_name, "version": version}, + color=ctx.color, + ) + ctx.exit() + + if not param_decls: + param_decls = ("--version",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show the version and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) + + +def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--help`` option which immediately prints the help page + and exits the program. + + This is usually unnecessary, as the ``--help`` option is added to + each command automatically unless ``add_help_option=False`` is + passed. + + :param param_decls: One or more option names. Defaults to the single + value ``"--help"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + if not param_decls: + param_decls = ("--help",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show this message and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) diff --git a/zhdo.space/lib/python3.9/site-packages/click/exceptions.py b/zhdo.space/lib/python3.9/site-packages/click/exceptions.py new file mode 100644 index 0000000..9e20b3e --- /dev/null +++ b/zhdo.space/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/zhdo.space/lib/python3.9/site-packages/click/formatting.py b/zhdo.space/lib/python3.9/site-packages/click/formatting.py new file mode 100644 index 0000000..ddd2a2f --- /dev/null +++ b/zhdo.space/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/zhdo.space/lib/python3.9/site-packages/click/globals.py b/zhdo.space/lib/python3.9/site-packages/click/globals.py new file mode 100644 index 0000000..480058f --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/click/globals.py @@ -0,0 +1,68 @@ +import typing as t +from threading import local + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + +_local = local() + + +@t.overload +def get_current_context(silent: "te.Literal[False]" = False) -> "Context": + ... + + +@t.overload +def get_current_context(silent: bool = ...) -> t.Optional["Context"]: + ... + + +def get_current_context(silent: bool = False) -> t.Optional["Context"]: + """Returns the current click context. This can be used as a way to + access the current context object from anywhere. This is a more implicit + alternative to the :func:`pass_context` decorator. This function is + primarily useful for helpers such as :func:`echo` which might be + interested in changing its behavior based on the current context. + + To push the current context, :meth:`Context.scope` can be used. + + .. versionadded:: 5.0 + + :param silent: if set to `True` the return value is `None` if no context + is available. The default behavior is to raise a + :exc:`RuntimeError`. + """ + try: + return t.cast("Context", _local.stack[-1]) + except (AttributeError, IndexError) as e: + if not silent: + raise RuntimeError("There is no active click context.") from e + + return None + + +def push_context(ctx: "Context") -> None: + """Pushes a new context to the current stack.""" + _local.__dict__.setdefault("stack", []).append(ctx) + + +def pop_context() -> None: + """Removes the top level from the stack.""" + _local.stack.pop() + + +def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]: + """Internal helper to get the default value of the color flag. If a + value is passed it's returned unchanged, otherwise it's looked up from + the current context. + """ + if color is not None: + return color + + ctx = get_current_context(silent=True) + + if ctx is not None: + return ctx.color + + return None diff --git a/zhdo.space/lib/python3.9/site-packages/click/parser.py b/zhdo.space/lib/python3.9/site-packages/click/parser.py new file mode 100644 index 0000000..2d5a2ed --- /dev/null +++ b/zhdo.space/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``, ``append_const`` or ``count``. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + opts = [normalize_opt(opt, self.ctx) for opt in opts] + option = Option(obj, opts, dest, action=action, nargs=nargs, const=const) + self._opt_prefixes.update(option.prefixes) + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + def add_argument( + self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1 + ) -> None: + """Adds a positional argument named `dest` to the parser. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + self._args.append(Argument(obj, dest=dest, nargs=nargs)) + + def parse_args( + self, args: t.List[str] + ) -> t.Tuple[t.Dict[str, t.Any], t.List[str], t.List["CoreParameter"]]: + """Parses positional arguments and returns ``(values, args, order)`` + for the parsed options and arguments as well as the leftover + arguments if there are any. The order is a list of objects as they + appear on the command line. If arguments appear multiple times they + will be memorized multiple times as well. + """ + state = ParsingState(args) + try: + self._process_args_for_options(state) + self._process_args_for_args(state) + except UsageError: + if self.ctx is None or not self.ctx.resilient_parsing: + raise + return state.opts, state.largs, state.order + + def _process_args_for_args(self, state: ParsingState) -> None: + pargs, args = _unpack_args( + state.largs + state.rargs, [x.nargs for x in self._args] + ) + + for idx, arg in enumerate(self._args): + arg.process(pargs[idx], state) + + state.largs = args + state.rargs = [] + + def _process_args_for_options(self, state: ParsingState) -> None: + while state.rargs: + arg = state.rargs.pop(0) + arglen = len(arg) + # Double dashes always handled explicitly regardless of what + # prefixes are valid. + if arg == "--": + return + elif arg[:1] in self._opt_prefixes and arglen > 1: + self._process_opts(arg, state) + elif self.allow_interspersed_args: + state.largs.append(arg) + else: + state.rargs.insert(0, arg) + return + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # The while loop will usually consume 1 or more arguments per pass. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt( + self, opt: str, explicit_value: t.Optional[str], state: ParsingState + ) -> None: + if opt not in self._long_opt: + from difflib import get_close_matches + + possibilities = get_close_matches(opt, self._long_opt) + raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx) + + option = self._long_opt[opt] + if option.takes_value: + # At this point it's safe to modify rargs by injecting the + # explicit value, because no exception is raised in this + # branch. This means that the inserted value will be fully + # consumed. + if explicit_value is not None: + state.rargs.insert(0, explicit_value) + + value = self._get_value_from_state(opt, option, state) + + elif explicit_value is not None: + raise BadOptionUsage( + opt, _("Option {name!r} does not take a value.").format(name=opt) + ) + + else: + value = None + + option.process(value, state) + + def _match_short_opt(self, arg: str, state: ParsingState) -> None: + stop = False + i = 1 + prefix = arg[0] + unknown_options = [] + + for ch in arg[1:]: + opt = normalize_opt(f"{prefix}{ch}", self.ctx) + option = self._short_opt.get(opt) + i += 1 + + if not option: + if self.ignore_unknown_options: + unknown_options.append(ch) + continue + raise NoSuchOption(opt, ctx=self.ctx) + if option.takes_value: + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + state.rargs.insert(0, arg[i:]) + stop = True + + value = self._get_value_from_state(opt, option, state) + + else: + value = None + + option.process(value, state) + + if stop: + break + + # If we got any unknown options we re-combinate the string of the + # remaining options and re-attach the prefix, then report that + # to the state as new larg. This way there is basic combinatorics + # that can be achieved while still ignoring unknown arguments. + if self.ignore_unknown_options and unknown_options: + state.largs.append(f"{prefix}{''.join(unknown_options)}") + + def _get_value_from_state( + self, option_name: str, option: Option, state: ParsingState + ) -> t.Any: + nargs = option.nargs + + if len(state.rargs) < nargs: + if option.obj._flag_needs_value: + # Option allows omitting the value. + value = _flag_needs_value + else: + raise BadOptionUsage( + option_name, + ngettext( + "Option {name!r} requires an argument.", + "Option {name!r} requires {nargs} arguments.", + nargs, + ).format(name=option_name, nargs=nargs), + ) + elif nargs == 1: + next_rarg = state.rargs[0] + + if ( + option.obj._flag_needs_value + and isinstance(next_rarg, str) + and next_rarg[:1] in self._opt_prefixes + and len(next_rarg) > 1 + ): + # The next arg looks like the start of an option, don't + # use it as the value if omitting the value is allowed. + value = _flag_needs_value + else: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + return value + + def _process_opts(self, arg: str, state: ParsingState) -> None: + explicit_value = None + # Long option handling happens in two parts. The first part is + # supporting explicitly attached values. In any case, we will try + # to long match the option first. + if "=" in arg: + long_opt, explicit_value = arg.split("=", 1) + else: + long_opt = arg + norm_long_opt = normalize_opt(long_opt, self.ctx) + + # At this point we will match the (assumed) long option through + # the long option matching code. Note that this allows options + # like "-foo" to be matched as long options. + try: + self._match_long_opt(norm_long_opt, explicit_value, state) + except NoSuchOption: + # At this point the long option matching failed, and we need + # to try with short options. However there is a special rule + # which says, that if we have a two character options prefix + # (applies to "--foo" for instance), we do not dispatch to the + # short option code and will instead raise the no option + # error. + if arg[:2] not in self._opt_prefixes: + self._match_short_opt(arg, state) + return + + if not self.ignore_unknown_options: + raise + + state.largs.append(arg) diff --git a/zhdo.space/lib/python3.9/site-packages/click/py.typed b/zhdo.space/lib/python3.9/site-packages/click/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/zhdo.space/lib/python3.9/site-packages/click/shell_completion.py b/zhdo.space/lib/python3.9/site-packages/click/shell_completion.py new file mode 100644 index 0000000..c17a8e6 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/click/shell_completion.py @@ -0,0 +1,580 @@ +import os +import re +import typing as t +from gettext import gettext as _ + +from .core import Argument +from .core import BaseCommand +from .core import Context +from .core import MultiCommand +from .core import Option +from .core import Parameter +from .core import ParameterSource +from .parser import split_arg_string +from .utils import echo + + +def shell_complete( + cli: BaseCommand, + ctx_args: t.Dict[str, t.Any], + prog_name: str, + complete_var: str, + instruction: str, +) -> int: + """Perform shell completion for the given CLI program. + + :param cli: Command being called. + :param ctx_args: Extra arguments to pass to + ``cli.make_context``. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + :param instruction: Value of ``complete_var`` with the completion + instruction and shell, in the form ``instruction_shell``. + :return: Status code to exit with. + """ + shell, _, instruction = instruction.partition("_") + comp_cls = get_completion_class(shell) + + if comp_cls is None: + return 1 + + comp = comp_cls(cli, ctx_args, prog_name, complete_var) + + if instruction == "source": + echo(comp.source()) + return 0 + + if instruction == "complete": + echo(comp.complete()) + return 0 + + return 1 + + +class CompletionItem: + """Represents a completion value and metadata about the value. The + default metadata is ``type`` to indicate special shell handling, + and ``help`` if a shell supports showing a help string next to the + value. + + Arbitrary parameters can be passed when creating the object, and + accessed using ``item.attr``. If an attribute wasn't passed, + accessing it returns ``None``. + + :param value: The completion suggestion. + :param type: Tells the shell script to provide special completion + support for the type. Click uses ``"dir"`` and ``"file"``. + :param help: String shown next to the value if supported. + :param kwargs: Arbitrary metadata. The built-in implementations + don't use this, but custom type completions paired with custom + shell support could use it. + """ + + __slots__ = ("value", "type", "help", "_info") + + def __init__( + self, + value: t.Any, + type: str = "plain", + help: t.Optional[str] = None, + **kwargs: t.Any, + ) -> None: + self.value = value + self.type = type + self.help = help + self._info = kwargs + + def __getattr__(self, name: str) -> t.Any: + return self._info.get(name) + + +# Only Bash >= 4.4 has the nosort option. +_SOURCE_BASH = """\ +%(complete_func)s() { + local IFS=$'\\n' + local response + + response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \ +%(complete_var)s=bash_complete $1) + + for completion in $response; do + IFS=',' read type value <<< "$completion" + + if [[ $type == 'dir' ]]; then + COMPREPLY=() + compopt -o dirnames + elif [[ $type == 'file' ]]; then + COMPREPLY=() + compopt -o default + elif [[ $type == 'plain' ]]; then + COMPREPLY+=($value) + fi + done + + return 0 +} + +%(complete_func)s_setup() { + complete -o nosort -F %(complete_func)s %(prog_name)s +} + +%(complete_func)s_setup; +""" + +_SOURCE_ZSH = """\ +#compdef %(prog_name)s + +%(complete_func)s() { + local -a completions + local -a completions_with_descriptions + local -a response + (( ! $+commands[%(prog_name)s] )) && return 1 + + response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \ +%(complete_var)s=zsh_complete %(prog_name)s)}") + + for type key descr in ${response}; do + if [[ "$type" == "plain" ]]; then + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + elif [[ "$type" == "dir" ]]; then + _path_files -/ + elif [[ "$type" == "file" ]]; then + _path_files -f + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -a completions + fi +} + +compdef %(complete_func)s %(prog_name)s; +""" + +_SOURCE_FISH = """\ +function %(complete_func)s; + set -l response; + + for value in (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ +COMP_CWORD=(commandline -t) %(prog_name)s); + set response $response $value; + end; + + for completion in $response; + set -l metadata (string split "," $completion); + + if test $metadata[1] = "dir"; + __fish_complete_directories $metadata[2]; + else if test $metadata[1] = "file"; + __fish_complete_path $metadata[2]; + else if test $metadata[1] = "plain"; + echo $metadata[2]; + end; + end; +end; + +complete --no-files --command %(prog_name)s --arguments \ +"(%(complete_func)s)"; +""" + + +class ShellComplete: + """Base class for providing shell completion support. A subclass for + a given shell will override attributes and methods to implement the + completion instructions (``source`` and ``complete``). + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + + .. versionadded:: 8.0 + """ + + name: t.ClassVar[str] + """Name to register the shell as with :func:`add_completion_class`. + This is used in completion instructions (``{name}_source`` and + ``{name}_complete``). + """ + + source_template: t.ClassVar[str] + """Completion script template formatted by :meth:`source`. This must + be provided by subclasses. + """ + + def __init__( + self, + cli: BaseCommand, + ctx_args: t.Dict[str, t.Any], + prog_name: str, + complete_var: str, + ) -> None: + self.cli = cli + self.ctx_args = ctx_args + self.prog_name = prog_name + self.complete_var = complete_var + + @property + def func_name(self) -> str: + """The name of the shell function defined by the completion + script. + """ + safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), re.ASCII) + return f"_{safe_name}_completion" + + def source_vars(self) -> t.Dict[str, t.Any]: + """Vars for formatting :attr:`source_template`. + + By default this provides ``complete_func``, ``complete_var``, + and ``prog_name``. + """ + return { + "complete_func": self.func_name, + "complete_var": self.complete_var, + "prog_name": self.prog_name, + } + + def source(self) -> str: + """Produce the shell script that defines the completion + function. By default this ``%``-style formats + :attr:`source_template` with the dict returned by + :meth:`source_vars`. + """ + return self.source_template % self.source_vars() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + """Use the env vars defined by the shell script to return a + tuple of ``args, incomplete``. This must be implemented by + subclasses. + """ + raise NotImplementedError + + def get_completions( + self, args: t.List[str], incomplete: str + ) -> t.List[CompletionItem]: + """Determine the context and last complete command or parameter + from the complete args. Call that object's ``shell_complete`` + method to get the completions for the incomplete value. + + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args) + obj, incomplete = _resolve_incomplete(ctx, args, incomplete) + return obj.shell_complete(ctx, incomplete) + + def format_completion(self, item: CompletionItem) -> str: + """Format a completion item into the form recognized by the + shell script. This must be implemented by subclasses. + + :param item: Completion item to format. + """ + raise NotImplementedError + + def complete(self) -> str: + """Produce the completion data to send back to the shell. + + By default this calls :meth:`get_completion_args`, gets the + completions, then calls :meth:`format_completion` for each + completion. + """ + args, incomplete = self.get_completion_args() + completions = self.get_completions(args, incomplete) + out = [self.format_completion(item) for item in completions] + return "\n".join(out) + + +class BashComplete(ShellComplete): + """Shell completion for Bash.""" + + name = "bash" + source_template = _SOURCE_BASH + + def _check_version(self) -> None: + import subprocess + + output = subprocess.run( + ["bash", "-c", "echo ${BASH_VERSION}"], stdout=subprocess.PIPE + ) + match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode()) + + if match is not None: + major, minor = match.groups() + + if major < "4" or major == "4" and minor < "4": + raise RuntimeError( + _( + "Shell completion is not supported for Bash" + " versions older than 4.4." + ) + ) + else: + raise RuntimeError( + _("Couldn't detect Bash version, shell completion is not supported.") + ) + + def source(self) -> str: + self._check_version() + return super().source() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type},{item.value}" + + +class ZshComplete(ShellComplete): + """Shell completion for Zsh.""" + + name = "zsh" + source_template = _SOURCE_ZSH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}" + + +class FishComplete(ShellComplete): + """Shell completion for Fish.""" + + name = "fish" + source_template = _SOURCE_FISH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + incomplete = os.environ["COMP_CWORD"] + args = cwords[1:] + + # Fish stores the partial word in both COMP_WORDS and + # COMP_CWORD, remove it from complete args. + if incomplete and args and args[-1] == incomplete: + args.pop() + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + if item.help: + return f"{item.type},{item.value}\t{item.help}" + + return f"{item.type},{item.value}" + + +_available_shells: t.Dict[str, t.Type[ShellComplete]] = { + "bash": BashComplete, + "fish": FishComplete, + "zsh": ZshComplete, +} + + +def add_completion_class( + cls: t.Type[ShellComplete], name: t.Optional[str] = None +) -> None: + """Register a :class:`ShellComplete` subclass under the given name. + The name will be provided by the completion instruction environment + variable during completion. + + :param cls: The completion class that will handle completion for the + shell. + :param name: Name to register the class under. Defaults to the + class's ``name`` attribute. + """ + if name is None: + name = cls.name + + _available_shells[name] = cls + + +def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]: + """Look up a registered :class:`ShellComplete` subclass by the name + provided by the completion instruction environment variable. If the + name isn't registered, returns ``None``. + + :param shell: Name the class is registered under. + """ + return _available_shells.get(shell) + + +def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: + """Determine if the given parameter is an argument that can still + accept values. + + :param ctx: Invocation context for the command represented by the + parsed complete args. + :param param: Argument object being checked. + """ + if not isinstance(param, Argument): + return False + + assert param.name is not None + value = ctx.params[param.name] + return ( + param.nargs == -1 + or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE + or ( + param.nargs > 1 + and isinstance(value, (tuple, list)) + and len(value) < param.nargs + ) + ) + + +def _start_of_option(ctx: Context, value: str) -> bool: + """Check if the value looks like the start of an option.""" + if not value: + return False + + c = value[0] + return c in ctx._opt_prefixes + + +def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> bool: + """Determine if the given parameter is an option that needs a value. + + :param args: List of complete args before the incomplete value. + :param param: Option object being checked. + """ + if not isinstance(param, Option): + return False + + if param.is_flag or param.count: + return False + + last_option = None + + for index, arg in enumerate(reversed(args)): + if index + 1 > param.nargs: + break + + if _start_of_option(ctx, arg): + last_option = arg + + return last_option is not None and last_option in param.opts + + +def _resolve_context( + cli: BaseCommand, ctx_args: t.Dict[str, t.Any], prog_name: str, args: t.List[str] +) -> Context: + """Produce the context hierarchy starting with the command and + traversing the complete arguments. This only follows the commands, + it doesn't trigger input prompts or callbacks. + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param args: List of complete args before the incomplete value. + """ + ctx_args["resilient_parsing"] = True + ctx = cli.make_context(prog_name, args.copy(), **ctx_args) + args = ctx.protected_args + ctx.args + + while args: + command = ctx.command + + if isinstance(command, MultiCommand): + if not command.chain: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True) + args = ctx.protected_args + ctx.args + else: + while args: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + sub_ctx = cmd.make_context( + name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + resilient_parsing=True, + ) + args = sub_ctx.args + + ctx = sub_ctx + args = [*sub_ctx.protected_args, *sub_ctx.args] + else: + break + + return ctx + + +def _resolve_incomplete( + ctx: Context, args: t.List[str], incomplete: str +) -> t.Tuple[t.Union[BaseCommand, Parameter], str]: + """Find the Click object that will handle the completion of the + incomplete value. Return the object and the incomplete value. + + :param ctx: Invocation context for the command represented by + the parsed complete args. + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + # Different shells treat an "=" between a long option name and + # value differently. Might keep the value joined, return the "=" + # as a separate item, or return the split name and value. Always + # split and discard the "=" to make completion easier. + if incomplete == "=": + incomplete = "" + elif "=" in incomplete and _start_of_option(ctx, incomplete): + name, _, incomplete = incomplete.partition("=") + args.append(name) + + # The "--" marker tells Click to stop treating values as options + # even if they start with the option character. If it hasn't been + # given and the incomplete arg looks like an option, the current + # command will provide option name completions. + if "--" not in args and _start_of_option(ctx, incomplete): + return ctx.command, incomplete + + params = ctx.command.get_params(ctx) + + # If the last complete arg is an option name with an incomplete + # value, the option will provide value completions. + for param in params: + if _is_incomplete_option(ctx, args, param): + return param, incomplete + + # It's not an option name or value. The first argument without a + # parsed value will provide value completions. + for param in params: + if _is_incomplete_argument(ctx, param): + return param, incomplete + + # There were no unparsed arguments, the command may be a group that + # will provide command name completions. + return ctx.command, incomplete diff --git a/zhdo.space/lib/python3.9/site-packages/click/termui.py b/zhdo.space/lib/python3.9/site-packages/click/termui.py new file mode 100644 index 0000000..bfb2f5a --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/click/termui.py @@ -0,0 +1,787 @@ +import inspect +import io +import itertools +import os +import sys +import typing as t +from gettext import gettext as _ + +from ._compat import isatty +from ._compat import strip_ansi +from ._compat import WIN +from .exceptions import Abort +from .exceptions import UsageError +from .globals import resolve_color_default +from .types import Choice +from .types import convert_type +from .types import ParamType +from .utils import echo +from .utils import LazyFile + +if t.TYPE_CHECKING: + from ._termui_impl import ProgressBar + +V = t.TypeVar("V") + +# The prompt functions to use. The doc tools currently override these +# functions to customize how they work. +visible_prompt_func: t.Callable[[str], str] = input + +_ansi_colors = { + "black": 30, + "red": 31, + "green": 32, + "yellow": 33, + "blue": 34, + "magenta": 35, + "cyan": 36, + "white": 37, + "reset": 39, + "bright_black": 90, + "bright_red": 91, + "bright_green": 92, + "bright_yellow": 93, + "bright_blue": 94, + "bright_magenta": 95, + "bright_cyan": 96, + "bright_white": 97, +} +_ansi_reset_all = "\033[0m" + + +def hidden_prompt_func(prompt: str) -> str: + import getpass + + return getpass.getpass(prompt) + + +def _build_prompt( + text: str, + suffix: str, + show_default: bool = False, + default: t.Optional[t.Any] = None, + show_choices: bool = True, + type: t.Optional[ParamType] = None, +) -> str: + prompt = text + if type is not None and show_choices and isinstance(type, Choice): + prompt += f" ({', '.join(map(str, type.choices))})" + if default is not None and show_default: + prompt = f"{prompt} [{_format_default(default)}]" + return f"{prompt}{suffix}" + + +def _format_default(default: t.Any) -> t.Any: + if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): + return default.name # type: ignore + + return default + + +def prompt( + text: str, + default: t.Optional[t.Any] = None, + hide_input: bool = False, + confirmation_prompt: t.Union[bool, str] = False, + type: t.Optional[t.Union[ParamType, t.Any]] = None, + value_proc: t.Optional[t.Callable[[str], t.Any]] = None, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, + show_choices: bool = True, +) -> t.Any: + """Prompts a user for input. This is a convenience function that can + be used to prompt a user for input later. + + If the user aborts the input by sending an interrupt signal, this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the text to show for the prompt. + :param default: the default value to use if no input happens. If this + is not given it will prompt until it's aborted. + :param hide_input: if this is set to true then the input value will + be hidden. + :param confirmation_prompt: Prompt a second time to confirm the + value. Can be set to a string instead of ``True`` to customize + the message. + :param type: the type to use to check the value against. + :param value_proc: if this parameter is provided it's a function that + is invoked instead of the type conversion to + convert a value. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + :param show_choices: Show or hide choices if the passed type is a Choice. + For example if type is a Choice of either day or week, + show_choices is true and text is "Group by" then the + prompt will be "Group by (day, week): ". + + .. versionadded:: 8.0 + ``confirmation_prompt`` can be a custom string. + + .. versionadded:: 7.0 + Added the ``show_choices`` parameter. + + .. versionadded:: 6.0 + Added unicode support for cmd.exe on Windows. + + .. versionadded:: 4.0 + Added the `err` parameter. + + """ + + def prompt_func(text: str) -> str: + f = hidden_prompt_func if hide_input else visible_prompt_func + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(text.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + return f(" ") + except (KeyboardInterrupt, EOFError): + # getpass doesn't print a newline if the user aborts input with ^C. + # Allegedly this behavior is inherited from getpass(3). + # A doc bug has been filed at https://bugs.python.org/issue24711 + if hide_input: + echo(None, err=err) + raise Abort() from None + + if value_proc is None: + value_proc = convert_type(type, default) + + prompt = _build_prompt( + text, prompt_suffix, show_default, default, show_choices, type + ) + + if confirmation_prompt: + if confirmation_prompt is True: + confirmation_prompt = _("Repeat for confirmation") + + confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) + + while True: + while True: + value = prompt_func(prompt) + if value: + break + elif default is not None: + value = default + break + try: + result = value_proc(value) + except UsageError as e: + if hide_input: + echo(_("Error: The value you entered was invalid."), err=err) + else: + echo(_("Error: {e.message}").format(e=e), err=err) # noqa: B306 + continue + if not confirmation_prompt: + return result + while True: + value2 = prompt_func(confirmation_prompt) + is_empty = not value and not value2 + if value2 or is_empty: + break + if value == value2: + return result + echo(_("Error: The two entered values do not match."), err=err) + + +def confirm( + text: str, + default: t.Optional[bool] = False, + abort: bool = False, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, +) -> bool: + """Prompts for confirmation (yes/no question). + + If the user aborts the input by sending a interrupt signal this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the question to ask. + :param default: The default value to use when no input is given. If + ``None``, repeat until input is given. + :param abort: if this is set to `True` a negative answer aborts the + exception by raising :exc:`Abort`. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + + .. versionchanged:: 8.0 + Repeat until input is given if ``default`` is ``None``. + + .. versionadded:: 4.0 + Added the ``err`` parameter. + """ + prompt = _build_prompt( + text, + prompt_suffix, + show_default, + "y/n" if default is None else ("Y/n" if default else "y/N"), + ) + + while True: + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(prompt.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + value = visible_prompt_func(" ").lower().strip() + except (KeyboardInterrupt, EOFError): + raise Abort() from None + if value in ("y", "yes"): + rv = True + elif value in ("n", "no"): + rv = False + elif default is not None and value == "": + rv = default + else: + echo(_("Error: invalid input"), err=err) + continue + break + if abort and not rv: + raise Abort() + return rv + + +def echo_via_pager( + text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], + color: t.Optional[bool] = None, +) -> None: + """This function takes a text and shows it via an environment specific + pager on stdout. + + .. versionchanged:: 3.0 + Added the `color` flag. + + :param text_or_generator: the text to page, or alternatively, a + generator emitting the text to page. + :param color: controls if the pager supports ANSI colors or not. The + default is autodetection. + """ + color = resolve_color_default(color) + + if inspect.isgeneratorfunction(text_or_generator): + i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)() + elif isinstance(text_or_generator, str): + i = [text_or_generator] + else: + i = iter(t.cast(t.Iterable[str], text_or_generator)) + + # convert every element of i to a text type if necessary + text_generator = (el if isinstance(el, str) else str(el) for el in i) + + from ._termui_impl import pager + + return pager(itertools.chain(text_generator, "\n"), color) + + +def progressbar( + iterable: t.Optional[t.Iterable[V]] = None, + length: t.Optional[int] = None, + label: t.Optional[str] = None, + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + fill_char: str = "#", + empty_char: str = "-", + bar_template: str = "%(label)s [%(bar)s] %(info)s", + info_sep: str = " ", + width: int = 36, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, +) -> "ProgressBar[V]": + """This function creates an iterable context manager that can be used + to iterate over something while showing a progress bar. It will + either iterate over the `iterable` or `length` items (that are counted + up). While iteration happens, this function will print a rendered + progress bar to the given `file` (defaults to stdout) and will attempt + to calculate remaining time and more. By default, this progress bar + will not be rendered if the file is not a terminal. + + The context manager creates the progress bar. When the context + manager is entered the progress bar is already created. With every + iteration over the progress bar, the iterable passed to the bar is + advanced and the bar is updated. When the context manager exits, + a newline is printed and the progress bar is finalized on screen. + + Note: The progress bar is currently designed for use cases where the + total progress can be expected to take at least several seconds. + Because of this, the ProgressBar class object won't display + progress that is considered too fast, and progress where the time + between steps is less than a second. + + No printing must happen or the progress bar will be unintentionally + destroyed. + + Example usage:: + + with progressbar(items) as bar: + for item in bar: + do_something_with(item) + + Alternatively, if no iterable is specified, one can manually update the + progress bar through the `update()` method instead of directly + iterating over the progress bar. The update method accepts the number + of steps to increment the bar with:: + + with progressbar(length=chunks.total_bytes) as bar: + for chunk in chunks: + process_chunk(chunk) + bar.update(chunks.bytes) + + The ``update()`` method also takes an optional value specifying the + ``current_item`` at the new position. This is useful when used + together with ``item_show_func`` to customize the output for each + manual step:: + + with click.progressbar( + length=total_size, + label='Unzipping archive', + item_show_func=lambda a: a.filename + ) as bar: + for archive in zip_file: + archive.extract() + bar.update(archive.size, archive) + + :param iterable: an iterable to iterate over. If not provided the length + is required. + :param length: the number of items to iterate over. By default the + progressbar will attempt to ask the iterator about its + length, which might or might not work. If an iterable is + also provided this parameter can be used to override the + length. If an iterable is not provided the progress bar + will iterate over a range of that length. + :param label: the label to show next to the progress bar. + :param show_eta: enables or disables the estimated time display. This is + automatically disabled if the length cannot be + determined. + :param show_percent: enables or disables the percentage display. The + default is `True` if the iterable has a length or + `False` if not. + :param show_pos: enables or disables the absolute position display. The + default is `False`. + :param item_show_func: A function called with the current item which + can return a string to show next to the progress bar. If the + function returns ``None`` nothing is shown. The current item can + be ``None``, such as when entering and exiting the bar. + :param fill_char: the character to use to show the filled part of the + progress bar. + :param empty_char: the character to use to show the non-filled part of + the progress bar. + :param bar_template: the format string to use as template for the bar. + The parameters in it are ``label`` for the label, + ``bar`` for the progress bar and ``info`` for the + info section. + :param info_sep: the separator between multiple info items (eta etc.) + :param width: the width of the progress bar in characters, 0 means full + terminal width + :param file: The file to write to. If this is not a terminal then + only the label is printed. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are included anywhere in the progress bar output + which is not the case by default. + :param update_min_steps: Render only when this many updates have + completed. This allows tuning for very fast iterators. + + .. versionchanged:: 8.0 + Output is shown even if execution time is less than 0.5 seconds. + + .. versionchanged:: 8.0 + ``item_show_func`` shows the current item, not the previous one. + + .. versionchanged:: 8.0 + Labels are echoed if the output is not a TTY. Reverts a change + in 7.0 that removed all output. + + .. versionadded:: 8.0 + Added the ``update_min_steps`` parameter. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. Added the ``update`` method to + the object. + + .. versionadded:: 2.0 + """ + from ._termui_impl import ProgressBar + + color = resolve_color_default(color) + return ProgressBar( + iterable=iterable, + length=length, + show_eta=show_eta, + show_percent=show_percent, + show_pos=show_pos, + item_show_func=item_show_func, + fill_char=fill_char, + empty_char=empty_char, + bar_template=bar_template, + info_sep=info_sep, + file=file, + label=label, + width=width, + color=color, + update_min_steps=update_min_steps, + ) + + +def clear() -> None: + """Clears the terminal screen. This will have the effect of clearing + the whole visible space of the terminal and moving the cursor to the + top left. This does not do anything if not connected to a terminal. + + .. versionadded:: 2.0 + """ + if not isatty(sys.stdout): + return + if WIN: + os.system("cls") + else: + sys.stdout.write("\033[2J\033[1;1H") + + +def _interpret_color( + color: t.Union[int, t.Tuple[int, int, int], str], offset: int = 0 +) -> str: + if isinstance(color, int): + return f"{38 + offset};5;{color:d}" + + if isinstance(color, (tuple, list)): + r, g, b = color + return f"{38 + offset};2;{r:d};{g:d};{b:d}" + + return str(_ansi_colors[color] + offset) + + +def style( + text: t.Any, + fg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bold: t.Optional[bool] = None, + dim: t.Optional[bool] = None, + underline: t.Optional[bool] = None, + overline: t.Optional[bool] = None, + italic: t.Optional[bool] = None, + blink: t.Optional[bool] = None, + reverse: t.Optional[bool] = None, + strikethrough: t.Optional[bool] = None, + reset: bool = True, +) -> str: + """Styles a text with ANSI styles and returns the new string. By + default the styling is self contained which means that at the end + of the string a reset code is issued. This can be prevented by + passing ``reset=False``. + + Examples:: + + click.echo(click.style('Hello World!', fg='green')) + click.echo(click.style('ATTENTION!', blink=True)) + click.echo(click.style('Some things', reverse=True, fg='cyan')) + click.echo(click.style('More colors', fg=(255, 12, 128), bg=117)) + + Supported color names: + + * ``black`` (might be a gray) + * ``red`` + * ``green`` + * ``yellow`` (might be an orange) + * ``blue`` + * ``magenta`` + * ``cyan`` + * ``white`` (might be light gray) + * ``bright_black`` + * ``bright_red`` + * ``bright_green`` + * ``bright_yellow`` + * ``bright_blue`` + * ``bright_magenta`` + * ``bright_cyan`` + * ``bright_white`` + * ``reset`` (reset the color code only) + + If the terminal supports it, color may also be specified as: + + - An integer in the interval [0, 255]. The terminal must support + 8-bit/256-color mode. + - An RGB tuple of three integers in [0, 255]. The terminal must + support 24-bit/true-color mode. + + See https://en.wikipedia.org/wiki/ANSI_color and + https://gist.github.com/XVilka/8346728 for more information. + + :param text: the string to style with ansi codes. + :param fg: if provided this will become the foreground color. + :param bg: if provided this will become the background color. + :param bold: if provided this will enable or disable bold mode. + :param dim: if provided this will enable or disable dim mode. This is + badly supported. + :param underline: if provided this will enable or disable underline. + :param overline: if provided this will enable or disable overline. + :param italic: if provided this will enable or disable italic. + :param blink: if provided this will enable or disable blinking. + :param reverse: if provided this will enable or disable inverse + rendering (foreground becomes background and the + other way round). + :param strikethrough: if provided this will enable or disable + striking through text. + :param reset: by default a reset-all code is added at the end of the + string which means that styles do not carry over. This + can be disabled to compose styles. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. + + .. versionchanged:: 8.0 + Added support for 256 and RGB color codes. + + .. versionchanged:: 8.0 + Added the ``strikethrough``, ``italic``, and ``overline`` + parameters. + + .. versionchanged:: 7.0 + Added support for bright colors. + + .. versionadded:: 2.0 + """ + if not isinstance(text, str): + text = str(text) + + bits = [] + + if fg: + try: + bits.append(f"\033[{_interpret_color(fg)}m") + except KeyError: + raise TypeError(f"Unknown color {fg!r}") from None + + if bg: + try: + bits.append(f"\033[{_interpret_color(bg, 10)}m") + except KeyError: + raise TypeError(f"Unknown color {bg!r}") from None + + if bold is not None: + bits.append(f"\033[{1 if bold else 22}m") + if dim is not None: + bits.append(f"\033[{2 if dim else 22}m") + if underline is not None: + bits.append(f"\033[{4 if underline else 24}m") + if overline is not None: + bits.append(f"\033[{53 if overline else 55}m") + if italic is not None: + bits.append(f"\033[{3 if italic else 23}m") + if blink is not None: + bits.append(f"\033[{5 if blink else 25}m") + if reverse is not None: + bits.append(f"\033[{7 if reverse else 27}m") + if strikethrough is not None: + bits.append(f"\033[{9 if strikethrough else 29}m") + bits.append(text) + if reset: + bits.append(_ansi_reset_all) + return "".join(bits) + + +def unstyle(text: str) -> str: + """Removes ANSI styling information from a string. Usually it's not + necessary to use this function as Click's echo function will + automatically remove styling if necessary. + + .. versionadded:: 2.0 + + :param text: the text to remove style information from. + """ + return strip_ansi(text) + + +def secho( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.AnyStr]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, + **styles: t.Any, +) -> None: + """This function combines :func:`echo` and :func:`style` into one + call. As such the following two calls are the same:: + + click.secho('Hello World!', fg='green') + click.echo(click.style('Hello World!', fg='green')) + + All keyword arguments are forwarded to the underlying functions + depending on which one they go with. + + Non-string types will be converted to :class:`str`. However, + :class:`bytes` are passed directly to :meth:`echo` without applying + style. If you want to style bytes that represent text, call + :meth:`bytes.decode` first. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. Bytes are + passed through without style applied. + + .. versionadded:: 2.0 + """ + if message is not None and not isinstance(message, (bytes, bytearray)): + message = style(message, **styles) + + return echo(message, file=file, nl=nl, err=err, color=color) + + +def edit( + text: t.Optional[t.AnyStr] = None, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + filename: t.Optional[str] = None, +) -> t.Optional[t.AnyStr]: + r"""Edits the given text in the defined editor. If an editor is given + (should be the full path to the executable but the regular operating + system search path is used for finding the executable) it overrides + the detected editor. Optionally, some environment variables can be + used. If the editor is closed without changes, `None` is returned. In + case a file is edited directly the return value is always `None` and + `require_save` and `extension` are ignored. + + If the editor cannot be opened a :exc:`UsageError` is raised. + + Note for Windows: to simplify cross-platform usage, the newlines are + automatically converted from POSIX to Windows and vice versa. As such, + the message here will have ``\n`` as newline markers. + + :param text: the text to edit. + :param editor: optionally the editor to use. Defaults to automatic + detection. + :param env: environment variables to forward to the editor. + :param require_save: if this is true, then not saving in the editor + will make the return value become `None`. + :param extension: the extension to tell the editor about. This defaults + to `.txt` but changing this might change syntax + highlighting. + :param filename: if provided it will edit this file instead of the + provided text contents. It will not use a temporary + file as an indirection in that case. + """ + from ._termui_impl import Editor + + ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension) + + if filename is None: + return ed.edit(text) + + ed.edit_file(filename) + return None + + +def launch(url: str, wait: bool = False, locate: bool = False) -> int: + """This function launches the given URL (or filename) in the default + viewer application for this file type. If this is an executable, it + might launch the executable in a new session. The return value is + the exit code of the launched application. Usually, ``0`` indicates + success. + + Examples:: + + click.launch('https://click.palletsprojects.com/') + click.launch('/my/downloaded/file', locate=True) + + .. versionadded:: 2.0 + + :param url: URL or filename of the thing to launch. + :param wait: Wait for the program to exit before returning. This + only works if the launched program blocks. In particular, + ``xdg-open`` on Linux does not block. + :param locate: if this is set to `True` then instead of launching the + application associated with the URL it will attempt to + launch a file manager with the file located. This + might have weird effects if the URL does not point to + the filesystem. + """ + from ._termui_impl import open_url + + return open_url(url, wait=wait, locate=locate) + + +# If this is provided, getchar() calls into this instead. This is used +# for unittesting purposes. +_getchar: t.Optional[t.Callable[[bool], str]] = None + + +def getchar(echo: bool = False) -> str: + """Fetches a single character from the terminal and returns it. This + will always return a unicode character and under certain rare + circumstances this might return more than one character. The + situations which more than one character is returned is when for + whatever reason multiple characters end up in the terminal buffer or + standard input was not actually a terminal. + + Note that this will always read from the terminal, even if something + is piped into the standard input. + + Note for Windows: in rare cases when typing non-ASCII characters, this + function might wait for a second character and then return both at once. + This is because certain Unicode characters look like special-key markers. + + .. versionadded:: 2.0 + + :param echo: if set to `True`, the character read will also show up on + the terminal. The default is to not show it. + """ + global _getchar + + if _getchar is None: + from ._termui_impl import getchar as f + + _getchar = f + + return _getchar(echo) + + +def raw_terminal() -> t.ContextManager[int]: + from ._termui_impl import raw_terminal as f + + return f() + + +def pause(info: t.Optional[str] = None, err: bool = False) -> None: + """This command stops execution and waits for the user to press any + key to continue. This is similar to the Windows batch "pause" + command. If the program is not run through a terminal, this command + will instead do nothing. + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param info: The message to print before pausing. Defaults to + ``"Press any key to continue..."``. + :param err: if set to message goes to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + if not isatty(sys.stdin) or not isatty(sys.stdout): + return + + if info is None: + info = _("Press any key to continue...") + + try: + if info: + echo(info, nl=False, err=err) + try: + getchar() + except (KeyboardInterrupt, EOFError): + pass + finally: + if info: + echo(err=err) diff --git a/zhdo.space/lib/python3.9/site-packages/click/testing.py b/zhdo.space/lib/python3.9/site-packages/click/testing.py new file mode 100644 index 0000000..e395c2e --- /dev/null +++ b/zhdo.space/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() + dt = tempfile.mkdtemp(dir=temp_dir) # type: ignore[type-var] + os.chdir(dt) + + try: + yield t.cast(str, dt) + finally: + os.chdir(cwd) + + if temp_dir is None: + try: + shutil.rmtree(dt) + except OSError: # noqa: B014 + pass diff --git a/zhdo.space/lib/python3.9/site-packages/click/types.py b/zhdo.space/lib/python3.9/site-packages/click/types.py new file mode 100644 index 0000000..b45ee53 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/click/types.py @@ -0,0 +1,1073 @@ +import os +import stat +import typing as t +from datetime import datetime +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import _get_argv_encoding +from ._compat import get_filesystem_encoding +from ._compat import open_stream +from .exceptions import BadParameter +from .utils import LazyFile +from .utils import safecall + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + from .core import Parameter + from .shell_completion import CompletionItem + + +class ParamType: + """Represents the type of a parameter. Validates and converts values + from the command line or Python into the correct type. + + To implement a custom type, subclass and implement at least the + following: + + - The :attr:`name` class attribute must be set. + - Calling an instance of the type with ``None`` must return + ``None``. This is already implemented by default. + - :meth:`convert` must convert string values to the correct type. + - :meth:`convert` must accept values that are already the correct + type. + - It must be able to convert a value if the ``ctx`` and ``param`` + arguments are ``None``. This can occur when converting prompt + input. + """ + + is_composite: t.ClassVar[bool] = False + arity: t.ClassVar[int] = 1 + + #: the descriptive name of this type + name: str + + #: if a list of this type is expected and the value is pulled from a + #: string environment variable, this is what splits it up. `None` + #: means any whitespace. For all parameters the general rule is that + #: whitespace splits them up. The exception are paths and files which + #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on + #: Windows). + envvar_list_splitter: t.ClassVar[t.Optional[str]] = None + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + # The class name without the "ParamType" suffix. + param_type = type(self).__name__.partition("ParamType")[0] + param_type = param_type.partition("ParameterType")[0] + + # Custom subclasses might not remember to set a name. + if hasattr(self, "name"): + name = self.name + else: + name = param_type + + return {"param_type": param_type, "name": name} + + def __call__( + self, + value: t.Any, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> t.Any: + if value is not None: + return self.convert(value, param, ctx) + + def get_metavar(self, param: "Parameter") -> t.Optional[str]: + """Returns the metavar default for this param if it provides one.""" + + def get_missing_message(self, param: "Parameter") -> t.Optional[str]: + """Optionally might return extra information about a missing + parameter. + + .. versionadded:: 2.0 + """ + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + """Convert the value to the correct type. This is not called if + the value is ``None`` (the missing value). + + This must accept string values from the command line, as well as + values that are already the correct type. It may also convert + other compatible types. + + The ``param`` and ``ctx`` arguments may be ``None`` in certain + situations, such as when converting prompt input. + + If the value cannot be converted, call :meth:`fail` with a + descriptive message. + + :param value: The value to convert. + :param param: The parameter that is using this type to convert + its value. May be ``None``. + :param ctx: The current context that arrived at this value. May + be ``None``. + """ + return value + + def split_envvar_value(self, rv: str) -> t.Sequence[str]: + """Given a value from an environment variable this splits it up + into small chunks depending on the defined envvar list splitter. + + If the splitter is set to `None`, which means that whitespace splits, + then leading and trailing whitespace is ignored. Otherwise, leading + and trailing splitters usually lead to empty items being included. + """ + return (rv or "").split(self.envvar_list_splitter) + + def fail( + self, + message: str, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> "t.NoReturn": + """Helper method to fail with an invalid value message.""" + raise BadParameter(message, ctx=ctx, param=param) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a list of + :class:`~click.shell_completion.CompletionItem` objects for the + incomplete value. Most types do not provide completions, but + some do, and this allows custom types to provide custom + completions as well. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + return [] + + +class CompositeParamType(ParamType): + is_composite = True + + @property + def arity(self) -> int: # type: ignore + raise NotImplementedError() + + +class FuncParamType(ParamType): + def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None: + self.name = func.__name__ + self.func = func + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["func"] = self.func + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self.func(value) + except ValueError: + try: + value = str(value) + except UnicodeError: + value = value.decode("utf-8", "replace") + + self.fail(value, param, ctx) + + +class UnprocessedParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + return value + + def __repr__(self) -> str: + return "UNPROCESSED" + + +class StringParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, bytes): + enc = _get_argv_encoding() + try: + value = value.decode(enc) + except UnicodeError: + fs_enc = get_filesystem_encoding() + if fs_enc != enc: + try: + value = value.decode(fs_enc) + except UnicodeError: + value = value.decode("utf-8", "replace") + else: + value = value.decode("utf-8", "replace") + return value + return str(value) + + def __repr__(self) -> str: + return "STRING" + + +class Choice(ParamType): + """The choice type allows a value to be checked against a fixed set + of supported values. All of these values have to be strings. + + You should only pass a list or tuple of choices. Other iterables + (like generators) may lead to surprising results. + + The resulting value will always be one of the originally passed choices + regardless of ``case_sensitive`` or any ``ctx.token_normalize_func`` + being specified. + + See :ref:`choice-opts` for an example. + + :param case_sensitive: Set to false to make choices case + insensitive. Defaults to true. + """ + + name = "choice" + + def __init__(self, choices: t.Sequence[str], case_sensitive: bool = True) -> None: + self.choices = choices + self.case_sensitive = case_sensitive + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["choices"] = self.choices + info_dict["case_sensitive"] = self.case_sensitive + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + choices_str = "|".join(self.choices) + + # Use curly braces to indicate a required argument. + if param.required and param.param_type_name == "argument": + return f"{{{choices_str}}}" + + # Use square braces to indicate an option or optional argument. + return f"[{choices_str}]" + + def get_missing_message(self, param: "Parameter") -> str: + return _("Choose from:\n\t{choices}").format(choices=",\n\t".join(self.choices)) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + # Match through normalization and case sensitivity + # first do token_normalize_func, then lowercase + # preserve original `value` to produce an accurate message in + # `self.fail` + normed_value = value + normed_choices = {choice: choice for choice in self.choices} + + if ctx is not None and ctx.token_normalize_func is not None: + normed_value = ctx.token_normalize_func(value) + normed_choices = { + ctx.token_normalize_func(normed_choice): original + for normed_choice, original in normed_choices.items() + } + + if not self.case_sensitive: + normed_value = normed_value.casefold() + normed_choices = { + normed_choice.casefold(): original + for normed_choice, original in normed_choices.items() + } + + if normed_value in normed_choices: + return normed_choices[normed_value] + + choices_str = ", ".join(map(repr, self.choices)) + self.fail( + ngettext( + "{value!r} is not {choice}.", + "{value!r} is not one of {choices}.", + len(self.choices), + ).format(value=value, choice=choices_str, choices=choices_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return f"Choice({list(self.choices)})" + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Complete choices that start with the incomplete value. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + str_choices = map(str, self.choices) + + if self.case_sensitive: + matched = (c for c in str_choices if c.startswith(incomplete)) + else: + incomplete = incomplete.lower() + matched = (c for c in str_choices if c.lower().startswith(incomplete)) + + return [CompletionItem(c) for c in matched] + + +class DateTime(ParamType): + """The DateTime type converts date strings into `datetime` objects. + + The format strings which are checked are configurable, but default to some + common (non-timezone aware) ISO 8601 formats. + + When specifying *DateTime* formats, you should only pass a list or a tuple. + Other iterables, like generators, may lead to surprising results. + + The format strings are processed using ``datetime.strptime``, and this + consequently defines the format strings which are allowed. + + Parsing is tried using each format, in order, and the first format which + parses successfully is used. + + :param formats: A list or tuple of date format strings, in the order in + which they should be tried. Defaults to + ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, + ``'%Y-%m-%d %H:%M:%S'``. + """ + + name = "datetime" + + def __init__(self, formats: t.Optional[t.Sequence[str]] = None): + self.formats = formats or ["%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S"] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["formats"] = self.formats + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + return f"[{'|'.join(self.formats)}]" + + def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]: + try: + return datetime.strptime(value, format) + except ValueError: + return None + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, datetime): + return value + + for format in self.formats: + converted = self._try_to_convert_date(value, format) + + if converted is not None: + return converted + + formats_str = ", ".join(map(repr, self.formats)) + self.fail( + ngettext( + "{value!r} does not match the format {format}.", + "{value!r} does not match the formats {formats}.", + len(self.formats), + ).format(value=value, format=formats_str, formats=formats_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return "DateTime" + + +class _NumberParamTypeBase(ParamType): + _number_class: t.ClassVar[t.Type] + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self._number_class(value) + except ValueError: + self.fail( + _("{value!r} is not a valid {number_type}.").format( + value=value, number_type=self.name + ), + param, + ctx, + ) + + +class _NumberRangeBase(_NumberParamTypeBase): + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + self.min = min + self.max = max + self.min_open = min_open + self.max_open = max_open + self.clamp = clamp + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + min=self.min, + max=self.max, + min_open=self.min_open, + max_open=self.max_open, + clamp=self.clamp, + ) + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import operator + + rv = super().convert(value, param, ctx) + lt_min: bool = self.min is not None and ( + operator.le if self.min_open else operator.lt + )(rv, self.min) + gt_max: bool = self.max is not None and ( + operator.ge if self.max_open else operator.gt + )(rv, self.max) + + if self.clamp: + if lt_min: + return self._clamp(self.min, 1, self.min_open) # type: ignore + + if gt_max: + return self._clamp(self.max, -1, self.max_open) # type: ignore + + if lt_min or gt_max: + self.fail( + _("{value} is not in the range {range}.").format( + value=rv, range=self._describe_range() + ), + param, + ctx, + ) + + return rv + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + """Find the valid value to clamp to bound in the given + direction. + + :param bound: The boundary value. + :param dir: 1 or -1 indicating the direction to move. + :param open: If true, the range does not include the bound. + """ + raise NotImplementedError + + def _describe_range(self) -> str: + """Describe the range for use in help text.""" + if self.min is None: + op = "<" if self.max_open else "<=" + return f"x{op}{self.max}" + + if self.max is None: + op = ">" if self.min_open else ">=" + return f"x{op}{self.min}" + + lop = "<" if self.min_open else "<=" + rop = "<" if self.max_open else "<=" + return f"{self.min}{lop}x{rop}{self.max}" + + def __repr__(self) -> str: + clamp = " clamped" if self.clamp else "" + return f"<{type(self).__name__} {self._describe_range()}{clamp}>" + + +class IntParamType(_NumberParamTypeBase): + name = "integer" + _number_class = int + + def __repr__(self) -> str: + return "INT" + + +class IntRange(_NumberRangeBase, IntParamType): + """Restrict an :data:`click.INT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "integer range" + + def _clamp( # type: ignore + self, bound: int, dir: "te.Literal[1, -1]", open: bool + ) -> int: + if not open: + return bound + + return bound + dir + + +class FloatParamType(_NumberParamTypeBase): + name = "float" + _number_class = float + + def __repr__(self) -> str: + return "FLOAT" + + +class FloatRange(_NumberRangeBase, FloatParamType): + """Restrict a :data:`click.FLOAT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. This is not supported if either + boundary is marked ``open``. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "float range" + + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + super().__init__( + min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp + ) + + if (min_open or max_open) and clamp: + raise TypeError("Clamping is not supported for open bounds.") + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + if not open: + return bound + + # Could use Python 3.9's math.nextafter here, but clamping an + # open float range doesn't seem to be particularly useful. It's + # left up to the user to write a callback to do it if needed. + raise RuntimeError("Clamping is not supported for open bounds.") + + +class BoolParamType(ParamType): + name = "boolean" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if value in {False, True}: + return bool(value) + + norm = value.strip().lower() + + if norm in {"1", "true", "t", "yes", "y", "on"}: + return True + + if norm in {"0", "false", "f", "no", "n", "off"}: + return False + + self.fail( + _("{value!r} is not a valid boolean.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "BOOL" + + +class UUIDParameterType(ParamType): + name = "uuid" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import uuid + + if isinstance(value, uuid.UUID): + return value + + value = value.strip() + + try: + return uuid.UUID(value) + except ValueError: + self.fail( + _("{value!r} is not a valid UUID.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "UUID" + + +class File(ParamType): + """Declares a parameter to be a file for reading or writing. The file + is automatically closed once the context tears down (after the command + finished working). + + Files can be opened for reading or writing. The special value ``-`` + indicates stdin or stdout depending on the mode. + + By default, the file is opened for reading text data, but it can also be + opened in binary mode or for writing. The encoding parameter can be used + to force a specific encoding. + + The `lazy` flag controls if the file should be opened immediately or upon + first IO. The default is to be non-lazy for standard input and output + streams as well as files opened for reading, `lazy` otherwise. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. + + Starting with Click 2.0, files can also be opened atomically in which + case all writes go into a separate file in the same folder and upon + completion the file will be moved over to the original location. This + is useful if a file regularly read by other users is modified. + + See :ref:`file-args` for more information. + """ + + name = "filename" + envvar_list_splitter = os.path.pathsep + + def __init__( + self, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: t.Optional[bool] = None, + atomic: bool = False, + ) -> None: + self.mode = mode + self.encoding = encoding + self.errors = errors + self.lazy = lazy + self.atomic = atomic + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update(mode=self.mode, encoding=self.encoding) + return info_dict + + def resolve_lazy_flag(self, value: t.Any) -> bool: + if self.lazy is not None: + return self.lazy + if value == "-": + return False + elif "w" in self.mode: + return True + return False + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + if hasattr(value, "read") or hasattr(value, "write"): + return value + + lazy = self.resolve_lazy_flag(value) + + if lazy: + f: t.IO = t.cast( + t.IO, + LazyFile( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ), + ) + + if ctx is not None: + ctx.call_on_close(f.close_intelligently) # type: ignore + + return f + + f, should_close = open_stream( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + # If a context is provided, we automatically close the file + # at the end of the context execution (or flush out). If a + # context does not exist, it's the caller's responsibility to + # properly close the file. This for instance happens when the + # type is used with prompts. + if ctx is not None: + if should_close: + ctx.call_on_close(safecall(f.close)) + else: + ctx.call_on_close(safecall(f.flush)) + + return f + except OSError as e: # noqa: B014 + self.fail(f"'{os.fsdecode(value)}': {e.strerror}", param, ctx) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide file path completions. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + return [CompletionItem(incomplete, type="file")] + + +class Path(ParamType): + """The ``Path`` type is similar to the :class:`File` type, but + returns the filename instead of an open file. Various checks can be + enabled to validate the type of file and permissions. + + :param exists: The file or directory needs to exist for the value to + be valid. If this is not set to ``True``, and the file does not + exist, then all further checks are silently skipped. + :param file_okay: Allow a file as a value. + :param dir_okay: Allow a directory as a value. + :param readable: if true, a readable check is performed. + :param writable: if true, a writable check is performed. + :param executable: if true, an executable check is performed. + :param resolve_path: Make the value absolute and resolve any + symlinks. A ``~`` is not expanded, as this is supposed to be + done by the shell only. + :param allow_dash: Allow a single dash as a value, which indicates + a standard stream (but does not open it). Use + :func:`~click.open_file` to handle opening this value. + :param path_type: Convert the incoming path value to this type. If + ``None``, keep Python's default, which is ``str``. Useful to + convert to :class:`pathlib.Path`. + + .. versionchanged:: 8.1 + Added the ``executable`` parameter. + + .. versionchanged:: 8.0 + Allow passing ``type=pathlib.Path``. + + .. versionchanged:: 6.0 + Added the ``allow_dash`` parameter. + """ + + envvar_list_splitter = os.path.pathsep + + def __init__( + self, + exists: bool = False, + file_okay: bool = True, + dir_okay: bool = True, + writable: bool = False, + readable: bool = True, + resolve_path: bool = False, + allow_dash: bool = False, + path_type: t.Optional[t.Type] = None, + executable: bool = False, + ): + self.exists = exists + self.file_okay = file_okay + self.dir_okay = dir_okay + self.readable = readable + self.writable = writable + self.executable = executable + self.resolve_path = resolve_path + self.allow_dash = allow_dash + self.type = path_type + + if self.file_okay and not self.dir_okay: + self.name = _("file") + elif self.dir_okay and not self.file_okay: + self.name = _("directory") + else: + self.name = _("path") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + exists=self.exists, + file_okay=self.file_okay, + dir_okay=self.dir_okay, + writable=self.writable, + readable=self.readable, + allow_dash=self.allow_dash, + ) + return info_dict + + def coerce_path_result(self, rv: t.Any) -> t.Any: + if self.type is not None and not isinstance(rv, self.type): + if self.type is str: + rv = os.fsdecode(rv) + elif self.type is bytes: + rv = os.fsencode(rv) + else: + rv = self.type(rv) + + return rv + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + rv = value + + is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") + + if not is_dash: + if self.resolve_path: + # os.path.realpath doesn't resolve symlinks on Windows + # until Python 3.8. Use pathlib for now. + import pathlib + + rv = os.fsdecode(pathlib.Path(rv).resolve()) + + try: + st = os.stat(rv) + except OSError: + if not self.exists: + return self.coerce_path_result(rv) + self.fail( + _("{name} {filename!r} does not exist.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + + if not self.file_okay and stat.S_ISREG(st.st_mode): + self.fail( + _("{name} {filename!r} is a file.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail( + _("{name} '{filename}' is a directory.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + + if self.readable and not os.access(rv, os.R_OK): + self.fail( + _("{name} {filename!r} is not readable.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + + if self.writable and not os.access(rv, os.W_OK): + self.fail( + _("{name} {filename!r} is not writable.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + + if self.executable and not os.access(value, os.X_OK): + self.fail( + _("{name} {filename!r} is not executable.").format( + name=self.name.title(), filename=os.fsdecode(value) + ), + param, + ctx, + ) + + return self.coerce_path_result(rv) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide path completions for only + directories or any paths. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + type = "dir" if self.dir_okay and not self.file_okay else "file" + return [CompletionItem(incomplete, type=type)] + + +class Tuple(CompositeParamType): + """The default behavior of Click is to apply a type on a value directly. + This works well in most cases, except for when `nargs` is set to a fixed + count and different types should be used for different items. In this + case the :class:`Tuple` type can be used. This type can only be used + if `nargs` is set to a fixed number. + + For more information see :ref:`tuple-type`. + + This can be selected by using a Python tuple literal as a type. + + :param types: a list of types that should be used for the tuple items. + """ + + def __init__(self, types: t.Sequence[t.Union[t.Type, ParamType]]) -> None: + self.types = [convert_type(ty) for ty in types] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["types"] = [t.to_info_dict() for t in self.types] + return info_dict + + @property + def name(self) -> str: # type: ignore + return f"<{' '.join(ty.name for ty in self.types)}>" + + @property + def arity(self) -> int: # type: ignore + return len(self.types) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + len_type = len(self.types) + len_value = len(value) + + if len_value != len_type: + self.fail( + ngettext( + "{len_type} values are required, but {len_value} was given.", + "{len_type} values are required, but {len_value} were given.", + len_value, + ).format(len_type=len_type, len_value=len_value), + param=param, + ctx=ctx, + ) + + return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) + + +def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> ParamType: + """Find the most appropriate :class:`ParamType` for the given Python + type. If the type isn't provided, it can be inferred from a default + value. + """ + guessed_type = False + + if ty is None and default is not None: + if isinstance(default, (tuple, list)): + # If the default is empty, ty will remain None and will + # return STRING. + if default: + item = default[0] + + # A tuple of tuples needs to detect the inner types. + # Can't call convert recursively because that would + # incorrectly unwind the tuple to a single type. + if isinstance(item, (tuple, list)): + ty = tuple(map(type, item)) + else: + ty = type(item) + else: + ty = type(default) + + guessed_type = True + + if isinstance(ty, tuple): + return Tuple(ty) + + if isinstance(ty, ParamType): + return ty + + if ty is str or ty is None: + return STRING + + if ty is int: + return INT + + if ty is float: + return FLOAT + + if ty is bool: + return BOOL + + if guessed_type: + return STRING + + if __debug__: + try: + if issubclass(ty, ParamType): + raise AssertionError( + f"Attempted to use an uninstantiated parameter type ({ty})." + ) + except TypeError: + # ty is an instance (correct), so issubclass fails. + pass + + return FuncParamType(ty) + + +#: A dummy parameter type that just does nothing. From a user's +#: perspective this appears to just be the same as `STRING` but +#: internally no string conversion takes place if the input was bytes. +#: This is usually useful when working with file paths as they can +#: appear in bytes and unicode. +#: +#: For path related uses the :class:`Path` type is a better choice but +#: there are situations where an unprocessed type is useful which is why +#: it is is provided. +#: +#: .. versionadded:: 4.0 +UNPROCESSED = UnprocessedParamType() + +#: A unicode string parameter type which is the implicit default. This +#: can also be selected by using ``str`` as type. +STRING = StringParamType() + +#: An integer parameter. This can also be selected by using ``int`` as +#: type. +INT = IntParamType() + +#: A floating point value parameter. This can also be selected by using +#: ``float`` as type. +FLOAT = FloatParamType() + +#: A boolean parameter. This is the default for boolean flags. This can +#: also be selected by using ``bool`` as a type. +BOOL = BoolParamType() + +#: A UUID parameter. +UUID = UUIDParameterType() diff --git a/zhdo.space/lib/python3.9/site-packages/click/utils.py b/zhdo.space/lib/python3.9/site-packages/click/utils.py new file mode 100644 index 0000000..8283788 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/click/utils.py @@ -0,0 +1,580 @@ +import os +import re +import sys +import typing as t +from functools import update_wrapper +from types import ModuleType + +from ._compat import _default_text_stderr +from ._compat import _default_text_stdout +from ._compat import _find_binary_writer +from ._compat import auto_wrap_for_ansi +from ._compat import binary_streams +from ._compat import get_filesystem_encoding +from ._compat import open_stream +from ._compat import should_strip_ansi +from ._compat import strip_ansi +from ._compat import text_streams +from ._compat import WIN +from .globals import resolve_color_default + +if t.TYPE_CHECKING: + import typing_extensions as te + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def _posixify(name: str) -> str: + return "-".join(name.split()).lower() + + +def safecall(func: F) -> F: + """Wraps a function so that it swallows exceptions.""" + + def wrapper(*args, **kwargs): # type: ignore + try: + return func(*args, **kwargs) + except Exception: + pass + + return update_wrapper(t.cast(F, wrapper), func) + + +def make_str(value: t.Any) -> str: + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(get_filesystem_encoding()) + except UnicodeError: + return value.decode("utf-8", "replace") + return str(value) + + +def make_default_short_help(help: str, max_length: int = 45) -> str: + """Returns a condensed version of help string.""" + # Consider only the first paragraph. + paragraph_end = help.find("\n\n") + + if paragraph_end != -1: + help = help[:paragraph_end] + + # Collapse newlines, tabs, and spaces. + words = help.split() + + if not words: + return "" + + # The first paragraph started with a "no rewrap" marker, ignore it. + if words[0] == "\b": + words = words[1:] + + total_length = 0 + last_index = len(words) - 1 + + for i, word in enumerate(words): + total_length += len(word) + (i > 0) + + if total_length > max_length: # too long, truncate + break + + if word[-1] == ".": # sentence end, truncate without "..." + return " ".join(words[: i + 1]) + + if total_length == max_length and i != last_index: + break # not at sentence end, truncate with "..." + else: + return " ".join(words) # no truncation needed + + # Account for the length of the suffix. + total_length += len("...") + + # remove words until the length is short enough + while i > 0: + total_length -= len(words[i]) + (i > 0) + + if total_length <= max_length: + break + + i -= 1 + + return " ".join(words[:i]) + "..." + + +class LazyFile: + """A lazy file works like a regular file but it does not fully open + the file but it does perform some basic checks early to see if the + filename parameter does make sense. This is useful for safely opening + files for writing. + """ + + def __init__( + self, + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, + ): + self.name = filename + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + self._f: t.Optional[t.IO] + + if filename == "-": + self._f, self.should_close = open_stream(filename, mode, encoding, errors) + else: + if "r" in mode: + # Open and close the file in case we're opening it for + # reading so that we can catch at least some errors in + # some cases early. + open(filename, mode).close() + self._f = None + self.should_close = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self.open(), name) + + def __repr__(self) -> str: + if self._f is not None: + return repr(self._f) + return f"" + + def open(self) -> t.IO: + """Opens the file if it's not yet open. This call might fail with + a :exc:`FileError`. Not handling this error will produce an error + that Click shows. + """ + if self._f is not None: + return self._f + try: + rv, self.should_close = open_stream( + self.name, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + except OSError as e: # noqa: E402 + from .exceptions import FileError + + raise FileError(self.name, hint=e.strerror) from e + self._f = rv + return rv + + def close(self) -> None: + """Closes the underlying file, no matter what.""" + if self._f is not None: + self._f.close() + + def close_intelligently(self) -> None: + """This function only closes the file if it was opened by the lazy + file wrapper. For instance this will never close stdin. + """ + if self.should_close: + self.close() + + def __enter__(self) -> "LazyFile": + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + self.close_intelligently() + + def __iter__(self) -> t.Iterator[t.AnyStr]: + self.open() + return iter(self._f) # type: ignore + + +class KeepOpenFile: + def __init__(self, file: t.IO) -> None: + self._file = file + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._file, name) + + def __enter__(self) -> "KeepOpenFile": + return self + + def __exit__(self, exc_type, exc_value, tb): # type: ignore + pass + + def __repr__(self) -> str: + return repr(self._file) + + def __iter__(self) -> t.Iterator[t.AnyStr]: + return iter(self._file) + + +def echo( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.Any]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, +) -> None: + """Print a message and newline to stdout or a file. This should be + used instead of :func:`print` because it provides better support + for different data, files, and environments. + + Compared to :func:`print`, this does the following: + + - Ensures that the output encoding is not misconfigured on Linux. + - Supports Unicode in the Windows console. + - Supports writing to binary outputs, and supports writing bytes + to text outputs. + - Supports colors and styles on Windows. + - Removes ANSI color and style codes if the output does not look + like an interactive terminal. + - Always flushes the output. + + :param message: The string or bytes to output. Other objects are + converted to strings. + :param file: The file to write to. Defaults to ``stdout``. + :param err: Write to ``stderr`` instead of ``stdout``. + :param nl: Print a newline after the message. Enabled by default. + :param color: Force showing or hiding colors and other styles. By + default Click will remove color if the output does not look like + an interactive terminal. + + .. versionchanged:: 6.0 + Support Unicode output on the Windows console. Click does not + modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()`` + will still not support Unicode. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionadded:: 3.0 + Added the ``err`` parameter. + + .. versionchanged:: 2.0 + Support colors on Windows if colorama is installed. + """ + if file is None: + if err: + file = _default_text_stderr() + else: + file = _default_text_stdout() + + # Convert non bytes/text into the native string type. + if message is not None and not isinstance(message, (str, bytes, bytearray)): + out: t.Optional[t.Union[str, bytes]] = str(message) + else: + out = message + + if nl: + out = out or "" + if isinstance(out, str): + out += "\n" + else: + out += b"\n" + + if not out: + file.flush() + return + + # If there is a message and the value looks like bytes, we manually + # need to find the binary stream and write the message in there. + # This is done separately so that most stream types will work as you + # would expect. Eg: you can write to StringIO for other cases. + if isinstance(out, (bytes, bytearray)): + binary_file = _find_binary_writer(file) + + if binary_file is not None: + file.flush() + binary_file.write(out) + binary_file.flush() + return + + # ANSI style code support. For no message or bytes, nothing happens. + # When outputting to a file instead of a terminal, strip codes. + else: + color = resolve_color_default(color) + + if should_strip_ansi(file, color): + out = strip_ansi(out) + elif WIN: + if auto_wrap_for_ansi is not None: + file = auto_wrap_for_ansi(file) # type: ignore + elif not color: + out = strip_ansi(out) + + file.write(out) # type: ignore + file.flush() + + +def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO: + """Returns a system stream for byte processing. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + """ + opener = binary_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener() + + +def get_text_stream( + name: "te.Literal['stdin', 'stdout', 'stderr']", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", +) -> t.TextIO: + """Returns a system stream for text processing. This usually returns + a wrapped stream around a binary stream returned from + :func:`get_binary_stream` but it also can take shortcuts for already + correctly configured streams. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + :param encoding: overrides the detected default encoding. + :param errors: overrides the default error mode. + """ + opener = text_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener(encoding, errors) + + +def open_file( + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: bool = False, + atomic: bool = False, +) -> t.IO: + """Open a file, with extra behavior to handle ``'-'`` to indicate + a standard stream, lazy open on write, and atomic write. Similar to + the behavior of the :class:`~click.File` param type. + + If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is + wrapped so that using it in a context manager will not close it. + This makes it possible to use the function without accidentally + closing a standard stream: + + .. code-block:: python + + with open_file(filename) as f: + ... + + :param filename: The name of the file to open, or ``'-'`` for + ``stdin``/``stdout``. + :param mode: The mode in which to open the file. + :param encoding: The encoding to decode or encode a file opened in + text mode. + :param errors: The error handling mode. + :param lazy: Wait to open the file until it is accessed. For read + mode, the file is temporarily opened to raise access errors + early, then closed until it is read again. + :param atomic: Write to a temporary file and replace the given file + on close. + + .. versionadded:: 3.0 + """ + if lazy: + return t.cast(t.IO, LazyFile(filename, mode, encoding, errors, atomic=atomic)) + + f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic) + + if not should_close: + f = t.cast(t.IO, KeepOpenFile(f)) + + return f + + +def format_filename( + filename: t.Union[str, bytes, os.PathLike], shorten: bool = False +) -> str: + """Formats a filename for user display. The main purpose of this + function is to ensure that the filename can be displayed at all. This + will decode the filename to unicode if necessary in a way that it will + not fail. Optionally, it can shorten the filename to not include the + full path to the filename. + + :param filename: formats a filename for UI display. This will also convert + the filename into unicode without failing. + :param shorten: this optionally shortens the filename to strip of the + path that leads up to it. + """ + if shorten: + filename = os.path.basename(filename) + + return os.fsdecode(filename) + + +def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str: + r"""Returns the config folder for the application. The default behavior + is to return whatever is most appropriate for the operating system. + + To give you an idea, for an app called ``"Foo Bar"``, something like + the following folders could be returned: + + Mac OS X: + ``~/Library/Application Support/Foo Bar`` + Mac OS X (POSIX): + ``~/.foo-bar`` + Unix: + ``~/.config/foo-bar`` + Unix (POSIX): + ``~/.foo-bar`` + Windows (roaming): + ``C:\Users\\AppData\Roaming\Foo Bar`` + Windows (not roaming): + ``C:\Users\\AppData\Local\Foo Bar`` + + .. versionadded:: 2.0 + + :param app_name: the application name. This should be properly capitalized + and can contain whitespace. + :param roaming: controls if the folder should be roaming or not on Windows. + Has no affect otherwise. + :param force_posix: if this is set to `True` then on any POSIX system the + folder will be stored in the home folder with a leading + dot instead of the XDG config home or darwin's + application support folder. + """ + if WIN: + key = "APPDATA" if roaming else "LOCALAPPDATA" + folder = os.environ.get(key) + if folder is None: + folder = os.path.expanduser("~") + return os.path.join(folder, app_name) + if force_posix: + return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}")) + if sys.platform == "darwin": + return os.path.join( + os.path.expanduser("~/Library/Application Support"), app_name + ) + return os.path.join( + os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")), + _posixify(app_name), + ) + + +class PacifyFlushWrapper: + """This wrapper is used to catch and suppress BrokenPipeErrors resulting + from ``.flush()`` being called on broken pipe during the shutdown/final-GC + of the Python interpreter. Notably ``.flush()`` is always called on + ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any + other cleanup code, and the case where the underlying file is not a broken + pipe, all calls and attributes are proxied. + """ + + def __init__(self, wrapped: t.IO) -> None: + self.wrapped = wrapped + + def flush(self) -> None: + try: + self.wrapped.flush() + except OSError as e: + import errno + + if e.errno != errno.EPIPE: + raise + + def __getattr__(self, attr: str) -> t.Any: + return getattr(self.wrapped, attr) + + +def _detect_program_name( + path: t.Optional[str] = None, _main: t.Optional[ModuleType] = None +) -> str: + """Determine the command used to run the program, for use in help + text. If a file or entry point was executed, the file name is + returned. If ``python -m`` was used to execute a module or package, + ``python -m name`` is returned. + + This doesn't try to be too precise, the goal is to give a concise + name for help text. Files are only shown as their name without the + path. ``python`` is only shown for modules, and the full path to + ``sys.executable`` is not shown. + + :param path: The Python file being executed. Python puts this in + ``sys.argv[0]``, which is used by default. + :param _main: The ``__main__`` module. This should only be passed + during internal testing. + + .. versionadded:: 8.0 + Based on command args detection in the Werkzeug reloader. + + :meta private: + """ + if _main is None: + _main = sys.modules["__main__"] + + if not path: + path = sys.argv[0] + + # The value of __package__ indicates how Python was called. It may + # not exist if a setuptools script is installed as an egg. It may be + # set incorrectly for entry points created with pip on Windows. + if getattr(_main, "__package__", None) is None or ( + os.name == "nt" + and _main.__package__ == "" + and not os.path.exists(path) + and os.path.exists(f"{path}.exe") + ): + # Executed a file, like "python app.py". + return os.path.basename(path) + + # Executed a module, like "python -m example". + # Rewritten by Python from "-m script" to "/path/to/script.py". + # Need to look at main module to determine how it was executed. + py_module = t.cast(str, _main.__package__) + name = os.path.splitext(os.path.basename(path))[0] + + # A submodule like "example.cli". + if name != "__main__": + py_module = f"{py_module}.{name}" + + return f"python -m {py_module.lstrip('.')}" + + +def _expand_args( + args: t.Iterable[str], + *, + user: bool = True, + env: bool = True, + glob_recursive: bool = True, +) -> t.List[str]: + """Simulate Unix shell expansion with Python functions. + + See :func:`glob.glob`, :func:`os.path.expanduser`, and + :func:`os.path.expandvars`. + + This is intended for use on Windows, where the shell does not do any + expansion. It may not exactly match what a Unix shell would do. + + :param args: List of command line arguments to expand. + :param user: Expand user home directory. + :param env: Expand environment variables. + :param glob_recursive: ``**`` matches directories recursively. + + .. versionchanged:: 8.1 + Invalid glob patterns are treated as empty expansions rather + than raising an error. + + .. versionadded:: 8.0 + + :meta private: + """ + from glob import glob + + out = [] + + for arg in args: + if user: + arg = os.path.expanduser(arg) + + if env: + arg = os.path.expandvars(arg) + + try: + matches = glob(arg, recursive=glob_recursive) + except re.error: + matches = [] + + if not matches: + out.append(arg) + else: + out.extend(matches) + + return out diff --git a/zhdo.space/lib/python3.9/site-packages/distutils-precedence.pth b/zhdo.space/lib/python3.9/site-packages/distutils-precedence.pth new file mode 100644 index 0000000..6de4198 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/distutils-precedence.pth @@ -0,0 +1 @@ +import os; var = 'SETUPTOOLS_USE_DISTUTILS'; enabled = os.environ.get(var, 'stdlib') == 'local'; enabled and __import__('_distutils_hack').add_shim(); diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__init__.py b/zhdo.space/lib/python3.9/site-packages/flask/__init__.py new file mode 100644 index 0000000..f684f57 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/flask/__init__.py @@ -0,0 +1,45 @@ +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 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.1.2" diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__main__.py b/zhdo.space/lib/python3.9/site-packages/flask/__main__.py new file mode 100644 index 0000000..4e28416 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/flask/__main__.py @@ -0,0 +1,3 @@ +from .cli import main + +main() diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/__init__.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3483c571f3df095e79560cd5d5a93abad497602b GIT binary patch literal 1851 zcmbu9NpE6D5XS)<9tHzuG2ZtTFEF-e5=DxlD3NkY4l|J=)ur{|HSmUh%XIe}FNgUm zIp>t`!!@V*3OS{!02}!lEdTlSzlx^1s(EgyR7m0L@3Sx6Kl7>7KeU*CWpME${+kq% zm-5mo6{I1ZCe9#dAj7<%7J@}sWL{L+AO|_*td~0UWHZW71a#ZV2!zoybkNkHRKK0 zV6G!?!X|SAc?-6fSCO}2o4KiWf?e2UUPIo4J?3@feb{H-Kt6y2=1t^7IAq>JK7u3W zZRBG(X5K+QffMFkl@CtglzC5`1?O*V6N~?AfpBN%rDL6NQxVi*n5f!Few~CDL&6duie* zG_=>!Pb!hI_CpHfevZPvKR~LveJi!FL*EGf{K4&B6hDeyqO}a|%on{VwDN&IUm3ba zxN$sZ)ybOfFlU!1Y4$-F>-MO=+Dq1)Tbz9v?utois?B*R$T89we{#@19(0J|#z0!Z z3+agfuAiZS4C8f zKL}lgWB%;=%I$KCsFYY1uPhus9q=i8+rDYv{?_^y3IShj|jDoGP%>g`kg7xZkNpe8?F^GcG7pNpVF+H_dKP@M*I9oqH9%NB`yk0@& WEe@O9{FKt1R6CFxia~brFaZGO{xm`W literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/app.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/app.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f37fc5eff1feb918fc4a4d7320b9e5778f1f4c68 GIT binary patch literal 63297 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 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/blueprints.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/blueprints.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f9b5311b6bdeea340cbb3b129a17b5af583f8d1 GIT binary patch literal 21716 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 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/cli.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/cli.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d94bf1bcda8f210e250c61f207205c9c05ac5309 GIT binary patch literal 26317 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 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/debughelpers.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/debughelpers.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48c6b3bd9fedb1d389c3128a9121396d8944fd2b GIT binary patch literal 6450 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 Scg0_MefiDc-15og%YOmyDccbM literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/globals.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/globals.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9887c0d7c7c3f79af261d5dbe3151240268fc915 GIT binary patch literal 1833 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 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/scaffold.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/scaffold.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55c4ab694ae85ffb53f815745b66e7dc57f431e6 GIT binary patch literal 24784 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 MEdFKggJS;w06oZ_0RR91 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/signals.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/signals.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d72f037497fcd0d1b06fb96c711c4fdd08bf825e GIT binary patch literal 2370 zcmZuyPj4GV6rcU$wPQPpou+LH9QJ@fmKqzu2??PhL{TrP)F2gx!)Wap$D6Eo-I;My zTNMY=kHGr&O-@KW9Z{F|y*<^pe$?*LC@lV6=8;t!) zi|q$8_6WoLfk`syWsG~vV<12CrvVQ(owSJ5jL#bIo}Dq`6gkjAX=CV&f#sifa=amCH20h>LN&j!!(CTd2q~ zs7$k!vLxTAQCb%|F7i0Z5p8-^Wk&Vm_(^W8N+fBL1<5xDaG1Z5U3X+^d5w_vV@W@%~LDHU2Gb%#JmXoXshh{)sY?w2lqB*bahStx{lK$1a0$B zdC~eQhEuk=jI;YT(3Fw-9!>XYqOw>`l(STqxqJY$DV6Pe(B?blhzDox0KlT3-hhFh zeKOqh&z4WmT`3}^E@CsE%?gb$>?Bq^RHI~WR$-}f4<)V>y`ZBAOiV#R7Ae_BuWLV> z=Qf?HZzw(V3C!Mhqb4YyJ|I8b$H4PF|6f1w|5UuYsozfa5hsK|3Qvb?nh;$@of_IjbDumwM{Y6`a#on{NMv(uERsT6c4 zi4j_jRQghBBgTd1`#Z}mA6?K~kD++e)eYUc;f2wA;Yn~3b-d6+$D!S2m&|7<+*6J4 zDXrx4-cUh*B{;1PEDyDMF;~W(f^2PZuu}=f$Wb$a|zG1E-Jjf zP8Qc$d3W7Y#HM4FttUjhUF8Xp!5d>X-T$h#YR#mE>l-ZlT4@0q?tIj?0mRNrgrKElMW1VmlS9S zpmsso=72raX>RSIhhFM~G}B8?{YUy2;LuA?`4>8qOn+}dP^1&5xpbz`?DFmRzW09b zV-+kc)D3)pzx=!1^J|9jFKSGGRW#m4Q5(!KxWQRucnrU0WbRv@#i-8$ZF?0>+n^oK z(R2lL)vJPbcr~i+&v|p2u7R$5bxqGj^ZO02q3Js41#f{Fg7p^V=U6o#E$uIR%X+jC zo!W1DO+9*AtYFS+$6Pn~!V|_9`O;^$w|3Lu%ly=520tY#k1fweyU9qf^~r<<%|{@EuMU+3pAf1@}Vedp1)!Jk9l zbDZ5aS{J?~x$U%AUVkT0;#LxHA<>%Ojt@hb#QP#n(X8DO`~4_L1?c6H-bvCM$sp!m zLdXUN7X6^#_uJ`1U!_6&K6;wI6bA#L(wW}1UC~LTz*vmK{Pbk&Qzbnf6C9gVZbX5i z-DJ$I zrjY>~=y@wMdNz72>giQL*`Q3wr!u^KU37v$l)B~J+;$SD;$iCcWzrT(C34es--~;q zohtXMp)}3KPO4zUKxpckgxYZR+lwoOSc+cxql9Pii@`hFj-Wn)D?>ST0eu zOw}n=Ez1Mj2N1C5K+^clO?mi*Ay+W??~k|kl6|q&8wByz-9+Bs8t(CAQ}u(km?ooe zcdP#>-Am%vHh;dQ!c_biQ|<>{p|(0C=&doIVcgy9Kguuqyx@PLC#}l~?@gSos4{Ga zIm~7?R@bG@Buvwo(U6{o>TMKt36;=x>6x5)7B_|6t8k0kz-Wa#z^KD5=%6Y|tHXZ~ zSIUjT`@#)eDY}Cwkna0o+zVcH#R**9-9hT^1L~5;xroQa4Q9b`V3?q7S&DPw0K(0DEH#w5OJ)3GUSq z0Crno?ikq04Lfcu2rGenR3JdkgQcC8m0QqcUQPORMc)s++)Ir1cmN9;c?#G)5DW~}g zRyMWStmbRiL)d@X-h(Y`J1N}z@YAbqq4NUbQIf!};F6~i8*69-oKe^g2%Or31yNx} zv#=+hETo!2wprlh8-ONoQ@MtsD2i*SA|T&3zF>$$1=dWtfuUjxt>hC;6Uttr#oA2R z@Zz^Kc>*;npP%v$d95_d!q^BnEU2K`}u z^%EmDUokQZqH?lIR_$2F@Jt6y&X9-M`;}1*eyRo$JDHgw(?N@NWb*UOzKy*y^D+B9 zvNrfIYey1;$N`=o3+*Ht5t4y#KS)Wjse)@+@DbMJ*sm%1GM35;s+__mytvokVt3Hp z6HyyUDJ@5AZ12##L`4_@1rrLu~(rnYh(|bnO$n^F6@p$ znp#h96ngr^IH*&31!Y>|lF$zjUct|a{92W#tvyc;( z^Ipo34HmNwULw4e+!H49#%z$($eJVz3I?t{m9|lWMLstfe9C6EFax?Pabj2+3+5t{ zrWzYwdX_|Hki39(ZOXRGk03xr8}BZN)Oc)+5d3>c2__6)Lb3oBkL+WEOpr#8Dq0jT zYf+rc+$?56NQ-a)?8wP%ZM5$mY^K$WJ;sxv5Kb+(lt>E)y@hjgXVB-!Eb_%DM7m%4 zSS2ZEL6XCHZqvvZLX^KNB-Mo_{RDHq&CAKxF|d!K2w8@fRE;f;W!3;SeDN7_o4rNr zw0sU5$O}|mq{^j=LW#~3z)UJ7|db|X>P0U5U>Wao1? zMJ!~HCQ?!;((29aTVPV(drJG-E_9mm15DgRQFIfSzrAeRY~$-jP1omjJ#VtJUpE?( z=IS&N7$bP))$zllkh(Sp3;pFs<}kqm9YW6^xK>11&i+X5RY$O6HnLK{e`bWzY;)N9 zm41;a9r{ZZ>bTztp)cL7!Y*>@(k9=+F}NOiA<7P8PKu>houtq{zPO}W#ig~+oOKg< zb^O@NFsn!%t!2C+mYKXtdsz8ud6gnzOyJo`$a+^Tg=vc*iI608!c3lDKLTOuJ(FTK zp*h7aKG~_ge~|L7ug%0Dda5(tK*A}Pj%@G zrSJ2dyXpHt)hcz9Sh(UL#Ej62&7uhR!P|yZEBG{LV|EK(4g(p|@dOpTozz}3h&Zhb z4uen|ksIp7@>}mR-l}|7mBJ{}O1uK~lbD{G8cX?^!sASQjbEAv!6u(8+%_^lZ;dh^ zpa!oOywNA~5#HXR%?L-ih1c|y#geh+O9j7^1%E(i;ky?cL@|ozCbPeiH_#85Iz?Ld zKf&dV|AI>mzX{6l@}&gRg^@sgTGq2bE&qkF>E0|SVm zd{R5%ljm@$w`YU+{|ZO)8q}v7zb&)q%!yG(cZ1Vh4FGd5$XbT}855EgtErzrGYCnkaGN((=Oc&Px3Pl3nww H#@c@X^eIUF literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/testing.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/testing.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de3bdeee4533e5a151565432055511440a4a9071 GIT binary patch literal 9210 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 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/typing.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/typing.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7f7d2f8db4c354d88ea4f70af03fbb853d5154f2 GIT binary patch literal 1348 zcmZWp&2HO95ax=c%*dAIA6br^pSo$&)Q3tyataU>wPnXP5;(4{H0WM}m3Ac4UU8Y- zB^>9F_vxu`(TCu*r@lfHAemiJvfz;5aOV5I`QeZtt5z!>9)Caj*xQXf?_V3t9*B9r z;idl}p2s~-ghvUG^OAauQAzltfCj`ez6eKUT6TUQ=0*{Xh=!Hp^*O3r!s=ylnFZKI+yi&*#uCzzVDt^;R*iPvSz^ zaFuF~sX?Pq)}aQ=vpzCdmq&vTtFNQ_w(U!s=xy+DNO)+~^p1^(xC0m69Y;>Rj{U6S zp2Zw;zv*G#Soz&lIkN$$-?R)bqjg)M-`|KI6!8yE{iBU=FAs;MqVi7;Ddt80Hax_> z6ZTQTR)+-EU4@@HIrX+~{b%3s(H6;TZ%+3Qx6@R_eP&{rAT)OXjDynXMkkRZZ3t4e6Lw(_#MO5?HufNUK}3n)5W()fj$G?y41tiCD8RtP!}H{ z8@4zzOdFN;O{PG*nsj5zUMiNR*u90^b?ZEQo#1r2kBNEMyE35jU^niY+}}>F^61cj zVn!-jolN`(6B*=woETa;HOyqXBRSB@_~DM&2=d@%tW6$vvs3_`9}_N(E)**mN2`;X zCx9a-6{=Myk>u0-*m|M}Y!iC(Np}wb-R0k~K z;(CI=Jk_vYmNozX-aeBfXrE^+X}^)`qW$5F%a%@AA7)(<_uA=|Ig`ng*3-6*4g7+V z3pNDZ9tfr{+T-uDmE!AoHj+FO@GJhoJbi>F^2=nwo_;_|?p!1hi9VIS1W|z4CSDJ| c1fgZEZjqEeTdqQu(65sQ*+9?wE9Cy%SJzj0O8@`> literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/views.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/views.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d03b285995a013c3d6e4caa3f5521f332ec5d50f GIT binary patch literal 4982 zcma)ATaVku73T0FX|>w*B}o$}X*zK)Yo&=cy`V@J8zY9}T-szEI8K5pH7G7;wBni~ z<>7EQ+R8zZbz$eBed|+Qz%B|Dekl5X_}ZuZg+8?X&X7yVYo`r?8F6L~&zza_&3Dcy zSXpUXc>b~W`S#}1mi13+EIti1-ayF`RKgN0w)#xi!inv%(|4GKcNgz&-!<=EY>mCX z$1K^{u|(r9?2z@FZ(E`%TDL6GI<)&Ow3b90t+re`boy-cSoyu%Ul!~` ztGoIY=CroHVyL^USPpZgWTO3GGC{McSnTqPd|aW1>9!r76! za3^VodL#o;G}DQWAXhYmjHQ-^Gs$(~X%&RB@Fsx{MnPdb*)-E~3=`fR@{K@iwK1T%QjrZv z?L?(}k$__Qt{O0UM9Py?!&tRRo#txjK(W-`0M=BwYM)_UAs2_l!k>I^5YwJ zE|c-_Wu63Mc}y97p$shf@a#J>j#K^{61(~0*|}OEy0^H9b8G7(5?$XU(erCB8_)XW z+1E?EdqL)tx6iGOr}Vql?Uw338OelC(;To!G;NxYVX6WxdB7)ezOxf-$CVe2R20Yc zW=l9(Dh?OuQBVS8pVZZUKZ2G4hLX@K__^&V-&a@xd7UJy)$Y+L-9=MT*ZnO=E-yl#XKrEb73HkGR*@8_e_9Qh@=VLhdACmz(IgN%m)5nKj5To zrSLL&uHM?0py8!@gAMMDw(WpU)PfaRl!Wwc3KH2*^SBN=5-oTZh&c z%tQ(M;O`$+94Cq8O5RBKq*5Rlm=Ct8=wOllXkEre0!0w&Jcu7&0S{9lv8z`X6ddD2 zP-Crvw&`J7G&^S~5wz5+1-B?*!By`b5wR4Plu8x4U1E_3mU;>+{MQHTqjW6Sck>`w z|0Gq{*AGS_?SZF5x%e7K+v}4lJeT~W_w)5E(()CETn~0+wr)6bo#-L!O{T@keV6jZd0_kFA|D>~)-^?hoo)A&3zN=OkN4+SC0I)Reyq0-ha zGsPC{u5;VE&2HO6L{H(|>U?R>tX)UFHDh;d-^II!Uyu6Uw61k-x-<8VeaODFZ@f0M zFw&^ynrJl_V*^)}-a8Bun=N8feZ1=EFdA(<)yy*h=e zX!$;!7~e12zCTU{4!`fK7ig&I`yvg|qNAZsqUw5u6ULc(hC1d}E!B)zn#O6E>?@j; zA(zm|Xa&~F3vPooSc|n;yIH=q&}y-R&Z6brC)D>Kt-g<{==lB(5MF7gqCGE7I!lAC z%O*<>;=+9o!KrZI;o^kv2MMAHh#M})63F_(-A>cETJ}Y-A>|h3R?yBPW2els#Gm>u z&C;cc=xw1g`@V|46_kwVq|IFZjB|SVNqefa-qL-`NT99a8R*pa zgoUNsTgJb@t7ozu0%?>)8X$EtT#}l&DN(LfH1df62N~(&)JW@zUoO_|evEy4&o zNLLFlpCEPWHq{yyWiVWLlv-p36Qv55nuT*+P9Lyh$uAEo&|@HA9RE{%n$pHl3kS|_ zu?9+qt)gzTlMR<0JU#aa`K@2+GKnZ;%+BlSPzCch@teA?&-3aD;oy?KcHstx>e+HU}2MU)UgeDk>AN!bTY(JQK&^yqCD!9_0lV_Efbxl#c{DWHUwzHv0Ur$D z-oc=PEkrb~a|k-yWdcM|jxGu#gcV#31_RuAAYECL_4uR7_r)})n0MiWchAk2c`O^I zYZB%)H=|=i6n?5(0>F}iQFL`|U#G27^J%T(8Z!H@)y;p% ze^iICa)R2RwadR;`=1xHxsl|=@=iA2kNLgqNDdb>nnFDX^gNW*60WFRM#+ASN?S8a zvt9e1b02@T96C3hnIo*+Qm<04VApNDK?a%Ae3WJH{K66rN&LzFGjgRbn0D`ZAQlh| zqNPnSl-O^paNoIf;Y~$Txx7ca-H0#*Uu!HC3fO#a_-0HR-d!Q*SmGQ%bSyH_)-JDA< zV&Hc)CoKR6`h=n$B-Tr?uq1l?i_*|jx~nSE3g(N`Z3Ogkee|7)U&Rvs*f>BcA+>sq tIw}4XF20n8B#h$6*-*4L%b0(j?kgsmwd@Y)tmD|M@gLV)y>{}s{{oHQSsMTV literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/wrappers.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/flask/__pycache__/wrappers.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0bcc40aaba87d0cd61de8194a19dfa72306d18fe GIT binary patch literal 5076 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 iM>eN+NNk@q@8tpN=j5CTg_EY= (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 :meth:`test_client` method creates an instance of this test + #: client class. Defaults to :class:`~flask.testing.FlaskClient`. + #: + #: .. versionadded:: 0.7 + test_client_class: t.Optional[t.Type["FlaskClient"]] = None + + #: The :class:`~click.testing.CliRunner` subclass, by default + #: :class:`~flask.testing.FlaskCliRunner` that is used by + #: :meth:`test_cli_runner`. Its ``__init__`` method should take a + #: Flask app object as the first argument. + #: + #: .. versionadded:: 1.0 + test_cli_runner_class: t.Optional[t.Type["FlaskCliRunner"]] = None + + #: the session interface to use. By default an instance of + #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here. + #: + #: .. versionadded:: 0.8 + session_interface: SessionInterface = SecureCookieSessionInterface() + + def __init__( + self, + import_name: str, + static_url_path: t.Optional[str] = None, + static_folder: t.Optional[t.Union[str, os.PathLike]] = "static", + static_host: t.Optional[str] = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: t.Optional[str] = "templates", + instance_path: t.Optional[str] = None, + instance_relative_config: bool = False, + root_path: t.Optional[str] = None, + ): + super().__init__( + import_name=import_name, + static_folder=static_folder, + static_url_path=static_url_path, + template_folder=template_folder, + root_path=root_path, + ) + + if instance_path is None: + instance_path = self.auto_find_instance_path() + elif not os.path.isabs(instance_path): + raise ValueError( + "If an instance path is provided it must be absolute." + " A relative path was given instead." + ) + + #: Holds the path to the instance folder. + #: + #: .. versionadded:: 0.8 + self.instance_path = instance_path + + #: The configuration dictionary as :class:`Config`. This behaves + #: exactly like a regular dictionary but supports additional methods + #: to load a config from files. + self.config = self.make_config(instance_relative_config) + + #: 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[BeforeFirstRequestCallable] = [] + + #: A list of functions that are called when the application context + #: is destroyed. Since the application context is also torn down + #: if the request ends this is the place to store code that disconnects + #: from databases. + #: + #: .. versionadded:: 0.9 + self.teardown_appcontext_funcs: t.List[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. + """ + names: t.Iterable[t.Optional[str]] = (None,) + + # A template may be rendered outside a request context. + if request: + names = chain(names, reversed(request.blueprints)) + + # The values passed to render_template take precedence. Keep a + # copy to re-apply after all context functions. + orig_ctx = context.copy() + + for name in names: + if name in self.template_context_processors: + for func in self.template_context_processors[name]: + context.update(func()) + + context.update(orig_ctx) + + def make_shell_context(self) -> dict: + """Returns the shell context for an interactive shell for this + application. This runs all the registered shell context + processors. + + .. versionadded:: 0.11 + """ + rv = {"app": self, "g": g} + for processor in self.shell_context_processors: + rv.update(processor()) + return rv + + #: 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: BeforeFirstRequestCallable + ) -> BeforeFirstRequestCallable: + """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)) + names = (*request.blueprints, None) + + for c in (code, None) if code is not None else (None,): + for name in names: + handler_map = self.error_handler_spec[name][c] + + if not handler_map: + continue + + for cls in exc_class.__mro__: + handler = handler_map.get(cls) + + if handler is not None: + return handler + return None + + def handle_http_exception( + self, e: HTTPException + ) -> t.Union[HTTPException, ResponseReturnValue]: + """Handles an HTTP exception. By default this will invoke the + registered error handlers and fall back to returning the + exception as response. + + .. versionchanged:: 1.0.3 + ``RoutingException``, used internally for actions such as + slash redirects during routing, is not passed to error + handlers. + + .. versionchanged:: 1.0 + Exceptions are looked up by code *and* by MRO, so + ``HTTPException`` subclasses can be handled with a catch-all + handler for the base ``HTTPException``. + + .. versionadded:: 0.3 + """ + # Proxy exceptions don't have error codes. We want to always return + # those unchanged as errors + if e.code is None: + return e + + # RoutingExceptions are used internally to trigger routing + # actions, such as slash redirects raising RequestRedirect. They + # are not raised or handled in user code. + if isinstance(e, RoutingException): + return e + + handler = self._find_error_handler(e) + if handler is None: + return e + return self.ensure_sync(handler)(e) + + def trap_http_exception(self, e: Exception) -> bool: + """Checks if an HTTP exception should be trapped or not. By default + this will return ``False`` for all exceptions except for a bad request + key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``. It + also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``. + + This is called for all HTTP exceptions raised by a view function. + If it returns ``True`` for any exception the error handler for this + exception is not called and it shows up as regular exception in the + traceback. This is helpful for debugging implicitly raised HTTP + exceptions. + + .. versionchanged:: 1.0 + Bad request errors are not trapped by default in debug mode. + + .. versionadded:: 0.8 + """ + if self.config["TRAP_HTTP_EXCEPTIONS"]: + return True + + trap_bad_request = self.config["TRAP_BAD_REQUEST_ERRORS"] + + # if unset, trap key errors in debug mode + if ( + trap_bad_request is None + and self.debug + and isinstance(e, BadRequestKeyError) + ): + return True + + if trap_bad_request: + return isinstance(e, BadRequest) + + return False + + def handle_user_exception( + self, e: Exception + ) -> t.Union[HTTPException, 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": + """Intercept routing exceptions and possibly do something else. + + In debug mode, intercept a routing redirect and replace it with + an error if the body will be discarded. + + With modern Werkzeug this shouldn't occur, since it now uses a + 308 status which tells the browser to resend the method and + body. + + .. versionchanged:: 2.1 + Don't intercept 307 and 308 redirects. + + :meta private: + :internal: + """ + if ( + not self.debug + or not isinstance(request.routing_exception, RequestRedirect) + or request.routing_exception.code in {307, 308} + or request.method in {"GET", "HEAD", "OPTIONS"} + ): + raise request.routing_exception # type: ignore + + from .debughelpers import FormDataRoutingRedirect + + raise FormDataRoutingRedirect(request) + + def dispatch_request(self) -> 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." + ) from None + + 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 # type: ignore[misc] + # decide if a 2-tuple has status or headers + elif len_rv == 2: + if isinstance(rv[1], (Headers, dict, tuple, list)): + rv, headers = rv + else: + rv, status = rv # type: ignore[misc] + # other sized tuples are not allowed + else: + raise TypeError( + "The view function did not return a valid response tuple." + " The tuple must have the form (body, status, headers)," + " (body, status), or (body, headers)." + ) + + # the body must not be None + if rv is None: + raise TypeError( + f"The view function for {request.endpoint!r} did not" + " return a valid response. The function either returned" + " None or ended without a return statement." + ) + + # make sure the body is an instance of the response class + if not isinstance(rv, self.response_class): + if isinstance(rv, (str, bytes, bytearray)): + # let the response class set the status and headers instead of + # waiting to do it manually, so that the class can handle any + # special logic + rv = self.response_class( + rv, + status=status, + headers=headers, # type: ignore[arg-type] + ) + status = headers = None + elif isinstance(rv, dict): + 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]) from None + 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 + else: + rv.status_code = status + + # extend existing headers with provided headers + if headers: + rv.headers.update(headers) # type: ignore[arg-type] + + return rv + + def create_url_adapter( + self, request: t.Optional[Request] + ) -> t.Optional[MapAdapter]: + """Creates a URL adapter for the given request. The URL adapter + is created at a point where the request context is not yet set + up so the request is passed explicitly. + + .. versionadded:: 0.6 + + .. versionchanged:: 0.9 + This can now also be called without a request object when the + URL adapter is created for the application context. + + .. versionchanged:: 1.0 + :data:`SERVER_NAME` no longer implicitly enables subdomain + matching. Use :attr:`subdomain_matching` instead. + """ + if request is not None: + # If subdomain matching is disabled (the default), use the + # default subdomain in all cases. This should be the default + # in Werkzeug but it currently does not have that feature. + if not self.subdomain_matching: + subdomain = self.url_map.default_subdomain or None + else: + subdomain = None + + return self.url_map.bind_to_environ( + request.environ, + server_name=self.config["SERVER_NAME"], + subdomain=subdomain, + ) + # We need at the very least the server name to be set for this + # to work. + if self.config["SERVER_NAME"] is not None: + return self.url_map.bind( + self.config["SERVER_NAME"], + script_name=self.config["APPLICATION_ROOT"], + url_scheme=self.config["PREFERRED_URL_SCHEME"], + ) + + return None + + def inject_url_defaults(self, endpoint: str, values: dict) -> None: + """Injects the URL defaults for the given endpoint directly into + the values dictionary passed. This is used internally and + automatically called on URL building. + + .. versionadded:: 0.7 + """ + names: t.Iterable[t.Optional[str]] = (None,) + + # url_for may be called outside a request context, parse the + # passed endpoint instead of using request.blueprints. + if "." in endpoint: + names = chain( + names, reversed(_split_blueprint_path(endpoint.rpartition(".")[0])) + ) + + for name in names: + if name in self.url_default_functions: + for func in self.url_default_functions[name]: + func(endpoint, values) + + def handle_url_build_error( + self, error: 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. + """ + names = (None, *reversed(request.blueprints)) + + for name in names: + if name in self.url_value_preprocessors: + for url_func in self.url_value_preprocessors[name]: + url_func(request.endpoint, request.view_args) + + for name in names: + if name in self.before_request_funcs: + for before_func in self.before_request_funcs[name]: + rv = self.ensure_sync(before_func)() + + if rv is not None: + return rv + + return None + + def process_response(self, response: Response) -> Response: + """Can be overridden in order to modify the response object + before it's sent to the WSGI server. By default this will + call all the :meth:`after_request` decorated functions. + + .. versionchanged:: 0.5 + As of Flask 0.5 the functions registered for after request + execution are called in reverse order of registration. + + :param response: a :attr:`response_class` object. + :return: a new response object or the same, has to be an + instance of :attr:`response_class`. + """ + ctx = _request_ctx_stack.top + + for func in ctx._after_request_functions: + response = self.ensure_sync(func)(response) + + for name in chain(request.blueprints, (None,)): + if name in self.after_request_funcs: + for func in reversed(self.after_request_funcs[name]): + response = self.ensure_sync(func)(response) + + if not self.session_interface.is_null_session(ctx.session): + self.session_interface.save_session(self, ctx.session, response) + + return response + + def do_teardown_request( + self, exc: t.Optional[BaseException] = _sentinel # type: ignore + ) -> None: + """Called after the request is dispatched and the response is + returned, right before the request context is popped. + + This calls all functions decorated with + :meth:`teardown_request`, and :meth:`Blueprint.teardown_request` + if a blueprint handled the request. Finally, the + :data:`request_tearing_down` signal is sent. + + This is called by + :meth:`RequestContext.pop() `, + which may be delayed during testing to maintain access to + resources. + + :param exc: An unhandled exception raised while dispatching the + request. Detected from the current exception information if + not passed. Passed to each teardown function. + + .. versionchanged:: 0.9 + Added the ``exc`` argument. + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + + for name in chain(request.blueprints, (None,)): + if name in self.teardown_request_funcs: + for func in reversed(self.teardown_request_funcs[name]): + self.ensure_sync(func)(exc) + + request_tearing_down.send(self, exc=exc) + + def do_teardown_appcontext( + self, exc: t.Optional[BaseException] = _sentinel # type: ignore + ) -> None: + """Called right before the application context is popped. + + When handling a request, the application context is popped + after the request context. See :meth:`do_teardown_request`. + + This calls all functions decorated with + :meth:`teardown_appcontext`. Then the + :data:`appcontext_tearing_down` signal is sent. + + This is called by + :meth:`AppContext.pop() `. + + .. versionadded:: 0.9 + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + + for func in reversed(self.teardown_appcontext_funcs): + self.ensure_sync(func)(exc) + + appcontext_tearing_down.send(self, exc=exc) + + def app_context(self) -> AppContext: + """Create an :class:`~flask.ctx.AppContext`. Use as a ``with`` + block to push the context, which will make :data:`current_app` + point at this application. + + An application context is automatically pushed by + :meth:`RequestContext.push() ` + when handling a request, and when running a CLI command. Use + this to manually create a context outside of these situations. + + :: + + with app.app_context(): + init_db() + + See :doc:`/appcontext`. + + .. versionadded:: 0.9 + """ + return AppContext(self) + + def request_context(self, environ: dict) -> RequestContext: + """Create a :class:`~flask.ctx.RequestContext` representing a + WSGI environment. Use a ``with`` block to push the context, + which will make :data:`request` point at this request. + + See :doc:`/reqcontext`. + + Typically you should not call this from your own code. A request + context is automatically pushed by the :meth:`wsgi_app` when + handling a request. Use :meth:`test_request_context` to create + an environment and context instead of this method. + + :param environ: a WSGI environment + """ + return RequestContext(self, environ) + + def test_request_context(self, *args: t.Any, **kwargs: t.Any) -> RequestContext: + """Create a :class:`~flask.ctx.RequestContext` for a WSGI + environment created from the given values. This is mostly useful + during testing, where you may want to run a function that uses + request data without dispatching a full request. + + See :doc:`/reqcontext`. + + Use a ``with`` block to push the context, which will make + :data:`request` point at the request for the created + environment. :: + + with test_request_context(...): + generate_report() + + When using the shell, it may be easier to push and pop the + context manually to avoid indentation. :: + + ctx = app.test_request_context(...) + ctx.push() + ... + ctx.pop() + + Takes the same arguments as Werkzeug's + :class:`~werkzeug.test.EnvironBuilder`, with some defaults from + the application. See the linked Werkzeug docs for most of the + available arguments. Flask-specific behavior is listed here. + + :param path: URL path being requested. + :param base_url: Base URL where the app is being served, which + ``path`` is relative to. If not given, built from + :data:`PREFERRED_URL_SCHEME`, ``subdomain``, + :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. + :param subdomain: Subdomain name to append to + :data:`SERVER_NAME`. + :param url_scheme: Scheme to use instead of + :data:`PREFERRED_URL_SCHEME`. + :param data: The request body, either as a string or a dict of + form keys and values. + :param json: If given, this is serialized as JSON and passed as + ``data``. Also defaults ``content_type`` to + ``application/json``. + :param args: other positional arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + :param kwargs: other keyword arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + """ + from .testing import EnvironBuilder + + builder = EnvironBuilder(self, *args, **kwargs) + + try: + return self.request_context(builder.get_environ()) + finally: + builder.close() + + def wsgi_app(self, environ: dict, start_response: t.Callable) -> t.Any: + """The actual WSGI application. This is not implemented in + :meth:`__call__` so that middlewares can be applied without + losing a reference to the app object. Instead of doing this:: + + app = MyMiddleware(app) + + It's a better idea to do this instead:: + + app.wsgi_app = MyMiddleware(app.wsgi_app) + + Then you still have the original application object around and + can continue to call methods on it. + + .. versionchanged:: 0.7 + Teardown events for the request and app contexts are called + even if an unhandled error occurs. Other events may not be + called depending on when an error occurs during dispatch. + See :ref:`callbacks-and-errors`. + + :param environ: A WSGI environment. + :param start_response: A callable accepting a status code, + a list of headers, and an optional exception context to + start the response. + """ + ctx = self.request_context(environ) + error: t.Optional[BaseException] = None + try: + try: + ctx.push() + response = self.full_dispatch_request() + except Exception as e: + error = e + response = self.handle_exception(e) + except: # noqa: B001 + error = sys.exc_info()[1] + raise + return response(environ, start_response) + finally: + if 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/zhdo.space/lib/python3.9/site-packages/flask/blueprints.py b/zhdo.space/lib/python3.9/site-packages/flask/blueprints.py new file mode 100644 index 0000000..5d3b4e2 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/flask/blueprints.py @@ -0,0 +1,597 @@ +import os +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 BeforeFirstRequestCallable +from .typing import BeforeRequestCallable +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 + from .typing import ErrorHandlerCallable + +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[t.Union[str, os.PathLike]] = None, + static_url_path: t.Optional[str] = None, + template_folder: t.Optional[str] = None, + url_prefix: t.Optional[str] = None, + subdomain: t.Optional[str] = None, + url_defaults: t.Optional[dict] = None, + root_path: t.Optional[str] = None, + cli_group: t.Optional[str] = _sentinel, # type: ignore + ): + super().__init__( + import_name=import_name, + static_folder=static_folder, + static_url_path=static_url_path, + template_folder=template_folder, + root_path=root_path, + ) + + if "." in name: + raise ValueError("'name' may not contain a dot '.' character.") + + self.name = name + self.url_prefix = url_prefix + self.subdomain = subdomain + self.deferred_functions: t.List[DeferredSetupFunction] = [] + + if url_defaults is None: + url_defaults = {} + + self.url_values_defaults = url_defaults + self.cli_group = cli_group + self._blueprints: t.List[t.Tuple["Blueprint", dict]] = [] + + def _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. + """ + name_prefix = options.get("name_prefix", "") + self_name = options.get("name", self.name) + name = f"{name_prefix}.{self_name}".lstrip(".") + + if name in app.blueprints: + bp_desc = "this" if app.blueprints[name] is self else "a different" + existing_at = f" '{name}'" if self_name != name else "" + + raise ValueError( + f"The name '{self_name}' is already registered for" + f" {bp_desc} blueprint{existing_at}. Use 'name=' to" + f" provide a unique name." + ) + + first_bp_registration = not any(bp is self for bp in app.blueprints.values()) + first_name_registration = name not in app.blueprints + + app.blueprints[name] = self + self._got_registered_once = True + state = self.make_setup_state(app, options, first_bp_registration) + + if self.has_static_folder: + state.add_url_rule( + f"{self.static_url_path}/", + view_func=self.send_static_file, + endpoint="static", + ) + + # Merge blueprint data into parent. + if first_bp_registration or first_name_registration: + + def extend(bp_dict, parent_dict): + for key, values in bp_dict.items(): + key = name if key is None else f"{name}.{key}" + parent_dict[key].extend(values) + + for key, value in self.error_handler_spec.items(): + key = name if key is None else f"{name}.{key}" + value = defaultdict( + dict, + { + code: { + exc_class: func for exc_class, func in code_values.items() + } + for code, code_values in value.items() + }, + ) + app.error_handler_spec[key] = value + + for endpoint, func in self.view_functions.items(): + app.view_functions[endpoint] = func + + extend(self.before_request_funcs, app.before_request_funcs) + extend(self.after_request_funcs, app.after_request_funcs) + extend( + self.teardown_request_funcs, + app.teardown_request_funcs, + ) + extend(self.url_default_functions, app.url_default_functions) + extend(self.url_value_preprocessors, app.url_value_preprocessors) + extend(self.template_context_processors, app.template_context_processors) + + for deferred in self.deferred_functions: + deferred(state) + + cli_resolved_group = options.get("cli_group", self.cli_group) + + if self.cli.commands: + if cli_resolved_group is None: + app.cli.commands.update(self.cli.commands) + elif cli_resolved_group is _sentinel: + self.cli.name = name + app.cli.add_command(self.cli) + else: + self.cli.name = cli_resolved_group + app.cli.add_command(self.cli) + + for blueprint, bp_options in self._blueprints: + bp_options = bp_options.copy() + bp_url_prefix = bp_options.get("url_prefix") + + if bp_url_prefix is None: + bp_url_prefix = blueprint.url_prefix + + if state.url_prefix is not None and bp_url_prefix is not None: + bp_options["url_prefix"] = ( + state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/") + ) + elif bp_url_prefix is not None: + bp_options["url_prefix"] = bp_url_prefix + elif state.url_prefix is not None: + bp_options["url_prefix"] = state.url_prefix + + bp_options["name_prefix"] = name + blueprint.register(app, bp_options) + + 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: BeforeFirstRequestCallable + ) -> BeforeFirstRequestCallable: + """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/zhdo.space/lib/python3.9/site-packages/flask/cli.py b/zhdo.space/lib/python3.9/site-packages/flask/cli.py new file mode 100644 index 0000000..36c4f1b --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/flask/cli.py @@ -0,0 +1,992 @@ +import ast +import inspect +import os +import platform +import re +import sys +import traceback +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 + +if sys.version_info >= (3, 10): + from importlib import metadata +else: + # Use a backport on Python < 3.10. + # + # We technically have importlib.metadata on 3.8+, + # but the API changed in 3.10, so use the backport + # for consistency. + import importlib_metadata as metadata # type: ignore + + +class NoAppException(click.UsageError): + """Raised if an application cannot be found or loaded.""" + + +def find_best_app(module): + """Given a module instance this tries to find the best possible + application in the module or raises an exception. + """ + from . import Flask + + # Search for the most common names first. + for attr_name in ("app", "application"): + app = getattr(module, attr_name, None) + + if isinstance(app, Flask): + return app + + # Otherwise find the only object that is a Flask instance. + matches = [v for v in module.__dict__.values() if isinstance(v, Flask)] + + if len(matches) == 1: + return matches[0] + elif len(matches) > 1: + raise NoAppException( + "Detected multiple Flask applications in module" + f" {module.__name__!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 = app_factory() + + if isinstance(app, Flask): + return app + except TypeError as e: + if not _called_with_wrong_args(app_factory): + raise + + raise NoAppException( + f"Detected factory {attr_name!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." + ) from e + + 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 _called_with_wrong_args(f): + """Check whether calling a function raised a ``TypeError`` because + the call failed or because something in the factory raised the + error. + + :param f: The function that was called. + :return: ``True`` if the call failed. + """ + tb = sys.exc_info()[2] + + try: + while tb is not None: + if tb.tb_frame.f_code is f.__code__: + # In the function, it was called successfully. + return False + + tb = tb.tb_next + + # Didn't reach the function. + return True + finally: + # Delete tb to break a circular reference. + # https://docs.python.org/2/library/sys.html#sys.exc_info + del tb + + +def find_app_by_string(module, app_name): + """Check if the given string is a variable name or a function. Call + a function to get the app instance, or return the variable directly. + """ + from . import Flask + + # Parse app_name as a single expression to determine if it's a valid + # attribute name or function call. + try: + expr = ast.parse(app_name.strip(), mode="eval").body + except SyntaxError: + raise NoAppException( + f"Failed to parse {app_name!r} as an attribute name or function call." + ) from None + + if isinstance(expr, ast.Name): + name = expr.id + args = [] + kwargs = {} + elif isinstance(expr, ast.Call): + # Ensure the function name is an attribute name only. + if not isinstance(expr.func, ast.Name): + raise NoAppException( + f"Function reference must be a simple name: {app_name!r}." + ) + + name = expr.func.id + + # Parse the positional and keyword arguments as literals. + try: + args = [ast.literal_eval(arg) for arg in expr.args] + kwargs = {kw.arg: ast.literal_eval(kw.value) for kw in expr.keywords} + except ValueError: + # literal_eval gives cryptic error messages, show a generic + # message with the full expression instead. + raise NoAppException( + f"Failed to parse arguments as literal values: {app_name!r}." + ) from None + else: + raise NoAppException( + f"Failed to parse {app_name!r} as an attribute name or function call." + ) + + try: + attr = getattr(module, name) + except AttributeError as e: + raise NoAppException( + f"Failed to find attribute {name!r} in {module.__name__!r}." + ) from e + + # If the attribute is a function, call it with any args and kwargs + # to get the real application. + if inspect.isfunction(attr): + try: + app = attr(*args, **kwargs) + except TypeError as e: + if not _called_with_wrong_args(attr): + raise + + raise NoAppException( + f"The factory {app_name!r} in module" + f" {module.__name__!r} could not be called with the" + " specified arguments." + ) from e + else: + app = attr + + if isinstance(app, Flask): + return app + + raise NoAppException( + "A valid Flask application was not obtained from" + f" '{module.__name__}:{app_name}'." + ) + + +def prepare_import(path): + """Given a filename this will try to calculate the python path, add it + to the search path and return the actual module name that is expected. + """ + path = os.path.realpath(path) + + fname, ext = os.path.splitext(path) + if ext == ".py": + path = fname + + if os.path.basename(path) == "__init__": + path = os.path.dirname(path) + + module_name = [] + + # move up until outside package structure (no __init__.py) + while True: + path, name = os.path.split(path) + module_name.append(name) + + if not os.path.exists(os.path.join(path, "__init__.py")): + break + + if sys.path[0] != path: + sys.path.insert(0, path) + + return ".".join(module_name[::-1]) + + +def locate_app(module_name, app_name, raise_if_not_found=True): + __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()}" + ) from None + elif raise_if_not_found: + raise NoAppException(f"Could not import {module_name!r}.") from None + else: + return + + module = sys.modules[module_name] + + if app_name is None: + return find_best_app(module) + else: + return find_app_by_string(module, app_name) + + +def get_version(ctx, param, value): + if not value or ctx.resilient_parsing: + return + + import werkzeug + from . import __version__ + + click.echo( + f"Python {platform.python_version()}\n" + f"Flask {__version__}\n" + f"Werkzeug {werkzeug.__version__}", + color=ctx.color, + ) + ctx.exit() + + +version_option = click.Option( + ["--version"], + help="Show the flask version", + expose_value=False, + callback=get_version, + is_flag=True, + is_eager=True, +) + + +class 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 = 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): + # Store the Click context and push it in the loader thread so + # script_info is still available. + ctx = click.get_current_context(silent=True) + + def _load_app(): + __traceback_hide__ = True # noqa: F841 + + with self._lock: + if ctx is not None: + click.globals.push_context(ctx) + + try: + self._load_unlocked() + except Exception as e: + self._bg_loading_exc = e + + t = Thread(target=_load_app, args=()) + t.start() + + def _flush_bg_loading_exception(self): + __traceback_hide__ = True # noqa: F841 + exc = self._bg_loading_exc + + if exc is not None: + self._bg_loading_exc = None + raise exc + + def _load_unlocked(self): + __traceback_hide__ = True # noqa: F841 + self._app = rv = self.loader() + self._bg_loading_exc = 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 = self.create_app() + else: + if self.app_import_path: + path, name = ( + re.split(r":(?![\\/])", self.app_import_path, 1) + [None] + )[:2] + import_name = prepare_import(path) + app = locate_app(import_name, name) + else: + for path in ("wsgi.py", "app.py"): + import_name = prepare_import(path) + app = locate_app(import_name, None, raise_if_not_found=False) + + if app: + break + + if not app: + raise NoAppException( + "Could not locate a Flask application. 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 + + for ep in metadata.entry_points(group="flask.commands"): + self.add_command(ep.load(), ep.name) + + self._loaded_plugin_commands = True + + def get_command(self, ctx, name): + self._load_plugin_commands() + # Look up built-in and plugin commands, which should be + # available even if the app fails to load. + rv = super().get_command(ctx, name) + + if rv is not None: + return rv + + info = ctx.ensure_object(ScriptInfo) + + # Look up commands provided by the app, showing an error and + # continuing if the app couldn't be loaded. + try: + 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, + ) from None + + return value + + obj = import_string(value, silent=True) + + if isinstance(obj, ssl.SSLContext): + return obj + + raise + + +def _validate_key(ctx, param, value): + """The ``--key`` option must be specified when ``--cert`` is a file. + Modifies the ``cert`` param to be a ``(cert, key)`` pair if needed. + """ + cert = ctx.params.get("cert") + is_adhoc = cert == "adhoc" + 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.", + is_eager=True, +) +@click.option( + "--key", + type=click.Path(exists=True, dir_okay=False, resolve_path=True), + callback=_validate_key, + expose_value=False, + help="The key file to use when specifying a certificate.", +) +@click.option( + "--reload/--no-reload", + default=None, + help="Enable or disable the reloader. By default the reloader " + "is active if debug is enabled.", +) +@click.option( + "--debugger/--no-debugger", + default=None, + help="Enable or disable the debugger. By default the debugger " + "is active if debug is enabled.", +) +@click.option( + "--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}." + ), +) +@click.option( + "--exclude-patterns", + default=None, + type=SeparatedPathType(), + help=( + "Files matching these fnmatch patterns will not trigger a reload" + " on change. Multiple patterns are separated by" + f" {os.path.pathsep!r}." + ), +) +@pass_script_info +def run_command( + info, + host, + port, + reload, + debugger, + eager_loading, + with_threads, + cert, + extra_files, + exclude_patterns, +): + """Run a local development server. + + This server is for development purposes only. It does not provide + the stability, security, or performance of production WSGI servers. + + The reloader and debugger are enabled by default 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, + exclude_patterns=exclude_patterns, + ) + + +@click.command("shell", short_help="Run a shell in the app context.") +@with_appcontext +def shell_command() -> None: + """Run an interactive Python shell in the context of a given + Flask application. The application will populate the default + namespace of this shell according to its configuration. + + This is useful for executing small snippets of management code + without having to manually configure the application. + """ + import code + 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: + cli.main() + + +if __name__ == "__main__": + main() diff --git a/zhdo.space/lib/python3.9/site-packages/flask/config.py b/zhdo.space/lib/python3.9/site-packages/flask/config.py new file mode 100644 index 0000000..7b6a137 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/flask/config.py @@ -0,0 +1,337 @@ +import errno +import json +import os +import types +import typing as t + +from werkzeug.utils import import_string + + +class ConfigAttribute: + """Makes an attribute forward to the config""" + + def __init__(self, name: str, get_converter: t.Optional[t.Callable] = None) -> None: + self.__name__ = name + self.get_converter = get_converter + + def __get__(self, obj: t.Any, owner: t.Any = None) -> t.Any: + if obj is None: + return self + rv = obj.config[self.__name__] + if self.get_converter is not None: + rv = self.get_converter(rv) + return rv + + def __set__(self, obj: t.Any, value: t.Any) -> None: + obj.config[self.__name__] = value + + +class Config(dict): + """Works exactly like a dict but provides ways to fill it from files + or special dictionaries. There are two common patterns to populate the + config. + + Either you can fill the config from a config file:: + + app.config.from_pyfile('yourconfig.cfg') + + Or alternatively you can define the configuration options in the + module that calls :meth:`from_object` or provide an import path to + a module that should be loaded. It is also possible to tell it to + use the same module and with that provide the configuration values + just before the call:: + + DEBUG = True + SECRET_KEY = 'development key' + app.config.from_object(__name__) + + In both cases (loading from any Python file or loading from modules), + only uppercase keys are added to the config. This makes it possible to use + lowercase values in the config file for temporary values that are not added + to the config or to define the config keys in the same file that implements + the application. + + Probably the most interesting way to load configurations is from an + environment variable pointing to a file:: + + app.config.from_envvar('YOURAPPLICATION_SETTINGS') + + In this case before launching the application you have to set this + environment variable to the file you want to use. On Linux and OS X + use the export statement:: + + export YOURAPPLICATION_SETTINGS='/path/to/config/file' + + On windows use `set` instead. + + :param root_path: path to which files are read relative from. When the + config object is created by the application, this is + the application's :attr:`~flask.Flask.root_path`. + :param defaults: an optional dictionary of default values + """ + + def __init__(self, root_path: str, defaults: t.Optional[dict] = None) -> None: + super().__init__(defaults or {}) + self.root_path = root_path + + def from_envvar(self, variable_name: str, silent: bool = False) -> bool: + """Loads a configuration from an environment variable pointing to + a configuration file. This is basically just a shortcut with nicer + error messages for this line of code:: + + app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS']) + + :param variable_name: name of the environment variable + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: ``True`` if the file was loaded successfully. + """ + rv = os.environ.get(variable_name) + if not rv: + if silent: + return False + raise RuntimeError( + f"The environment variable {variable_name!r} is not set" + " and as such configuration could not be loaded. Set" + " this variable and make it point to a configuration" + " file" + ) + return self.from_pyfile(rv, silent=silent) + + def from_prefixed_env( + self, prefix: str = "FLASK", *, loads: t.Callable[[str], t.Any] = json.loads + ) -> bool: + """Load any environment variables that start with ``FLASK_``, + dropping the prefix from the env key for the config key. Values + are passed through a loading function to attempt to convert them + to more specific types than strings. + + Keys are loaded in :func:`sorted` order. + + The default loading function attempts to parse values as any + valid JSON type, including dicts and lists. + + Specific items in nested dicts can be set by separating the + keys with double underscores (``__``). If an intermediate key + doesn't exist, it will be initialized to an empty dict. + + :param prefix: Load env vars that start with this prefix, + separated with an underscore (``_``). + :param loads: Pass each string value to this function and use + the returned value as the config value. If any error is + raised it is ignored and the value remains a string. The + default is :func:`json.loads`. + + .. versionadded:: 2.1 + """ + prefix = f"{prefix}_" + len_prefix = len(prefix) + + for key in sorted(os.environ): + if not key.startswith(prefix): + continue + + value = os.environ[key] + + try: + value = loads(value) + except Exception: + # Keep the value as a string if loading failed. + pass + + # Change to key.removeprefix(prefix) on Python >= 3.9. + key = key[len_prefix:] + + if "__" not in key: + # A non-nested key, set directly. + self[key] = value + continue + + # Traverse nested dictionaries with keys separated by "__". + current = self + *parts, tail = key.split("__") + + for part in parts: + # If an intermediate dict does not exist, create it. + if part not in current: + current[part] = {} + + current = current[part] + + current[tail] = value + + return True + + def from_pyfile(self, filename: str, silent: bool = False) -> bool: + """Updates the values in the config from a Python file. This function + behaves as if the file was imported as module with the + :meth:`from_object` function. + + :param filename: the filename of the config. This can either be an + absolute filename or a filename relative to the + root path. + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: ``True`` if the file was loaded successfully. + + .. versionadded:: 0.7 + `silent` parameter. + """ + filename = os.path.join(self.root_path, filename) + d = types.ModuleType("config") + d.__file__ = filename + try: + with open(filename, mode="rb") as config_file: + exec(compile(config_file.read(), filename, "exec"), d.__dict__) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR, errno.ENOTDIR): + return False + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + self.from_object(d) + return True + + def from_object(self, obj: t.Union[object, str]) -> None: + """Updates the values from the given object. An object can be of one + of the following two types: + + - a string: in this case the object with that name will be imported + - an actual object reference: that object is used directly + + Objects are usually either modules or classes. :meth:`from_object` + loads only the uppercase attributes of the module/class. A ``dict`` + object will not work with :meth:`from_object` because the keys of a + ``dict`` are not attributes of the ``dict`` class. + + Example of module-based configuration:: + + app.config.from_object('yourapplication.default_config') + from yourapplication import default_config + app.config.from_object(default_config) + + Nothing is done to the object before loading. If the object is a + class and has ``@property`` attributes, it needs to be + instantiated before being passed to this method. + + You should not use this function to load the actual configuration but + rather configuration defaults. The actual config should be loaded + with :meth:`from_pyfile` and ideally from a location not within the + package because the package might be installed system wide. + + See :ref:`config-dev-prod` for an example of class-based configuration + using :meth:`from_object`. + + :param obj: an import name or object + """ + if isinstance(obj, str): + obj = import_string(obj) + for key in dir(obj): + if key.isupper(): + self[key] = getattr(obj, key) + + def from_file( + self, + filename: str, + load: t.Callable[[t.IO[t.Any]], t.Mapping], + silent: bool = False, + ) -> bool: + """Update the values in the config from a file that is loaded + using the ``load`` parameter. The loaded data is passed to the + :meth:`from_mapping` method. + + .. code-block:: python + + import json + app.config.from_file("config.json", load=json.load) + + import toml + app.config.from_file("config.toml", load=toml.load) + + :param filename: The path to the data file. This can be an + absolute path or relative to the config root path. + :param load: A callable that takes a file handle and returns a + mapping of loaded data from the file. + :type load: ``Callable[[Reader], Mapping]`` where ``Reader`` + implements a ``read`` method. + :param silent: Ignore the file if it doesn't exist. + :return: ``True`` if the file was loaded successfully. + + .. versionadded:: 2.0 + """ + filename = os.path.join(self.root_path, filename) + + try: + with open(filename) as f: + obj = load(f) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR): + return False + + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + + return self.from_mapping(obj) + + def from_mapping( + self, mapping: t.Optional[t.Mapping[str, t.Any]] = None, **kwargs: t.Any + ) -> bool: + """Updates the config like :meth:`update` ignoring items with non-upper + keys. + :return: Always returns ``True``. + + .. versionadded:: 0.11 + """ + mappings: t.Dict[str, t.Any] = {} + if mapping is not None: + mappings.update(mapping) + mappings.update(kwargs) + for key, value in mappings.items(): + if key.isupper(): + self[key] = value + return True + + def get_namespace( + self, namespace: str, lowercase: bool = True, trim_namespace: bool = True + ) -> t.Dict[str, t.Any]: + """Returns a dictionary containing a subset of configuration options + that match the specified namespace/prefix. Example usage:: + + app.config['IMAGE_STORE_TYPE'] = 'fs' + app.config['IMAGE_STORE_PATH'] = '/var/app/images' + app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com' + image_store_config = app.config.get_namespace('IMAGE_STORE_') + + The resulting dictionary `image_store_config` would look like:: + + { + 'type': 'fs', + 'path': '/var/app/images', + 'base_url': 'http://img.website.com' + } + + This is often useful when configuration options map directly to + keyword arguments in functions or class constructors. + + :param namespace: a configuration namespace + :param lowercase: a flag indicating if the keys of the resulting + dictionary should be lowercase + :param trim_namespace: a flag indicating if the keys of the resulting + dictionary should not include the namespace + + .. versionadded:: 0.11 + """ + rv = {} + for k, v in self.items(): + if not k.startswith(namespace): + continue + if trim_namespace: + key = k[len(namespace) :] + else: + key = k + if lowercase: + key = key.lower() + rv[key] = v + return rv + + def __repr__(self) -> str: + return f"<{type(self).__name__} {dict.__repr__(self)}>" diff --git a/zhdo.space/lib/python3.9/site-packages/flask/ctx.py b/zhdo.space/lib/python3.9/site-packages/flask/ctx.py new file mode 100644 index 0000000..3ed8fd3 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/flask/ctx.py @@ -0,0 +1,513 @@ +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 + """ + top = _request_ctx_stack.top + + if top is None: + raise RuntimeError( + "This decorator can only be used when a request context is" + " active, such as within a view function." + ) + + 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 when a request context is" + " active, such as within a view function." + ) + + reqctx = top.copy() + + def wrapper(*args, **kwargs): + with reqctx: + return reqctx.app.ensure_sync(f)(*args, **kwargs) + + return update_wrapper(wrapper, f) + + +def has_request_context() -> bool: + """If you have code that wants to test if a request context is there or + not this function can be used. For instance, you may want to take advantage + of request information if the request object is available, but fail + silently if it is unavailable. + + :: + + class User(db.Model): + + def __init__(self, username, remote_addr=None): + self.username = username + if remote_addr is None and has_request_context(): + remote_addr = request.remote_addr + self.remote_addr = remote_addr + + Alternatively you can also just test any of the context bound objects + (such as :class:`request` or :class:`g`) for truthness:: + + class User(db.Model): + + def __init__(self, username, remote_addr=None): + self.username = username + if remote_addr is None and request: + remote_addr = request.remote_addr + self.remote_addr = remote_addr + + .. versionadded:: 0.7 + """ + return _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: t.Optional[type], + exc_value: t.Optional[BaseException], + tb: t.Optional[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) -> _AppCtxGlobals: + import warnings + + warnings.warn( + "Accessing 'g' on the request context is deprecated and" + " will be removed in Flask 2.2. Access `g` directly or from" + "the application context instead.", + DeprecationWarning, + stacklevel=2, + ) + return _app_ctx_stack.top.g + + @g.setter + def g(self, value: _AppCtxGlobals) -> None: + import warnings + + warnings.warn( + "Setting 'g' on the request context is deprecated and" + " will be removed in Flask 2.2. Set it on the application" + " context instead.", + DeprecationWarning, + stacklevel=2, + ) + _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: t.Optional[type], + exc_value: t.Optional[BaseException], + tb: t.Optional[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/zhdo.space/lib/python3.9/site-packages/flask/debughelpers.py b/zhdo.space/lib/python3.9/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..27d378c --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/flask/debughelpers.py @@ -0,0 +1,174 @@ +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 in debug mode if a routing redirect + would cause the browser to drop the method or body. This happens + when method is not GET, HEAD or OPTIONS and the status code is not + 307 or 308. + """ + + def __init__(self, request): + exc = request.routing_exception + buf = [ + f"A request was sent to '{request.url}', but routing issued" + f" a redirect to the canonical URL '{exc.new_url}'." + ] + + if f"{request.base_url}/" == exc.new_url.partition("?")[0]: + buf.append( + " The URL was defined with a trailing slash. Flask" + " will redirect to the URL with a trailing slash if it" + " was accessed without one." + ) + + buf.append( + " Send requests to the canonical URL, or use 307 or 308 for" + " routing redirects. Otherwise, browsers will drop form" + " data.\n\n" + "This exception is only raised in debug mode." + ) + super().__init__("".join(buf)) + + +def attach_enctype_error_multidict(request): + """Patch ``request.files.__getitem__`` to raise a descriptive error + about ``enctype=multipart/form-data``. + + :param request: The request to patch. + :meta private: + """ + oldcls = request.files.__class__ + + class newcls(oldcls): + def __getitem__(self, key): + try: + return super().__getitem__(key) + except KeyError as e: + if key not in request.form: + raise + + raise DebugFilesKeyError(request, key).with_traceback( + e.__traceback__ + ) from None + + newcls.__name__ = oldcls.__name__ + newcls.__module__ = oldcls.__module__ + request.files.__class__ = newcls + + +def _dump_loader_info(loader) -> t.Generator: + yield f"class: {type(loader).__module__}.{type(loader).__name__}" + for key, value in sorted(loader.__dict__.items()): + if key.startswith("_"): + continue + if isinstance(value, (tuple, list)): + if not all(isinstance(x, str) for x in value): + continue + yield f"{key}:" + for item in value: + yield f" - {item}" + continue + elif not isinstance(value, (str, int, float, bool)): + continue + yield f"{key}: {value!r}" + + +def explain_template_loading_attempts(app: Flask, template, attempts) -> None: + """This should help developers understand what failed""" + info = [f"Locating template {template!r}:"] + total_found = 0 + blueprint = None + 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/zhdo.space/lib/python3.9/site-packages/flask/globals.py b/zhdo.space/lib/python3.9/site-packages/flask/globals.py new file mode 100644 index 0000000..6d91c75 --- /dev/null +++ b/zhdo.space/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/zhdo.space/lib/python3.9/site-packages/flask/helpers.py b/zhdo.space/lib/python3.9/site-packages/flask/helpers.py new file mode 100644 index 0000000..fe47500 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/flask/helpers.py @@ -0,0 +1,790 @@ +import os +import pkgutil +import socket +import sys +import typing as t +import warnings +from datetime import datetime +from functools import lru_cache +from functools import update_wrapper +from threading import RLock + +import werkzeug.utils +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) # type: ignore + + +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.2.", + 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.2.", + 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.2.", + 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 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.2.", + 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__") and mod.__file__ is not None: + return os.path.dirname(os.path.abspath(mod.__file__)) + + # Next attempt: check the loader. + loader = pkgutil.get_loader(import_name) + + # Loader does not exist or we're referring to an unloaded main + # module or a main module without path (interactive sessions), go + # with the current working directory. + if loader is None or import_name == "__main__": + return os.getcwd() + + if hasattr(loader, "get_filename"): + filepath = loader.get_filename(import_name) # type: ignore + else: + # Fall back to imports. + __import__(import_name) + mod = sys.modules[import_name] + filepath = getattr(mod, "__file__", None) + + # If we don't have a file path it might be because it is a + # namespace package. In this case pick the root path from the + # first module that is contained in the package. + if filepath is None: + raise RuntimeError( + "No root path can be found for the provided module" + f" {import_name!r}. This can happen because the module" + " came from an import hook that does not provide file" + " name information or because it's a namespace package." + " In this case the root path needs to be explicitly" + " provided." + ) + + # filepath is import_name.py for a module, or __init__.py for a package. + return os.path.dirname(os.path.abspath(filepath)) + + +class locked_cached_property(werkzeug.utils.cached_property): + """A :func:`property` that is only evaluated once. Like + :class:`werkzeug.utils.cached_property` except access uses a lock + for thread safety. + + .. versionchanged:: 2.0 + Inherits from Werkzeug's ``cached_property`` (and ``property``). + """ + + def __init__( + self, + fget: t.Callable[[t.Any], t.Any], + name: t.Optional[str] = None, + doc: t.Optional[str] = None, + ) -> None: + super().__init__(fget, name=name, doc=doc) + self.lock = RLock() + + def __get__(self, obj: object, type: type = None) -> t.Any: # type: ignore + if obj is None: + return self + + with self.lock: + return super().__get__(obj, type=type) + + def __set__(self, obj: object, value: t.Any) -> None: + with self.lock: + super().__set__(obj, value) + + def __delete__(self, obj: object) -> None: + with self.lock: + super().__delete__(obj) + + +def is_ip(value: str) -> bool: + """Determine if the given string is an IP address. + + :param value: value to check + :type value: str + + :return: True if string is an IP address + :rtype: bool + """ + for family in (socket.AF_INET, socket.AF_INET6): + try: + socket.inet_pton(family, value) + except OSError: + pass + else: + return True + + return False + + +@lru_cache(maxsize=None) +def _split_blueprint_path(name: str) -> t.List[str]: + out: t.List[str] = [name] + + if "." in name: + out.extend(_split_blueprint_path(name.rpartition(".")[0])) + + return out diff --git a/zhdo.space/lib/python3.9/site-packages/flask/json/__init__.py b/zhdo.space/lib/python3.9/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..edc9793 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/flask/json/__init__.py @@ -0,0 +1,303 @@ +import dataclasses +import decimal +import json as _json +import typing as t +import uuid +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 + + +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, (decimal.Decimal, uuid.UUID)): + return str(o) + if dataclasses and dataclasses.is_dataclass(o): + return dataclasses.asdict(o) + if hasattr(o, "__html__"): + return str(o.__html__()) + 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 + + # Only set a custom encoder if it has custom behavior. This is + # faster on PyPy. + if cls is not _json.JSONEncoder: + kwargs.setdefault("cls", cls) + + 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 + + # Only set a custom decoder if it has custom behavior. This is + # faster on PyPy. + if cls not in {JSONDecoder, _json.JSONDecoder}: + kwargs.setdefault("cls", cls) + + +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.2 + :class:`decimal.Decimal` is supported by converting to a string. + + .. 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) + return _json.dumps(obj, **kwargs) + + +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) + _json.dump(obj, fp, **kwargs) + + +def loads( + s: t.Union[str, bytes], + 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) + 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) + 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 + ``') + # => <script> do_nasty_stuff() </script> + # sanitize_html('Click here for $100') + # => Click here for $100 + def sanitize_token(self, token): + + # accommodate filters which use token_type differently + token_type = token["type"] + if token_type in ("StartTag", "EndTag", "EmptyTag"): + name = token["name"] + namespace = token["namespace"] + if ((namespace, name) in self.allowed_elements or + (namespace is None and + (namespaces["html"], name) in self.allowed_elements)): + return self.allowed_token(token) + else: + return self.disallowed_token(token) + elif token_type == "Comment": + pass + else: + return token + + def allowed_token(self, token): + if "data" in token: + attrs = token["data"] + attr_names = set(attrs.keys()) + + # Remove forbidden attributes + for to_remove in (attr_names - self.allowed_attributes): + del token["data"][to_remove] + attr_names.remove(to_remove) + + # Remove attributes with disallowed URL values + for attr in (attr_names & self.attr_val_is_uri): + assert attr in attrs + # I don't have a clue where this regexp comes from or why it matches those + # characters, nor why we call unescape. I just know it's always been here. + # Should you be worried by this comment in a sanitizer? Yes. On the other hand, all + # this will do is remove *more* than it otherwise would. + val_unescaped = re.sub("[`\x00-\x20\x7f-\xa0\\s]+", '', + unescape(attrs[attr])).lower() + # remove replacement characters from unescaped characters + val_unescaped = val_unescaped.replace("\ufffd", "") + try: + uri = urlparse.urlparse(val_unescaped) + except ValueError: + uri = None + del attrs[attr] + if uri and uri.scheme: + if uri.scheme not in self.allowed_protocols: + del attrs[attr] + if uri.scheme == 'data': + m = data_content_type.match(uri.path) + if not m: + del attrs[attr] + elif m.group('content_type') not in self.allowed_content_types: + del attrs[attr] + + for attr in self.svg_attr_val_allows_ref: + if attr in attrs: + attrs[attr] = re.sub(r'url\s*\(\s*[^#\s][^)]+?\)', + ' ', + unescape(attrs[attr])) + if (token["name"] in self.svg_allow_local_href and + (namespaces['xlink'], 'href') in attrs and re.search(r'^\s*[^#\s].*', + attrs[(namespaces['xlink'], 'href')])): + del attrs[(namespaces['xlink'], 'href')] + if (None, 'style') in attrs: + attrs[(None, 'style')] = self.sanitize_css(attrs[(None, 'style')]) + token["data"] = attrs + return token + + def disallowed_token(self, token): + token_type = token["type"] + if token_type == "EndTag": + token["data"] = "" % token["name"] + elif token["data"]: + assert token_type in ("StartTag", "EmptyTag") + attrs = [] + for (ns, name), v in token["data"].items(): + attrs.append(' %s="%s"' % (name if ns is None else "%s:%s" % (prefixes[ns], name), escape(v))) + token["data"] = "<%s%s>" % (token["name"], ''.join(attrs)) + else: + token["data"] = "<%s>" % token["name"] + if token.get("selfClosing"): + token["data"] = token["data"][:-1] + "/>" + + token["type"] = "Characters" + + del token["name"] + return token + + def sanitize_css(self, style): + # disallow urls + style = re.compile(r'url\s*\(\s*[^\s)]+?\s*\)\s*').sub(' ', style) + + # gauntlet + if not re.match(r"""^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$""", style): + return '' + if not re.match(r"^\s*([-\w]+\s*:[^:;]*(;\s*|$))*$", style): + return '' + + clean = [] + for prop, value in re.findall(r"([-\w]+)\s*:\s*([^:;]*)", style): + if not value: + continue + if prop.lower() in self.allowed_css_properties: + clean.append(prop + ': ' + value + ';') + elif prop.split('-')[0].lower() in ['background', 'border', 'margin', + 'padding']: + for keyword in value.split(): + if keyword not in self.allowed_css_keywords and \ + not re.match(r"^(#[0-9a-fA-F]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$", keyword): # noqa + break + else: + clean.append(prop + ': ' + value + ';') + elif prop.lower() in self.allowed_svg_properties: + clean.append(prop + ': ' + value + ';') + + return ' '.join(clean) diff --git a/zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/whitespace.py b/zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/whitespace.py new file mode 100644 index 0000000..0d12584 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/filters/whitespace.py @@ -0,0 +1,38 @@ +from __future__ import absolute_import, division, unicode_literals + +import re + +from . import base +from ..constants import rcdataElements, spaceCharacters +spaceCharacters = "".join(spaceCharacters) + +SPACES_REGEX = re.compile("[%s]+" % spaceCharacters) + + +class Filter(base.Filter): + """Collapses whitespace except in pre, textarea, and script elements""" + spacePreserveElements = frozenset(["pre", "textarea"] + list(rcdataElements)) + + def __iter__(self): + preserve = 0 + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag" \ + and (preserve or token["name"] in self.spacePreserveElements): + preserve += 1 + + elif type == "EndTag" and preserve: + preserve -= 1 + + elif not preserve and type == "SpaceCharacters" and token["data"]: + # Test on token["data"] above to not introduce spaces where there were not + token["data"] = " " + + elif not preserve and type == "Characters": + token["data"] = collapse_spaces(token["data"]) + + yield token + + +def collapse_spaces(text): + return SPACES_REGEX.sub(' ', text) diff --git a/zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/html5parser.py b/zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/html5parser.py new file mode 100644 index 0000000..d06784f --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/pip/_vendor/html5lib/html5parser.py @@ -0,0 +1,2795 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import with_metaclass, viewkeys + +import types + +from . import _inputstream +from . import _tokenizer + +from . import treebuilders +from .treebuilders.base import Marker + +from . import _utils +from .constants import ( + spaceCharacters, asciiUpper2Lower, + specialElements, headingElements, cdataElements, rcdataElements, + tokenTypes, tagTokenTypes, + namespaces, + htmlIntegrationPointElements, mathmlTextIntegrationPointElements, + adjustForeignAttributes as adjustForeignAttributesMap, + adjustMathMLAttributes, adjustSVGAttributes, + E, + _ReparseException +) + + +def parse(doc, treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML document as a string or file-like object into a tree + + :arg doc: the document to parse as a string or file-like object + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import parse + >>> parse('

    This is a doc

    ') + + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parse(doc, **kwargs) + + +def parseFragment(doc, container="div", treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML fragment as a string or file-like object into a tree + + :arg doc: the fragment to parse as a string or file-like object + + :arg container: the container context to parse the fragment in + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import parseFragment + >>> parseFragment('this is a fragment') + + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parseFragment(doc, container=container, **kwargs) + + +def method_decorator_metaclass(function): + class Decorated(type): + def __new__(meta, classname, bases, classDict): + for attributeName, attribute in classDict.items(): + if isinstance(attribute, types.FunctionType): + attribute = function(attribute) + + classDict[attributeName] = attribute + return type.__new__(meta, classname, bases, classDict) + return Decorated + + +class HTMLParser(object): + """HTML parser + + Generates a tree structure from a stream of (possibly malformed) HTML. + + """ + + def __init__(self, tree=None, strict=False, namespaceHTMLElements=True, debug=False): + """ + :arg tree: a treebuilder class controlling the type of tree that will be + returned. Built in treebuilders can be accessed through + html5lib.treebuilders.getTreeBuilder(treeType) + + :arg strict: raise an exception when a parse error is encountered + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :arg debug: whether or not to enable debug mode which logs things + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() # generates parser with etree builder + >>> parser = HTMLParser('lxml', strict=True) # generates parser with lxml builder which is strict + + """ + + # Raise an exception on the first error encountered + self.strict = strict + + if tree is None: + tree = treebuilders.getTreeBuilder("etree") + self.tree = tree(namespaceHTMLElements) + self.errors = [] + + self.phases = {name: cls(self, self.tree) for name, cls in + getPhases(debug).items()} + + def _parse(self, stream, innerHTML=False, container="div", scripting=False, **kwargs): + + self.innerHTMLMode = innerHTML + self.container = container + self.scripting = scripting + self.tokenizer = _tokenizer.HTMLTokenizer(stream, parser=self, **kwargs) + self.reset() + + try: + self.mainLoop() + except _ReparseException: + self.reset() + self.mainLoop() + + def reset(self): + self.tree.reset() + self.firstStartTag = False + self.errors = [] + self.log = [] # only used with debug mode + # "quirks" / "limited quirks" / "no quirks" + self.compatMode = "no quirks" + + if self.innerHTMLMode: + self.innerHTML = self.container.lower() + + if self.innerHTML in cdataElements: + self.tokenizer.state = self.tokenizer.rcdataState + elif self.innerHTML in rcdataElements: + self.tokenizer.state = self.tokenizer.rawtextState + elif self.innerHTML == 'plaintext': + self.tokenizer.state = self.tokenizer.plaintextState + else: + # state already is data state + # self.tokenizer.state = self.tokenizer.dataState + pass + self.phase = self.phases["beforeHtml"] + self.phase.insertHtmlElement() + self.resetInsertionMode() + else: + self.innerHTML = False # pylint:disable=redefined-variable-type + self.phase = self.phases["initial"] + + self.lastPhase = None + + self.beforeRCDataPhase = None + + self.framesetOK = True + + @property + def documentEncoding(self): + """Name of the character encoding that was used to decode the input stream, or + :obj:`None` if that is not determined yet + + """ + if not hasattr(self, 'tokenizer'): + return None + return self.tokenizer.stream.charEncoding[0].name + + def isHTMLIntegrationPoint(self, element): + if (element.name == "annotation-xml" and + element.namespace == namespaces["mathml"]): + return ("encoding" in element.attributes and + element.attributes["encoding"].translate( + asciiUpper2Lower) in + ("text/html", "application/xhtml+xml")) + else: + return (element.namespace, element.name) in htmlIntegrationPointElements + + def isMathMLTextIntegrationPoint(self, element): + return (element.namespace, element.name) in mathmlTextIntegrationPointElements + + def mainLoop(self): + CharactersToken = tokenTypes["Characters"] + SpaceCharactersToken = tokenTypes["SpaceCharacters"] + StartTagToken = tokenTypes["StartTag"] + EndTagToken = tokenTypes["EndTag"] + CommentToken = tokenTypes["Comment"] + DoctypeToken = tokenTypes["Doctype"] + ParseErrorToken = tokenTypes["ParseError"] + + for token in self.tokenizer: + prev_token = None + new_token = token + while new_token is not None: + prev_token = new_token + currentNode = self.tree.openElements[-1] if self.tree.openElements else None + currentNodeNamespace = currentNode.namespace if currentNode else None + currentNodeName = currentNode.name if currentNode else None + + type = new_token["type"] + + if type == ParseErrorToken: + self.parseError(new_token["data"], new_token.get("datavars", {})) + new_token = None + else: + if (len(self.tree.openElements) == 0 or + currentNodeNamespace == self.tree.defaultNamespace or + (self.isMathMLTextIntegrationPoint(currentNode) and + ((type == StartTagToken and + token["name"] not in frozenset(["mglyph", "malignmark"])) or + type in (CharactersToken, SpaceCharactersToken))) or + (currentNodeNamespace == namespaces["mathml"] and + currentNodeName == "annotation-xml" and + type == StartTagToken and + token["name"] == "svg") or + (self.isHTMLIntegrationPoint(currentNode) and + type in (StartTagToken, CharactersToken, SpaceCharactersToken))): + phase = self.phase + else: + phase = self.phases["inForeignContent"] + + if type == CharactersToken: + new_token = phase.processCharacters(new_token) + elif type == SpaceCharactersToken: + new_token = phase.processSpaceCharacters(new_token) + elif type == StartTagToken: + new_token = phase.processStartTag(new_token) + elif type == EndTagToken: + new_token = phase.processEndTag(new_token) + elif type == CommentToken: + new_token = phase.processComment(new_token) + elif type == DoctypeToken: + new_token = phase.processDoctype(new_token) + + if (type == StartTagToken and prev_token["selfClosing"] and + not prev_token["selfClosingAcknowledged"]): + self.parseError("non-void-element-with-trailing-solidus", + {"name": prev_token["name"]}) + + # When the loop finishes it's EOF + reprocess = True + phases = [] + while reprocess: + phases.append(self.phase) + reprocess = self.phase.processEOF() + if reprocess: + assert self.phase not in phases + + def parse(self, stream, *args, **kwargs): + """Parse a HTML document into a well-formed tree + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element). + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parse('

    This is a doc

    ') + + + """ + self._parse(stream, False, None, *args, **kwargs) + return self.tree.getDocument() + + def parseFragment(self, stream, *args, **kwargs): + """Parse a HTML fragment into a well-formed tree fragment + + :arg container: name of the element we're setting the innerHTML + property if set to None, default to 'div' + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parseFragment('this is a fragment') + + + """ + self._parse(stream, True, *args, **kwargs) + return self.tree.getFragment() + + def parseError(self, errorcode="XXX-undefined-error", datavars=None): + # XXX The idea is to make errorcode mandatory. + if datavars is None: + datavars = {} + self.errors.append((self.tokenizer.stream.position(), errorcode, datavars)) + if self.strict: + raise ParseError(E[errorcode] % datavars) + + def adjustMathMLAttributes(self, token): + adjust_attributes(token, adjustMathMLAttributes) + + def adjustSVGAttributes(self, token): + adjust_attributes(token, adjustSVGAttributes) + + def adjustForeignAttributes(self, token): + adjust_attributes(token, adjustForeignAttributesMap) + + def reparseTokenNormal(self, token): + # pylint:disable=unused-argument + self.parser.phase() + + def resetInsertionMode(self): + # The name of this method is mostly historical. (It's also used in the + # specification.) + last = False + newModes = { + "select": "inSelect", + "td": "inCell", + "th": "inCell", + "tr": "inRow", + "tbody": "inTableBody", + "thead": "inTableBody", + "tfoot": "inTableBody", + "caption": "inCaption", + "colgroup": "inColumnGroup", + "table": "inTable", + "head": "inBody", + "body": "inBody", + "frameset": "inFrameset", + "html": "beforeHead" + } + for node in self.tree.openElements[::-1]: + nodeName = node.name + new_phase = None + if node == self.tree.openElements[0]: + assert self.innerHTML + last = True + nodeName = self.innerHTML + # Check for conditions that should only happen in the innerHTML + # case + if nodeName in ("select", "colgroup", "head", "html"): + assert self.innerHTML + + if not last and node.namespace != self.tree.defaultNamespace: + continue + + if nodeName in newModes: + new_phase = self.phases[newModes[nodeName]] + break + elif last: + new_phase = self.phases["inBody"] + break + + self.phase = new_phase + + def parseRCDataRawtext(self, token, contentType): + # Generic RCDATA/RAWTEXT Parsing algorithm + assert contentType in ("RAWTEXT", "RCDATA") + + self.tree.insertElement(token) + + if contentType == "RAWTEXT": + self.tokenizer.state = self.tokenizer.rawtextState + else: + self.tokenizer.state = self.tokenizer.rcdataState + + self.originalPhase = self.phase + + self.phase = self.phases["text"] + + +@_utils.memoize +def getPhases(debug): + def log(function): + """Logger that records which phase processes each token""" + type_names = {value: key for key, value in tokenTypes.items()} + + def wrapped(self, *args, **kwargs): + if function.__name__.startswith("process") and len(args) > 0: + token = args[0] + info = {"type": type_names[token['type']]} + if token['type'] in tagTokenTypes: + info["name"] = token['name'] + + self.parser.log.append((self.parser.tokenizer.state.__name__, + self.parser.phase.__class__.__name__, + self.__class__.__name__, + function.__name__, + info)) + return function(self, *args, **kwargs) + else: + return function(self, *args, **kwargs) + return wrapped + + def getMetaclass(use_metaclass, metaclass_func): + if use_metaclass: + return method_decorator_metaclass(metaclass_func) + else: + return type + + # pylint:disable=unused-argument + class Phase(with_metaclass(getMetaclass(debug, log))): + """Base class for helper object that implements each phase of processing + """ + __slots__ = ("parser", "tree", "__startTagCache", "__endTagCache") + + def __init__(self, parser, tree): + self.parser = parser + self.tree = tree + self.__startTagCache = {} + self.__endTagCache = {} + + def processEOF(self): + raise NotImplementedError + + def processComment(self, token): + # For most phases the following is correct. Where it's not it will be + # overridden. + self.tree.insertComment(token, self.tree.openElements[-1]) + + def processDoctype(self, token): + self.parser.parseError("unexpected-doctype") + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processSpaceCharacters(self, token): + self.tree.insertText(token["data"]) + + def processStartTag(self, token): + # Note the caching is done here rather than BoundMethodDispatcher as doing it there + # requires a circular reference to the Phase, and this ends up with a significant + # (CPython 2.7, 3.8) GC cost when parsing many short inputs + name = token["name"] + # In Py2, using `in` is quicker in general than try/except KeyError + # In Py3, `in` is quicker when there are few cache hits (typically short inputs) + if name in self.__startTagCache: + func = self.__startTagCache[name] + else: + func = self.__startTagCache[name] = self.startTagHandler[name] + # bound the cache size in case we get loads of unknown tags + while len(self.__startTagCache) > len(self.startTagHandler) * 1.1: + # this makes the eviction policy random on Py < 3.7 and FIFO >= 3.7 + self.__startTagCache.pop(next(iter(self.__startTagCache))) + return func(token) + + def startTagHtml(self, token): + if not self.parser.firstStartTag and token["name"] == "html": + self.parser.parseError("non-html-root") + # XXX Need a check here to see if the first start tag token emitted is + # this token... If it's not, invoke self.parser.parseError(). + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[0].attributes: + self.tree.openElements[0].attributes[attr] = value + self.parser.firstStartTag = False + + def processEndTag(self, token): + # Note the caching is done here rather than BoundMethodDispatcher as doing it there + # requires a circular reference to the Phase, and this ends up with a significant + # (CPython 2.7, 3.8) GC cost when parsing many short inputs + name = token["name"] + # In Py2, using `in` is quicker in general than try/except KeyError + # In Py3, `in` is quicker when there are few cache hits (typically short inputs) + if name in self.__endTagCache: + func = self.__endTagCache[name] + else: + func = self.__endTagCache[name] = self.endTagHandler[name] + # bound the cache size in case we get loads of unknown tags + while len(self.__endTagCache) > len(self.endTagHandler) * 1.1: + # this makes the eviction policy random on Py < 3.7 and FIFO >= 3.7 + self.__endTagCache.pop(next(iter(self.__endTagCache))) + return func(token) + + class InitialPhase(Phase): + __slots__ = tuple() + + def processSpaceCharacters(self, token): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + correct = token["correct"] + + if (name != "html" or publicId is not None or + systemId is not None and systemId != "about:legacy-compat"): + self.parser.parseError("unknown-doctype") + + if publicId is None: + publicId = "" + + self.tree.insertDoctype(token) + + if publicId != "": + publicId = publicId.translate(asciiUpper2Lower) + + if (not correct or token["name"] != "html" or + publicId.startswith( + ("+//silmaril//dtd html pro v0r11 19970101//", + "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", + "-//as//dtd html 3.0 aswedit + extensions//", + "-//ietf//dtd html 2.0 level 1//", + "-//ietf//dtd html 2.0 level 2//", + "-//ietf//dtd html 2.0 strict level 1//", + "-//ietf//dtd html 2.0 strict level 2//", + "-//ietf//dtd html 2.0 strict//", + "-//ietf//dtd html 2.0//", + "-//ietf//dtd html 2.1e//", + "-//ietf//dtd html 3.0//", + "-//ietf//dtd html 3.2 final//", + "-//ietf//dtd html 3.2//", + "-//ietf//dtd html 3//", + "-//ietf//dtd html level 0//", + "-//ietf//dtd html level 1//", + "-//ietf//dtd html level 2//", + "-//ietf//dtd html level 3//", + "-//ietf//dtd html strict level 0//", + "-//ietf//dtd html strict level 1//", + "-//ietf//dtd html strict level 2//", + "-//ietf//dtd html strict level 3//", + "-//ietf//dtd html strict//", + "-//ietf//dtd html//", + "-//metrius//dtd metrius presentational//", + "-//microsoft//dtd internet explorer 2.0 html strict//", + "-//microsoft//dtd internet explorer 2.0 html//", + "-//microsoft//dtd internet explorer 2.0 tables//", + "-//microsoft//dtd internet explorer 3.0 html strict//", + "-//microsoft//dtd internet explorer 3.0 html//", + "-//microsoft//dtd internet explorer 3.0 tables//", + "-//netscape comm. corp.//dtd html//", + "-//netscape comm. corp.//dtd strict html//", + "-//o'reilly and associates//dtd html 2.0//", + "-//o'reilly and associates//dtd html extended 1.0//", + "-//o'reilly and associates//dtd html extended relaxed 1.0//", + "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", + "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", + "-//spyglass//dtd html 2.0 extended//", + "-//sq//dtd html 2.0 hotmetal + extensions//", + "-//sun microsystems corp.//dtd hotjava html//", + "-//sun microsystems corp.//dtd hotjava strict html//", + "-//w3c//dtd html 3 1995-03-24//", + "-//w3c//dtd html 3.2 draft//", + "-//w3c//dtd html 3.2 final//", + "-//w3c//dtd html 3.2//", + "-//w3c//dtd html 3.2s draft//", + "-//w3c//dtd html 4.0 frameset//", + "-//w3c//dtd html 4.0 transitional//", + "-//w3c//dtd html experimental 19960712//", + "-//w3c//dtd html experimental 970421//", + "-//w3c//dtd w3 html//", + "-//w3o//dtd w3 html 3.0//", + "-//webtechs//dtd mozilla html 2.0//", + "-//webtechs//dtd mozilla html//")) or + publicId in ("-//w3o//dtd w3 html strict 3.0//en//", + "-/w3c/dtd html 4.0 transitional/en", + "html") or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is None or + systemId and systemId.lower() == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"): + self.parser.compatMode = "quirks" + elif (publicId.startswith( + ("-//w3c//dtd xhtml 1.0 frameset//", + "-//w3c//dtd xhtml 1.0 transitional//")) or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is not None): + self.parser.compatMode = "limited quirks" + + self.parser.phase = self.parser.phases["beforeHtml"] + + def anythingElse(self): + self.parser.compatMode = "quirks" + self.parser.phase = self.parser.phases["beforeHtml"] + + def processCharacters(self, token): + self.parser.parseError("expected-doctype-but-got-chars") + self.anythingElse() + return token + + def processStartTag(self, token): + self.parser.parseError("expected-doctype-but-got-start-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEndTag(self, token): + self.parser.parseError("expected-doctype-but-got-end-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEOF(self): + self.parser.parseError("expected-doctype-but-got-eof") + self.anythingElse() + return True + + class BeforeHtmlPhase(Phase): + __slots__ = tuple() + + # helper methods + def insertHtmlElement(self): + self.tree.insertRoot(impliedTagToken("html", "StartTag")) + self.parser.phase = self.parser.phases["beforeHead"] + + # other + def processEOF(self): + self.insertHtmlElement() + return True + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.insertHtmlElement() + return token + + def processStartTag(self, token): + if token["name"] == "html": + self.parser.firstStartTag = True + self.insertHtmlElement() + return token + + def processEndTag(self, token): + if token["name"] not in ("head", "body", "html", "br"): + self.parser.parseError("unexpected-end-tag-before-html", + {"name": token["name"]}) + else: + self.insertHtmlElement() + return token + + class BeforeHeadPhase(Phase): + __slots__ = tuple() + + def processEOF(self): + self.startTagHead(impliedTagToken("head", "StartTag")) + return True + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.tree.insertElement(token) + self.tree.headPointer = self.tree.openElements[-1] + self.parser.phase = self.parser.phases["inHead"] + + def startTagOther(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagImplyHead(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagOther(self, token): + self.parser.parseError("end-tag-after-implied-root", + {"name": token["name"]}) + + startTagHandler = _utils.MethodDispatcher([ + ("html", startTagHtml), + ("head", startTagHead) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + (("head", "body", "html", "br"), endTagImplyHead) + ]) + endTagHandler.default = endTagOther + + class InHeadPhase(Phase): + __slots__ = tuple() + + # the real thing + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.parser.parseError("two-heads-are-not-better-than-one") + + def startTagBaseLinkCommand(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMeta(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + attributes = token["data"] + if self.parser.tokenizer.stream.charEncoding[1] == "tentative": + if "charset" in attributes: + self.parser.tokenizer.stream.changeEncoding(attributes["charset"]) + elif ("content" in attributes and + "http-equiv" in attributes and + attributes["http-equiv"].lower() == "content-type"): + # Encoding it as UTF-8 here is a hack, as really we should pass + # the abstract Unicode string, and just use the + # ContentAttrParser on that, but using UTF-8 allows all chars + # to be encoded and as a ASCII-superset works. + data = _inputstream.EncodingBytes(attributes["content"].encode("utf-8")) + parser = _inputstream.ContentAttrParser(data) + codec = parser.parse() + self.parser.tokenizer.stream.changeEncoding(codec) + + def startTagTitle(self, token): + self.parser.parseRCDataRawtext(token, "RCDATA") + + def startTagNoFramesStyle(self, token): + # Need to decide whether to implement the scripting-disabled case + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagNoscript(self, token): + if self.parser.scripting: + self.parser.parseRCDataRawtext(token, "RAWTEXT") + else: + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inHeadNoscript"] + + def startTagScript(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.scriptDataState + self.parser.originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["text"] + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHead(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "head", "Expected head got %s" % node.name + self.parser.phase = self.parser.phases["afterHead"] + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.endTagHead(impliedTagToken("head")) + + startTagHandler = _utils.MethodDispatcher([ + ("html", startTagHtml), + ("title", startTagTitle), + (("noframes", "style"), startTagNoFramesStyle), + ("noscript", startTagNoscript), + ("script", startTagScript), + (("base", "basefont", "bgsound", "command", "link"), + startTagBaseLinkCommand), + ("meta", startTagMeta), + ("head", startTagHead) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + ("head", endTagHead), + (("br", "html", "body"), endTagHtmlBodyBr) + ]) + endTagHandler.default = endTagOther + + class InHeadNoscriptPhase(Phase): + __slots__ = tuple() + + def processEOF(self): + self.parser.parseError("eof-in-head-noscript") + self.anythingElse() + return True + + def processComment(self, token): + return self.parser.phases["inHead"].processComment(token) + + def processCharacters(self, token): + self.parser.parseError("char-in-head-noscript") + self.anythingElse() + return token + + def processSpaceCharacters(self, token): + return self.parser.phases["inHead"].processSpaceCharacters(token) + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBaseLinkCommand(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagHeadNoscript(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagNoscript(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "noscript", "Expected noscript got %s" % node.name + self.parser.phase = self.parser.phases["inHead"] + + def endTagBr(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + # Caller must raise parse error first! + self.endTagNoscript(impliedTagToken("noscript")) + + startTagHandler = _utils.MethodDispatcher([ + ("html", startTagHtml), + (("basefont", "bgsound", "link", "meta", "noframes", "style"), startTagBaseLinkCommand), + (("head", "noscript"), startTagHeadNoscript), + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + ("noscript", endTagNoscript), + ("br", endTagBr), + ]) + endTagHandler.default = endTagOther + + class AfterHeadPhase(Phase): + __slots__ = tuple() + + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBody(self, token): + self.parser.framesetOK = False + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inBody"] + + def startTagFrameset(self, token): + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagFromHead(self, token): + self.parser.parseError("unexpected-start-tag-out-of-my-head", + {"name": token["name"]}) + self.tree.openElements.append(self.tree.headPointer) + self.parser.phases["inHead"].processStartTag(token) + for node in self.tree.openElements[::-1]: + if node.name == "head": + self.tree.openElements.remove(node) + break + + def startTagHead(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.tree.insertElement(impliedTagToken("body", "StartTag")) + self.parser.phase = self.parser.phases["inBody"] + self.parser.framesetOK = True + + startTagHandler = _utils.MethodDispatcher([ + ("html", startTagHtml), + ("body", startTagBody), + ("frameset", startTagFrameset), + (("base", "basefont", "bgsound", "link", "meta", "noframes", "script", + "style", "title"), + startTagFromHead), + ("head", startTagHead) + ]) + startTagHandler.default = startTagOther + endTagHandler = _utils.MethodDispatcher([(("body", "html", "br"), + endTagHtmlBodyBr)]) + endTagHandler.default = endTagOther + + class InBodyPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#parsing-main-inbody + # the really-really-really-very crazy mode + __slots__ = ("processSpaceCharacters",) + + def __init__(self, *args, **kwargs): + super(InBodyPhase, self).__init__(*args, **kwargs) + # Set this to the default handler + self.processSpaceCharacters = self.processSpaceCharactersNonPre + + def isMatchingFormattingElement(self, node1, node2): + return (node1.name == node2.name and + node1.namespace == node2.namespace and + node1.attributes == node2.attributes) + + # helper + def addFormattingElement(self, token): + self.tree.insertElement(token) + element = self.tree.openElements[-1] + + matchingElements = [] + for node in self.tree.activeFormattingElements[::-1]: + if node is Marker: + break + elif self.isMatchingFormattingElement(node, element): + matchingElements.append(node) + + assert len(matchingElements) <= 3 + if len(matchingElements) == 3: + self.tree.activeFormattingElements.remove(matchingElements[-1]) + self.tree.activeFormattingElements.append(element) + + # the real deal + def processEOF(self): + allowed_elements = frozenset(("dd", "dt", "li", "p", "tbody", "td", + "tfoot", "th", "thead", "tr", "body", + "html")) + for node in self.tree.openElements[::-1]: + if node.name not in allowed_elements: + self.parser.parseError("expected-closing-tag-but-got-eof") + break + # Stop parsing + + def processSpaceCharactersDropNewline(self, token): + # Sometimes (start of
    , , and 
    +
    +
    + The debugger caught an exception in your WSGI application. You can now + look at the traceback which led to the error. + If you enable JavaScript you can also use additional features such as code + execution (if the evalex feature is enabled), automatic pasting of the + exceptions and much more. +
    +""" + + FOOTER + + """ + +""" +) + +CONSOLE_HTML = ( + HEADER + + """\ +

    Interactive Console

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

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

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

    {title}

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

    {description}

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

    {escape(self.name)}

    \n" + f"{self.get_description(environ)}\n" + ) + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + """Get a list of headers.""" + return [("Content-Type", "text/html; charset=utf-8")] + + def get_response( + self, + environ: t.Optional[t.Union["WSGIEnvironment", "WSGIRequest"]] = None, + scope: t.Optional[dict] = None, + ) -> "Response": + """Get a response object. If one was passed to the exception + it's returned directly. + + :param environ: the optional environ for the request. This + can be used to modify the response depending + on how the request looked like. + :return: a :class:`Response` object or a subclass thereof. + """ + from .wrappers.response import Response as WSGIResponse # noqa: F811 + + if self.response is not None: + return self.response + if environ is not None: + environ = _get_environ(environ) + headers = self.get_headers(environ, scope) + return WSGIResponse(self.get_body(environ, scope), self.code, headers) + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + """Call the exception as WSGI application. + + :param environ: the WSGI environment. + :param start_response: the response callable provided by the WSGI + server. + """ + response = t.cast("WSGIResponse", self.get_response(environ)) + return response(environ, start_response) + + def __str__(self) -> str: + code = self.code if self.code is not None else "???" + return f"{code} {self.name}: {self.description}" + + def __repr__(self) -> str: + code = self.code if self.code is not None else "???" + return f"<{type(self).__name__} '{code}: {self.name}'>" + + +class BadRequest(HTTPException): + """*400* `Bad Request` + + Raise if the browser sends something to the application the application + or server cannot handle. + """ + + code = 400 + description = ( + "The browser (or proxy) sent a request that this server could " + "not understand." + ) + + +class BadRequestKeyError(BadRequest, KeyError): + """An exception that is used to signal both a :exc:`KeyError` and a + :exc:`BadRequest`. Used by many of the datastructures. + """ + + _description = BadRequest.description + #: Show the KeyError along with the HTTP error message in the + #: response. This should be disabled in production, but can be + #: useful in a debug mode. + show_exception = False + + def __init__(self, arg: t.Optional[str] = None, *args: t.Any, **kwargs: t.Any): + super().__init__(*args, **kwargs) + + if arg is None: + KeyError.__init__(self) + else: + KeyError.__init__(self, arg) + + @property # type: ignore + def description(self) -> str: # type: ignore + if self.show_exception: + return ( + f"{self._description}\n" + f"{KeyError.__name__}: {KeyError.__str__(self)}" + ) + + return self._description + + @description.setter + def description(self, value: str) -> None: + self._description = value + + +class ClientDisconnected(BadRequest): + """Internal exception that is raised if Werkzeug detects a disconnected + client. Since the client is already gone at that point attempting to + send the error message to the client might not work and might ultimately + result in another exception in the server. Mainly this is here so that + it is silenced by default as far as Werkzeug is concerned. + + Since disconnections cannot be reliably detected and are unspecified + by WSGI to a large extent this might or might not be raised if a client + is gone. + + .. versionadded:: 0.8 + """ + + +class SecurityError(BadRequest): + """Raised if something triggers a security error. This is otherwise + exactly like a bad request error. + + .. versionadded:: 0.9 + """ + + +class BadHost(BadRequest): + """Raised if the submitted host is badly formatted. + + .. versionadded:: 0.11.2 + """ + + +class Unauthorized(HTTPException): + """*401* ``Unauthorized`` + + Raise if the user is not authorized to access a resource. + + The ``www_authenticate`` argument should be used to set the + ``WWW-Authenticate`` header. This is used for HTTP basic auth and + other schemes. Use :class:`~werkzeug.datastructures.WWWAuthenticate` + to create correctly formatted values. Strictly speaking a 401 + response is invalid if it doesn't provide at least one value for + this header, although real clients typically don't care. + + :param description: Override the default message used for the body + of the response. + :param www-authenticate: A single value, or list of values, for the + WWW-Authenticate header(s). + + .. versionchanged:: 2.0 + Serialize multiple ``www_authenticate`` items into multiple + ``WWW-Authenticate`` headers, rather than joining them + into a single value, for better interoperability. + + .. versionchanged:: 0.15.3 + If the ``www_authenticate`` argument is not set, the + ``WWW-Authenticate`` header is not set. + + .. versionchanged:: 0.15.3 + The ``response`` argument was restored. + + .. versionchanged:: 0.15.1 + ``description`` was moved back as the first argument, restoring + its previous position. + + .. versionchanged:: 0.15.0 + ``www_authenticate`` was added as the first argument, ahead of + ``description``. + """ + + code = 401 + description = ( + "The server could not verify that you are authorized to access" + " the URL requested. You either supplied the wrong credentials" + " (e.g. a bad password), or your browser doesn't understand" + " how to supply the credentials required." + ) + + def __init__( + self, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + www_authenticate: t.Optional[ + t.Union["WWWAuthenticate", t.Iterable["WWWAuthenticate"]] + ] = None, + ) -> None: + super().__init__(description, response) + + from .datastructures import WWWAuthenticate + + if isinstance(www_authenticate, WWWAuthenticate): + www_authenticate = (www_authenticate,) + + self.www_authenticate = www_authenticate + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + headers = super().get_headers(environ, scope) + if self.www_authenticate: + headers.extend(("WWW-Authenticate", str(x)) for x in self.www_authenticate) + return headers + + +class Forbidden(HTTPException): + """*403* `Forbidden` + + Raise if the user doesn't have the permission for the requested resource + but was authenticated. + """ + + code = 403 + description = ( + "You don't have the permission to access the requested" + " resource. It is either read-protected or not readable by the" + " server." + ) + + +class NotFound(HTTPException): + """*404* `Not Found` + + Raise if a resource does not exist and never existed. + """ + + code = 404 + description = ( + "The requested URL was not found on the server. If you entered" + " the URL manually please check your spelling and try again." + ) + + +class MethodNotAllowed(HTTPException): + """*405* `Method Not Allowed` + + Raise if the server used a method the resource does not handle. For + example `POST` if the resource is view only. Especially useful for REST. + + The first argument for this exception should be a list of allowed methods. + Strictly speaking the response would be invalid if you don't provide valid + methods in the header which you can do with that list. + """ + + code = 405 + description = "The method is not allowed for the requested URL." + + def __init__( + self, + valid_methods: t.Optional[t.Iterable[str]] = None, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + ) -> None: + """Takes an optional list of valid http methods + starting with werkzeug 0.3 the list will be mandatory.""" + super().__init__(description=description, response=response) + self.valid_methods = valid_methods + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + headers = super().get_headers(environ, scope) + if self.valid_methods: + headers.append(("Allow", ", ".join(self.valid_methods))) + return headers + + +class NotAcceptable(HTTPException): + """*406* `Not Acceptable` + + Raise if the server can't return any content conforming to the + `Accept` headers of the client. + """ + + code = 406 + description = ( + "The resource identified by the request is only capable of" + " generating response entities which have content" + " characteristics not acceptable according to the accept" + " headers sent in the request." + ) + + +class RequestTimeout(HTTPException): + """*408* `Request Timeout` + + Raise to signalize a timeout. + """ + + code = 408 + description = ( + "The server closed the network connection because the browser" + " didn't finish the request within the specified time." + ) + + +class Conflict(HTTPException): + """*409* `Conflict` + + Raise to signal that a request cannot be completed because it conflicts + with the current state on the server. + + .. versionadded:: 0.7 + """ + + code = 409 + description = ( + "A conflict happened while processing the request. The" + " resource might have been modified while the request was being" + " processed." + ) + + +class Gone(HTTPException): + """*410* `Gone` + + Raise if a resource existed previously and went away without new location. + """ + + code = 410 + description = ( + "The requested URL is no longer available on this server and" + " there is no forwarding address. If you followed a link from a" + " foreign page, please contact the author of this page." + ) + + +class LengthRequired(HTTPException): + """*411* `Length Required` + + Raise if the browser submitted data but no ``Content-Length`` header which + is required for the kind of processing the server does. + """ + + code = 411 + description = ( + "A request with this method requires a valid Content-" + "Length header." + ) + + +class PreconditionFailed(HTTPException): + """*412* `Precondition Failed` + + Status code used in combination with ``If-Match``, ``If-None-Match``, or + ``If-Unmodified-Since``. + """ + + code = 412 + description = ( + "The precondition on the request for the URL failed positive evaluation." + ) + + +class RequestEntityTooLarge(HTTPException): + """*413* `Request Entity Too Large` + + The status code one should return if the data submitted exceeded a given + limit. + """ + + code = 413 + description = "The data value transmitted exceeds the capacity limit." + + +class RequestURITooLarge(HTTPException): + """*414* `Request URI Too Large` + + Like *413* but for too long URLs. + """ + + code = 414 + description = ( + "The length of the requested URL exceeds the capacity limit for" + " this server. The request cannot be processed." + ) + + +class UnsupportedMediaType(HTTPException): + """*415* `Unsupported Media Type` + + The status code returned if the server is unable to handle the media type + the client transmitted. + """ + + code = 415 + description = ( + "The server does not support the media type transmitted in the request." + ) + + +class RequestedRangeNotSatisfiable(HTTPException): + """*416* `Requested Range Not Satisfiable` + + The client asked for an invalid part of the file. + + .. versionadded:: 0.7 + """ + + code = 416 + description = "The server cannot provide the requested range." + + def __init__( + self, + length: t.Optional[int] = None, + units: str = "bytes", + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + ) -> None: + """Takes an optional `Content-Range` header value based on ``length`` + parameter. + """ + super().__init__(description=description, response=response) + self.length = length + self.units = units + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + headers = super().get_headers(environ, scope) + if self.length is not None: + headers.append(("Content-Range", f"{self.units} */{self.length}")) + return headers + + +class ExpectationFailed(HTTPException): + """*417* `Expectation Failed` + + The server cannot meet the requirements of the Expect request-header. + + .. versionadded:: 0.7 + """ + + code = 417 + description = "The server could not meet the requirements of the Expect header" + + +class ImATeapot(HTTPException): + """*418* `I'm a teapot` + + The server should return this if it is a teapot and someone attempted + to brew coffee with it. + + .. versionadded:: 0.7 + """ + + code = 418 + description = "This server is a teapot, not a coffee machine" + + +class UnprocessableEntity(HTTPException): + """*422* `Unprocessable Entity` + + Used if the request is well formed, but the instructions are otherwise + incorrect. + """ + + code = 422 + description = ( + "The request was well-formed but was unable to be followed due" + " to semantic errors." + ) + + +class Locked(HTTPException): + """*423* `Locked` + + Used if the resource that is being accessed is locked. + """ + + code = 423 + description = "The resource that is being accessed is locked." + + +class FailedDependency(HTTPException): + """*424* `Failed Dependency` + + Used if the method could not be performed on the resource + because the requested action depended on another action and that action failed. + """ + + code = 424 + description = ( + "The method could not be performed on the resource because the" + " requested action depended on another action and that action" + " failed." + ) + + +class PreconditionRequired(HTTPException): + """*428* `Precondition Required` + + The server requires this request to be conditional, typically to prevent + the lost update problem, which is a race condition between two or more + clients attempting to update a resource through PUT or DELETE. By requiring + each client to include a conditional header ("If-Match" or "If-Unmodified- + Since") with the proper value retained from a recent GET request, the + server ensures that each client has at least seen the previous revision of + the resource. + """ + + code = 428 + description = ( + "This request is required to be conditional; try using" + ' "If-Match" or "If-Unmodified-Since".' + ) + + +class _RetryAfter(HTTPException): + """Adds an optional ``retry_after`` parameter which will set the + ``Retry-After`` header. May be an :class:`int` number of seconds or + a :class:`~datetime.datetime`. + """ + + def __init__( + self, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + retry_after: t.Optional[t.Union[datetime, int]] = None, + ) -> None: + super().__init__(description, response) + self.retry_after = retry_after + + def get_headers( + self, + environ: t.Optional["WSGIEnvironment"] = None, + scope: t.Optional[dict] = None, + ) -> t.List[t.Tuple[str, str]]: + headers = super().get_headers(environ, scope) + + if self.retry_after: + if isinstance(self.retry_after, datetime): + from .http import http_date + + value = http_date(self.retry_after) + else: + value = str(self.retry_after) + + headers.append(("Retry-After", value)) + + return headers + + +class TooManyRequests(_RetryAfter): + """*429* `Too Many Requests` + + The server is limiting the rate at which this user receives + responses, and this request exceeds that rate. (The server may use + any convenient method to identify users and their request rates). + The server may include a "Retry-After" header to indicate how long + the user should wait before retrying. + + :param retry_after: If given, set the ``Retry-After`` header to this + value. May be an :class:`int` number of seconds or a + :class:`~datetime.datetime`. + + .. versionchanged:: 1.0 + Added ``retry_after`` parameter. + """ + + code = 429 + description = "This user has exceeded an allotted request count. Try again later." + + +class RequestHeaderFieldsTooLarge(HTTPException): + """*431* `Request Header Fields Too Large` + + The server refuses to process the request because the header fields are too + large. One or more individual fields may be too large, or the set of all + headers is too large. + """ + + code = 431 + description = "One or more header fields exceeds the maximum size." + + +class UnavailableForLegalReasons(HTTPException): + """*451* `Unavailable For Legal Reasons` + + This status code indicates that the server is denying access to the + resource as a consequence of a legal demand. + """ + + code = 451 + description = "Unavailable for legal reasons." + + +class InternalServerError(HTTPException): + """*500* `Internal Server Error` + + Raise if an internal server error occurred. This is a good fallback if an + unknown error occurred in the dispatcher. + + .. versionchanged:: 1.0.0 + Added the :attr:`original_exception` attribute. + """ + + code = 500 + description = ( + "The server encountered an internal error and was unable to" + " complete your request. Either the server is overloaded or" + " there is an error in the application." + ) + + def __init__( + self, + description: t.Optional[str] = None, + response: t.Optional["Response"] = None, + original_exception: t.Optional[BaseException] = None, + ) -> None: + #: The original exception that caused this 500 error. Can be + #: used by frameworks to provide context when handling + #: unexpected errors. + self.original_exception = original_exception + super().__init__(description=description, response=response) + + +class NotImplemented(HTTPException): + """*501* `Not Implemented` + + Raise if the application does not support the action requested by the + browser. + """ + + code = 501 + description = "The server does not support the action requested by the browser." + + +class BadGateway(HTTPException): + """*502* `Bad Gateway` + + If you do proxying in your application you should return this status code + if you received an invalid response from the upstream server it accessed + in attempting to fulfill the request. + """ + + code = 502 + description = ( + "The proxy server received an invalid response from an upstream server." + ) + + +class ServiceUnavailable(_RetryAfter): + """*503* `Service Unavailable` + + Status code you should return if a service is temporarily + unavailable. + + :param retry_after: If given, set the ``Retry-After`` header to this + value. May be an :class:`int` number of seconds or a + :class:`~datetime.datetime`. + + .. versionchanged:: 1.0 + Added ``retry_after`` parameter. + """ + + code = 503 + description = ( + "The server is temporarily unable to service your request due" + " to maintenance downtime or capacity problems. Please try" + " again later." + ) + + +class GatewayTimeout(HTTPException): + """*504* `Gateway Timeout` + + Status code you should return if a connection to an upstream server + times out. + """ + + code = 504 + description = "The connection to an upstream server timed out." + + +class HTTPVersionNotSupported(HTTPException): + """*505* `HTTP Version Not Supported` + + The server does not support the HTTP protocol version used in the request. + """ + + code = 505 + description = ( + "The server does not support the HTTP protocol version used in the request." + ) + + +default_exceptions: t.Dict[int, t.Type[HTTPException]] = {} + + +def _find_exceptions() -> None: + for obj in globals().values(): + try: + is_http_exception = issubclass(obj, HTTPException) + except TypeError: + is_http_exception = False + if not is_http_exception or obj.code is None: + continue + old_obj = default_exceptions.get(obj.code, None) + if old_obj is not None and issubclass(obj, old_obj): + continue + default_exceptions[obj.code] = obj + + +_find_exceptions() +del _find_exceptions + + +class Aborter: + """When passed a dict of code -> exception items it can be used as + callable that raises exceptions. If the first argument to the + callable is an integer it will be looked up in the mapping, if it's + a WSGI application it will be raised in a proxy exception. + + The rest of the arguments are forwarded to the exception constructor. + """ + + def __init__( + self, + mapping: t.Optional[t.Dict[int, t.Type[HTTPException]]] = None, + extra: t.Optional[t.Dict[int, t.Type[HTTPException]]] = None, + ) -> None: + if mapping is None: + mapping = default_exceptions + self.mapping = dict(mapping) + if extra is not None: + self.mapping.update(extra) + + def __call__( + self, code: t.Union[int, "Response"], *args: t.Any, **kwargs: t.Any + ) -> "te.NoReturn": + from .sansio.response import Response + + if isinstance(code, Response): + raise HTTPException(response=code) + + if code not in self.mapping: + raise LookupError(f"no exception for {code!r}") + + raise self.mapping[code](*args, **kwargs) + + +def abort( + status: t.Union[int, "Response"], *args: t.Any, **kwargs: t.Any +) -> "te.NoReturn": + """Raises an :py:exc:`HTTPException` for the given status code or WSGI + application. + + If a status code is given, it will be looked up in the list of + exceptions and will raise that exception. If passed a WSGI application, + it will wrap it in a proxy WSGI exception and raise that:: + + abort(404) # 404 Not Found + abort(Response('Hello World')) + + """ + _aborter(status, *args, **kwargs) + + +_aborter: Aborter = Aborter() diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/formparser.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/formparser.py new file mode 100644 index 0000000..10d58ca --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/formparser.py @@ -0,0 +1,455 @@ +import typing as t +from functools import update_wrapper +from io import BytesIO +from itertools import chain +from typing import Union + +from . import exceptions +from .datastructures import FileStorage +from .datastructures import Headers +from .datastructures import MultiDict +from .http import parse_options_header +from .sansio.multipart import Data +from .sansio.multipart import Epilogue +from .sansio.multipart import Field +from .sansio.multipart import File +from .sansio.multipart import MultipartDecoder +from .sansio.multipart import NeedData +from .urls import url_decode_stream +from .wsgi import _make_chunk_iter +from .wsgi import get_content_length +from .wsgi import get_input_stream + +# there are some platforms where SpooledTemporaryFile is not available. +# In that case we need to provide a fallback. +try: + from tempfile import SpooledTemporaryFile +except ImportError: + from tempfile import TemporaryFile + + SpooledTemporaryFile = None # type: ignore + +if t.TYPE_CHECKING: + import typing as te + from _typeshed.wsgi import WSGIEnvironment + + t_parse_result = t.Tuple[t.IO[bytes], MultiDict, MultiDict] + + class TStreamFactory(te.Protocol): + def __call__( + self, + total_content_length: t.Optional[int], + content_type: t.Optional[str], + filename: t.Optional[str], + content_length: t.Optional[int] = None, + ) -> t.IO[bytes]: + ... + + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def _exhaust(stream: t.IO[bytes]) -> None: + bts = stream.read(64 * 1024) + while bts: + bts = stream.read(64 * 1024) + + +def default_stream_factory( + total_content_length: t.Optional[int], + content_type: t.Optional[str], + filename: t.Optional[str], + content_length: t.Optional[int] = None, +) -> t.IO[bytes]: + max_size = 1024 * 500 + + if SpooledTemporaryFile is not None: + return t.cast(t.IO[bytes], SpooledTemporaryFile(max_size=max_size, mode="rb+")) + elif total_content_length is None or total_content_length > max_size: + return t.cast(t.IO[bytes], TemporaryFile("rb+")) + + return BytesIO() + + +def parse_form_data( + environ: "WSGIEnvironment", + stream_factory: t.Optional["TStreamFactory"] = None, + charset: str = "utf-8", + errors: str = "replace", + max_form_memory_size: t.Optional[int] = None, + max_content_length: t.Optional[int] = None, + cls: t.Optional[t.Type[MultiDict]] = None, + silent: bool = True, +) -> "t_parse_result": + """Parse the form data in the environ and return it as tuple in the form + ``(stream, form, files)``. You should only call this method if the + transport method is `POST`, `PUT`, or `PATCH`. + + If the mimetype of the data transmitted is `multipart/form-data` the + files multidict will be filled with `FileStorage` objects. If the + mimetype is unknown the input stream is wrapped and returned as first + argument, else the stream is empty. + + This is a shortcut for the common usage of :class:`FormDataParser`. + + Have a look at :doc:`/request_data` for more details. + + .. versionadded:: 0.5 + The `max_form_memory_size`, `max_content_length` and + `cls` parameters were added. + + .. versionadded:: 0.5.1 + The optional `silent` flag was added. + + :param environ: the WSGI environment to be used for parsing. + :param stream_factory: An optional callable that returns a new read and + writeable file descriptor. This callable works + the same as :meth:`Response._get_file_stream`. + :param charset: The character set for URL and url encoded form data. + :param errors: The encoding error behavior. + :param max_form_memory_size: the maximum number of bytes to be accepted for + in-memory stored form data. If the data + exceeds the value specified an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param max_content_length: If this is provided and the transmitted data + is longer than this value an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param cls: an optional dict class to use. If this is not specified + or `None` the default :class:`MultiDict` is used. + :param silent: If set to False parsing errors will not be caught. + :return: A tuple in the form ``(stream, form, files)``. + """ + return FormDataParser( + stream_factory, + charset, + errors, + max_form_memory_size, + max_content_length, + cls, + silent, + ).parse_from_environ(environ) + + +def exhaust_stream(f: F) -> F: + """Helper decorator for methods that exhausts the stream on return.""" + + def wrapper(self, stream, *args, **kwargs): # type: ignore + try: + return f(self, stream, *args, **kwargs) + finally: + exhaust = getattr(stream, "exhaust", None) + + if exhaust is not None: + exhaust() + else: + while True: + chunk = stream.read(1024 * 64) + + if not chunk: + break + + return update_wrapper(t.cast(F, wrapper), f) + + +class FormDataParser: + """This class implements parsing of form data for Werkzeug. By itself + it can parse multipart and url encoded form data. It can be subclassed + and extended but for most mimetypes it is a better idea to use the + untouched stream and expose it as separate attributes on a request + object. + + .. versionadded:: 0.8 + + :param stream_factory: An optional callable that returns a new read and + writeable file descriptor. This callable works + the same as :meth:`Response._get_file_stream`. + :param charset: The character set for URL and url encoded form data. + :param errors: The encoding error behavior. + :param max_form_memory_size: the maximum number of bytes to be accepted for + in-memory stored form data. If the data + exceeds the value specified an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param max_content_length: If this is provided and the transmitted data + is longer than this value an + :exc:`~exceptions.RequestEntityTooLarge` + exception is raised. + :param cls: an optional dict class to use. If this is not specified + or `None` the default :class:`MultiDict` is used. + :param silent: If set to False parsing errors will not be caught. + """ + + def __init__( + self, + stream_factory: t.Optional["TStreamFactory"] = None, + charset: str = "utf-8", + errors: str = "replace", + max_form_memory_size: t.Optional[int] = None, + max_content_length: t.Optional[int] = None, + cls: t.Optional[t.Type[MultiDict]] = None, + silent: bool = True, + ) -> None: + if stream_factory is None: + stream_factory = default_stream_factory + + self.stream_factory = stream_factory + self.charset = charset + self.errors = errors + self.max_form_memory_size = max_form_memory_size + self.max_content_length = max_content_length + + if cls is None: + cls = MultiDict + + self.cls = cls + self.silent = silent + + def get_parse_func( + self, mimetype: str, options: t.Dict[str, str] + ) -> t.Optional[ + t.Callable[ + ["FormDataParser", t.IO[bytes], str, t.Optional[int], t.Dict[str, str]], + "t_parse_result", + ] + ]: + return self.parse_functions.get(mimetype) + + def parse_from_environ(self, environ: "WSGIEnvironment") -> "t_parse_result": + """Parses the information from the environment as form data. + + :param environ: the WSGI environment to be used for parsing. + :return: A tuple in the form ``(stream, form, files)``. + """ + content_type = environ.get("CONTENT_TYPE", "") + content_length = get_content_length(environ) + mimetype, options = parse_options_header(content_type) + return self.parse(get_input_stream(environ), mimetype, content_length, options) + + def parse( + self, + stream: t.IO[bytes], + mimetype: str, + content_length: t.Optional[int], + options: t.Optional[t.Dict[str, str]] = None, + ) -> "t_parse_result": + """Parses the information from the given stream, mimetype, + content length and mimetype parameters. + + :param stream: an input stream + :param mimetype: the mimetype of the data + :param content_length: the content length of the incoming data + :param options: optional mimetype parameters (used for + the multipart boundary for instance) + :return: A tuple in the form ``(stream, form, files)``. + """ + if ( + self.max_content_length is not None + and content_length is not None + and content_length > self.max_content_length + ): + # if the input stream is not exhausted, firefox reports Connection Reset + _exhaust(stream) + raise exceptions.RequestEntityTooLarge() + + if options is None: + options = {} + + parse_func = self.get_parse_func(mimetype, options) + + if parse_func is not None: + try: + return parse_func(self, stream, mimetype, content_length, options) + except ValueError: + if not self.silent: + raise + + return stream, self.cls(), self.cls() + + @exhaust_stream + def _parse_multipart( + self, + stream: t.IO[bytes], + mimetype: str, + content_length: t.Optional[int], + options: t.Dict[str, str], + ) -> "t_parse_result": + parser = MultiPartParser( + self.stream_factory, + self.charset, + self.errors, + max_form_memory_size=self.max_form_memory_size, + cls=self.cls, + ) + boundary = options.get("boundary", "").encode("ascii") + + if not boundary: + raise ValueError("Missing boundary") + + form, files = parser.parse(stream, boundary, content_length) + return stream, form, files + + @exhaust_stream + def _parse_urlencoded( + self, + stream: t.IO[bytes], + mimetype: str, + content_length: t.Optional[int], + options: t.Dict[str, str], + ) -> "t_parse_result": + if ( + self.max_form_memory_size is not None + and content_length is not None + and content_length > self.max_form_memory_size + ): + # if the input stream is not exhausted, firefox reports Connection Reset + _exhaust(stream) + raise exceptions.RequestEntityTooLarge() + + form = url_decode_stream(stream, self.charset, errors=self.errors, cls=self.cls) + return stream, form, self.cls() + + #: mapping of mimetypes to parsing functions + parse_functions: t.Dict[ + str, + t.Callable[ + ["FormDataParser", t.IO[bytes], str, t.Optional[int], t.Dict[str, str]], + "t_parse_result", + ], + ] = { + "multipart/form-data": _parse_multipart, + "application/x-www-form-urlencoded": _parse_urlencoded, + "application/x-url-encoded": _parse_urlencoded, + } + + +def _line_parse(line: str) -> t.Tuple[str, bool]: + """Removes line ending characters and returns a tuple (`stripped_line`, + `is_terminated`). + """ + if line[-2:] == "\r\n": + return line[:-2], True + + elif line[-1:] in {"\r", "\n"}: + return line[:-1], True + + return line, False + + +class MultiPartParser: + def __init__( + self, + stream_factory: t.Optional["TStreamFactory"] = None, + charset: str = "utf-8", + errors: str = "replace", + max_form_memory_size: t.Optional[int] = None, + cls: t.Optional[t.Type[MultiDict]] = None, + buffer_size: int = 64 * 1024, + ) -> None: + self.charset = charset + self.errors = errors + self.max_form_memory_size = max_form_memory_size + + if stream_factory is None: + stream_factory = default_stream_factory + + self.stream_factory = stream_factory + + if cls is None: + cls = MultiDict + + self.cls = cls + + self.buffer_size = buffer_size + + def fail(self, message: str) -> "te.NoReturn": + raise ValueError(message) + + def get_part_charset(self, headers: Headers) -> str: + # Figure out input charset for current part + content_type = headers.get("content-type") + + if content_type: + mimetype, ct_params = parse_options_header(content_type) + return ct_params.get("charset", self.charset) + + return self.charset + + def start_file_streaming( + self, event: File, total_content_length: t.Optional[int] + ) -> t.IO[bytes]: + content_type = event.headers.get("content-type") + + try: + content_length = int(event.headers["content-length"]) + except (KeyError, ValueError): + content_length = 0 + + container = self.stream_factory( + total_content_length=total_content_length, + filename=event.filename, + content_type=content_type, + content_length=content_length, + ) + return container + + def parse( + self, stream: t.IO[bytes], boundary: bytes, content_length: t.Optional[int] + ) -> t.Tuple[MultiDict, MultiDict]: + container: t.Union[t.IO[bytes], t.List[bytes]] + _write: t.Callable[[bytes], t.Any] + + iterator = chain( + _make_chunk_iter( + stream, + limit=content_length, + buffer_size=self.buffer_size, + ), + [None], + ) + + parser = MultipartDecoder(boundary, self.max_form_memory_size) + + fields = [] + files = [] + + current_part: Union[Field, File] + for data in iterator: + parser.receive_data(data) + event = parser.next_event() + while not isinstance(event, (Epilogue, NeedData)): + if isinstance(event, Field): + current_part = event + container = [] + _write = container.append + elif isinstance(event, File): + current_part = event + container = self.start_file_streaming(event, content_length) + _write = container.write + elif isinstance(event, Data): + _write(event.data) + if not event.more_data: + if isinstance(current_part, Field): + value = b"".join(container).decode( + self.get_part_charset(current_part.headers), self.errors + ) + fields.append((current_part.name, value)) + else: + container = t.cast(t.IO[bytes], container) + container.seek(0) + files.append( + ( + current_part.name, + FileStorage( + container, + current_part.filename, + current_part.name, + headers=current_part.headers, + ), + ) + ) + + event = parser.next_event() + + return self.cls(fields), self.cls(files) diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/http.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/http.py new file mode 100644 index 0000000..9369900 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/http.py @@ -0,0 +1,1371 @@ +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 + + +def parse_options_header( + value: t.Optional[str], multiple: "te.Literal[None]" = None +) -> t.Tuple[str, t.Dict[str, str]]: + """Parse a ``Content-Type``-like header into a tuple with the + value and any options: + + >>> parse_options_header('text/html; charset=utf8') + ('text/html', {'charset': 'utf8'}) + + This should is not for ``Cache-Control``-like headers, which use a + different format. For those, use :func:`parse_dict_header`. + + :param value: The header value to parse. + + .. versionchanged:: 2.1 + The ``multiple`` parameter is deprecated and will be removed in + Werkzeug 2.2. + + .. versionchanged:: 0.15 + :rfc:`2231` parameter continuations are handled. + + .. versionadded:: 0.5 + """ + if multiple is not None: + import warnings + + warnings.warn( + "The 'multiple' parameter of 'parse_options_header' is" + " deprecated and will be removed in Werkzeug 2.2.", + DeprecationWarning, + stacklevel=2, + ) + + 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. + if option_value is not None: + options[option] = options.get(option, "") + option_value + else: + options[option] = option_value # type: ignore[assignment] + + rest = rest[optmatch.end() :] + result.append(options) + if not multiple: + return tuple(result) # type: ignore[return-value] + value = rest + + return tuple(result) if result else ("", {}) # type: ignore[return-value] + + +_TAnyAccept = t.TypeVar("_TAnyAccept", bound="ds.Accept") + + +@typing.overload +def parse_accept_header(value: t.Optional[str]) -> "ds.Accept": + ... + + +@typing.overload +def parse_accept_header( + value: t.Optional[str], cls: t.Type[_TAnyAccept] +) -> _TAnyAccept: + ... + + +def parse_accept_header( + value: t.Optional[str], cls: t.Optional[t.Type[_TAnyAccept]] = None +) -> _TAnyAccept: + """Parses an HTTP Accept-* header. This does not implement a complete + valid algorithm but one that supports at least value and quality + extraction. + + Returns a new :class:`Accept` object (basically a list of ``(value, quality)`` + tuples sorted by the quality with some additional accessor methods). + + The second parameter can be a subclass of :class:`Accept` that is created + with the parsed values and returned. + + :param value: the accept header string to be parsed. + :param cls: the wrapper class for the return value (can be + :class:`Accept` or a subclass thereof) + :return: an instance of `cls`. + """ + if cls is None: + cls = t.cast(t.Type[_TAnyAccept], ds.Accept) + + if not value: + return cls(None) + + result = [] + for match in _accept_re.finditer(value): + quality_match = match.group(2) + if not quality_match: + quality: float = 1 + else: + quality = max(min(float(quality_match), 1), 0) + result.append((match.group(1), quality)) + return cls(result) + + +_TAnyCC = t.TypeVar("_TAnyCC", bound="ds._CacheControl") +_t_cc_update = t.Optional[t.Callable[[_TAnyCC], None]] + + +@typing.overload +def parse_cache_control_header( + value: t.Optional[str], on_update: _t_cc_update, cls: None = None +) -> "ds.RequestCacheControl": + ... + + +@typing.overload +def parse_cache_control_header( + value: t.Optional[str], on_update: _t_cc_update, cls: t.Type[_TAnyCC] +) -> _TAnyCC: + ... + + +def parse_cache_control_header( + value: t.Optional[str], + on_update: _t_cc_update = None, + cls: t.Optional[t.Type[_TAnyCC]] = None, +) -> _TAnyCC: + """Parse a cache control header. The RFC differs between response and + request cache control, this method does not. It's your responsibility + to not use the wrong control statements. + + .. versionadded:: 0.5 + The `cls` was added. If not specified an immutable + :class:`~werkzeug.datastructures.RequestCacheControl` is returned. + + :param value: a cache control header to be parsed. + :param on_update: an optional callable that is called every time a value + on the :class:`~werkzeug.datastructures.CacheControl` + object is changed. + :param cls: the class for the returned object. By default + :class:`~werkzeug.datastructures.RequestCacheControl` is used. + :return: a `cls` object. + """ + if cls is None: + cls = t.cast(t.Type[_TAnyCC], ds.RequestCacheControl) + + if not value: + return cls((), on_update) + + return cls(parse_dict_header(value), on_update) + + +_TAnyCSP = t.TypeVar("_TAnyCSP", bound="ds.ContentSecurityPolicy") +_t_csp_update = t.Optional[t.Callable[[_TAnyCSP], None]] + + +@typing.overload +def parse_csp_header( + value: t.Optional[str], on_update: _t_csp_update, cls: None = None +) -> "ds.ContentSecurityPolicy": + ... + + +@typing.overload +def parse_csp_header( + value: t.Optional[str], on_update: _t_csp_update, cls: t.Type[_TAnyCSP] +) -> _TAnyCSP: + ... + + +def parse_csp_header( + value: t.Optional[str], + on_update: _t_csp_update = None, + cls: t.Optional[t.Type[_TAnyCSP]] = None, +) -> _TAnyCSP: + """Parse a Content Security Policy header. + + .. versionadded:: 1.0.0 + Support for Content Security Policy headers was added. + + :param value: a csp header to be parsed. + :param on_update: an optional callable that is called every time a value + on the object is changed. + :param cls: the class for the returned object. By default + :class:`~werkzeug.datastructures.ContentSecurityPolicy` is used. + :return: a `cls` object. + """ + if cls is None: + cls = t.cast(t.Type[_TAnyCSP], ds.ContentSecurityPolicy) + + if value is None: + return cls((), on_update) + + items = [] + + for policy in value.split(";"): + policy = policy.strip() + + # Ignore badly formatted policies (no space) + if " " in policy: + directive, value = policy.strip().split(" ", 1) + items.append((directive.strip(), value.strip())) + + return cls(items, on_update) + + +def parse_set_header( + value: t.Optional[str], + on_update: t.Optional[t.Callable[["ds.HeaderSet"], None]] = None, +) -> "ds.HeaderSet": + """Parse a set-like header and return a + :class:`~werkzeug.datastructures.HeaderSet` object: + + >>> hs = parse_set_header('token, "quoted value"') + + The return value is an object that treats the items case-insensitively + and keeps the order of the items: + + >>> 'TOKEN' in hs + True + >>> hs.index('quoted value') + 1 + >>> hs + HeaderSet(['token', 'quoted value']) + + To create a header from the :class:`HeaderSet` again, use the + :func:`dump_header` function. + + :param value: a set header to be parsed. + :param on_update: an optional callable that is called every time a + value on the :class:`~werkzeug.datastructures.HeaderSet` + object is changed. + :return: a :class:`~werkzeug.datastructures.HeaderSet` + """ + if not value: + return ds.HeaderSet(None, on_update) + return ds.HeaderSet(parse_list_header(value), on_update) + + +def parse_authorization_header( + value: t.Optional[str], +) -> t.Optional["ds.Authorization"]: + """Parse an HTTP basic/digest authorization header transmitted by the web + browser. The return value is either `None` if the header was invalid or + not given, otherwise an :class:`~werkzeug.datastructures.Authorization` + object. + + :param value: the authorization header to parse. + :return: a :class:`~werkzeug.datastructures.Authorization` object or `None`. + """ + if not value: + return None + value = _wsgi_decoding_dance(value) + try: + auth_type, auth_info = value.split(None, 1) + auth_type = auth_type.lower() + except ValueError: + return None + if auth_type == "basic": + try: + username, password = base64.b64decode(auth_info).split(b":", 1) + except Exception: + return None + try: + return ds.Authorization( + "basic", + { + "username": _to_str(username, "utf-8"), + "password": _to_str(password, "utf-8"), + }, + ) + except UnicodeDecodeError: + return None + elif auth_type == "digest": + auth_map = parse_dict_header(auth_info) + for key in "username", "realm", "nonce", "uri", "response": + if key not in auth_map: + return None + if "qop" in auth_map: + if not auth_map.get("nc") or not auth_map.get("cnonce"): + return None + return ds.Authorization("digest", auth_map) + return None + + +def parse_www_authenticate_header( + value: t.Optional[str], + on_update: t.Optional[t.Callable[["ds.WWWAuthenticate"], None]] = None, +) -> "ds.WWWAuthenticate": + """Parse an HTTP WWW-Authenticate header into a + :class:`~werkzeug.datastructures.WWWAuthenticate` object. + + :param value: a WWW-Authenticate header to parse. + :param on_update: an optional callable that is called every time a value + on the :class:`~werkzeug.datastructures.WWWAuthenticate` + object is changed. + :return: a :class:`~werkzeug.datastructures.WWWAuthenticate` object. + """ + if not value: + return ds.WWWAuthenticate(on_update=on_update) + try: + auth_type, auth_info = value.split(None, 1) + auth_type = auth_type.lower() + except (ValueError, AttributeError): + return ds.WWWAuthenticate(value.strip().lower(), on_update=on_update) + return ds.WWWAuthenticate(auth_type, parse_dict_header(auth_info), on_update) + + +def parse_if_range_header(value: t.Optional[str]) -> "ds.IfRange": + """Parses an if-range header which can be an etag or a date. Returns + a :class:`~werkzeug.datastructures.IfRange` object. + + .. versionchanged:: 2.0 + If the value represents a datetime, it is timezone-aware. + + .. versionadded:: 0.7 + """ + if not value: + return ds.IfRange() + date = parse_date(value) + if date is not None: + return ds.IfRange(date=date) + # drop weakness information + return ds.IfRange(unquote_etag(value)[0]) + + +def parse_range_header( + value: t.Optional[str], make_inclusive: bool = True +) -> t.Optional["ds.Range"]: + """Parses a range header into a :class:`~werkzeug.datastructures.Range` + object. If the header is missing or malformed `None` is returned. + `ranges` is a list of ``(start, stop)`` tuples where the ranges are + non-inclusive. + + .. versionadded:: 0.7 + """ + if not value or "=" not in value: + return None + + ranges = [] + last_end = 0 + units, rng = value.split("=", 1) + units = units.strip().lower() + + for item in rng.split(","): + item = item.strip() + if "-" not in item: + return None + if item.startswith("-"): + if last_end < 0: + return None + try: + begin = int(item) + except ValueError: + return None + end = None + last_end = -1 + elif "-" in item: + begin_str, end_str = item.split("-", 1) + begin_str = begin_str.strip() + end_str = end_str.strip() + 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 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/zhdo.space/lib/python3.9/site-packages/werkzeug/local.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/local.py new file mode 100644 index 0000000..e297f38 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/local.py @@ -0,0 +1,532 @@ +import copy +import math +import operator +import typing as t +from contextvars import ContextVar +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]) + + +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")) + + 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) from None + + 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) from None + + +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__() + + 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 + + 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 by 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 + ) -> None: + if locals is None: + self.locals = [] + elif isinstance(locals, Local): + self.locals = [locals] + else: + self.locals = list(locals) + + 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: Return this function if the proxy is unbound + instead of raising a :exc:`RuntimeError`. + :param is_attr: This proxied name is an attribute, not a function. + Call the fallback immediately to get the value. + :param class_value: Value to return when accessed from the + ``LocalProxy`` class directly. Used for ``__doc__`` so building + docs still works. + """ + + __slots__ = ("bind_f", "fallback", "is_attr", "class_value", "name") + + def __init__( + self, + f: t.Optional[t.Callable] = None, + fallback: t.Optional[t.Callable] = None, + class_value: t.Optional[t.Any] = None, + is_attr: bool = False, + ) -> None: + bind_f: t.Optional[t.Callable[["LocalProxy", t.Any], t.Callable]] + + if hasattr(f, "__get__"): + # A Python function, can be turned into a bound method. + + def bind_f(instance: "LocalProxy", obj: t.Any) -> t.Callable: + return f.__get__(obj, type(obj)) # type: ignore + + elif f is not None: + # A C function, use partial to bind the first argument. + + def bind_f(instance: "LocalProxy", obj: t.Any) -> t.Callable: + return partial(f, obj) # type: ignore + + else: + # Use getattr, which will produce a bound method. + bind_f = None + + self.bind_f = bind_f + self.fallback = fallback + self.class_value = class_value + self.is_attr = is_attr + + def __set_name__(self, owner: "LocalProxy", name: str) -> None: + self.name = name + + def __get__(self, instance: "LocalProxy", owner: t.Optional[type] = None) -> t.Any: + if instance is None: + if self.class_value is not None: + return self.class_value + + return self + + try: + obj = instance._get_current_object() + except RuntimeError: + if self.fallback is None: + raise + + fallback = self.fallback.__get__(instance, owner) + + if self.is_attr: + # __class__ and __doc__ are attributes, not methods. + # Call the fallback to get the value. + return fallback() + + return fallback + + if self.bind_f is not None: + return self.bind_f(instance, obj) + + return getattr(obj, self.name) + + def __repr__(self) -> str: + return f"proxy {self.name}" + + def __call__(self, instance: "LocalProxy", *args: t.Any, **kwargs: t.Any) -> t.Any: + """Support calling unbound methods from the class. For example, + this happens with ``copy.copy``, which does + ``type(x).__copy__(x)``. ``type(x)`` can't be proxied, so it + returns the proxy type and descriptor. + """ + return self.__get__(instance, type(instance))(*args, **kwargs) + + +class _ProxyIOp(_ProxyLookup): + """Look up an augmented assignment method on a proxied object. The + method is wrapped to return the proxy instead of the object. + """ + + __slots__ = () + + def __init__( + self, f: t.Optional[t.Callable] = None, fallback: t.Optional[t.Callable] = None + ) -> None: + super().__init__(f, fallback) + + def bind_f(instance: "LocalProxy", obj: t.Any) -> t.Callable: + def i_op(self: t.Any, other: t.Any) -> "LocalProxy": + f(self, other) # type: ignore + return instance + + return i_op.__get__(obj, type(obj)) # type: ignore + + self.bind_f = bind_f + + +def _l_to_r_op(op: F) -> F: + """Swap the argument order to turn an l-op into an r-op.""" + + def r_op(obj: t.Any, other: t.Any) -> t.Any: + return op(other, obj) + + return t.cast(F, r_op) + + +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: + name = self.__name # type: ignore + raise RuntimeError(f"no object bound to {name}") from None + + __doc__ = _ProxyLookup( # type: ignore + class_value=__doc__, fallback=lambda self: type(self).__doc__, is_attr=True + ) + # __del__ should only delete the proxy + __repr__ = _ProxyLookup( # type: ignore + repr, fallback=lambda self: f"<{type(self).__name__} unbound>" + ) + __str__ = _ProxyLookup(str) # type: ignore + __bytes__ = _ProxyLookup(bytes) + __format__ = _ProxyLookup() # type: ignore + __lt__ = _ProxyLookup(operator.lt) + __le__ = _ProxyLookup(operator.le) + __eq__ = _ProxyLookup(operator.eq) # type: ignore + __ne__ = _ProxyLookup(operator.ne) # type: ignore + __gt__ = _ProxyLookup(operator.gt) + __ge__ = _ProxyLookup(operator.ge) + __hash__ = _ProxyLookup(hash) # type: ignore + __bool__ = _ProxyLookup(bool, fallback=lambda self: False) + __getattr__ = _ProxyLookup(getattr) + # __getattribute__ triggered through __getattr__ + __setattr__ = _ProxyLookup(setattr) # type: ignore + __delattr__ = _ProxyLookup(delattr) # type: ignore + __dir__ = _ProxyLookup(dir, fallback=lambda self: []) # type: ignore + # __get__ (proxying descriptor not supported) + # __set__ (descriptor) + # __delete__ (descriptor) + # __set_name__ (descriptor) + # __objclass__ (descriptor) + # __slots__ used by proxy itself + # __dict__ (__getattr__) + # __weakref__ (__getattr__) + # __init_subclass__ (proxying metaclass not supported) + # __prepare__ (metaclass) + __class__ = _ProxyLookup( + fallback=lambda self: type(self), is_attr=True + ) # type: ignore + __instancecheck__ = _ProxyLookup(lambda self, other: isinstance(other, self)) + __subclasscheck__ = _ProxyLookup(lambda self, other: issubclass(other, self)) + # __class_getitem__ triggered through __getitem__ + __call__ = _ProxyLookup(lambda self, *args, **kwargs: self(*args, **kwargs)) + __len__ = _ProxyLookup(len) + __length_hint__ = _ProxyLookup(operator.length_hint) + __getitem__ = _ProxyLookup(operator.getitem) + __setitem__ = _ProxyLookup(operator.setitem) + __delitem__ = _ProxyLookup(operator.delitem) + # __missing__ triggered through __getitem__ + __iter__ = _ProxyLookup(iter) + __next__ = _ProxyLookup(next) + __reversed__ = _ProxyLookup(reversed) + __contains__ = _ProxyLookup(operator.contains) + __add__ = _ProxyLookup(operator.add) + __sub__ = _ProxyLookup(operator.sub) + __mul__ = _ProxyLookup(operator.mul) + __matmul__ = _ProxyLookup(operator.matmul) + __truediv__ = _ProxyLookup(operator.truediv) + __floordiv__ = _ProxyLookup(operator.floordiv) + __mod__ = _ProxyLookup(operator.mod) + __divmod__ = _ProxyLookup(divmod) + __pow__ = _ProxyLookup(pow) + __lshift__ = _ProxyLookup(operator.lshift) + __rshift__ = _ProxyLookup(operator.rshift) + __and__ = _ProxyLookup(operator.and_) + __xor__ = _ProxyLookup(operator.xor) + __or__ = _ProxyLookup(operator.or_) + __radd__ = _ProxyLookup(_l_to_r_op(operator.add)) + __rsub__ = _ProxyLookup(_l_to_r_op(operator.sub)) + __rmul__ = _ProxyLookup(_l_to_r_op(operator.mul)) + __rmatmul__ = _ProxyLookup(_l_to_r_op(operator.matmul)) + __rtruediv__ = _ProxyLookup(_l_to_r_op(operator.truediv)) + __rfloordiv__ = _ProxyLookup(_l_to_r_op(operator.floordiv)) + __rmod__ = _ProxyLookup(_l_to_r_op(operator.mod)) + __rdivmod__ = _ProxyLookup(_l_to_r_op(divmod)) + __rpow__ = _ProxyLookup(_l_to_r_op(pow)) + __rlshift__ = _ProxyLookup(_l_to_r_op(operator.lshift)) + __rrshift__ = _ProxyLookup(_l_to_r_op(operator.rshift)) + __rand__ = _ProxyLookup(_l_to_r_op(operator.and_)) + __rxor__ = _ProxyLookup(_l_to_r_op(operator.xor)) + __ror__ = _ProxyLookup(_l_to_r_op(operator.or_)) + __iadd__ = _ProxyIOp(operator.iadd) + __isub__ = _ProxyIOp(operator.isub) + __imul__ = _ProxyIOp(operator.imul) + __imatmul__ = _ProxyIOp(operator.imatmul) + __itruediv__ = _ProxyIOp(operator.itruediv) + __ifloordiv__ = _ProxyIOp(operator.ifloordiv) + __imod__ = _ProxyIOp(operator.imod) + __ipow__ = _ProxyIOp(operator.ipow) + __ilshift__ = _ProxyIOp(operator.ilshift) + __irshift__ = _ProxyIOp(operator.irshift) + __iand__ = _ProxyIOp(operator.iand) + __ixor__ = _ProxyIOp(operator.ixor) + __ior__ = _ProxyIOp(operator.ior) + __neg__ = _ProxyLookup(operator.neg) + __pos__ = _ProxyLookup(operator.pos) + __abs__ = _ProxyLookup(abs) + __invert__ = _ProxyLookup(operator.invert) + __complex__ = _ProxyLookup(complex) + __int__ = _ProxyLookup(int) + __float__ = _ProxyLookup(float) + __index__ = _ProxyLookup(operator.index) + __round__ = _ProxyLookup(round) + __trunc__ = _ProxyLookup(math.trunc) + __floor__ = _ProxyLookup(math.floor) + __ceil__ = _ProxyLookup(math.ceil) + __enter__ = _ProxyLookup() + __exit__ = _ProxyLookup() + __await__ = _ProxyLookup() + __aiter__ = _ProxyLookup() + __anext__ = _ProxyLookup() + __aenter__ = _ProxyLookup() + __aexit__ = _ProxyLookup() + __copy__ = _ProxyLookup(copy.copy) + __deepcopy__ = _ProxyLookup(copy.deepcopy) + # __getnewargs_ex__ (pickle through proxy not supported) + # __getnewargs__ (pickle) + # __getstate__ (pickle) + # __setstate__ (pickle) + # __reduce__ (pickle) + # __reduce_ex__ (pickle) diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__init__.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__init__.py new file mode 100644 index 0000000..6ddcf7f --- /dev/null +++ b/zhdo.space/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/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82be5c8028372e3bd321885de4625ade7e05a693 GIT binary patch literal 696 zcmYjPJ&)8d5Y1l0$Cj1#2vHFoE2t0!G>5bjjdv2y#%3McvYq|7g8xIs|GAd> zDyXQKcu&WUWNYRIf~e4!@?AG(=f2uo2I18burB*&(596D4zA`L`NsHNWqA1LTisN z0BzQO8Z^5zx94MEubG)8E5IrHk*z;Ldy}D_^rIJ)Ni4bWJ$&c0qgRuq<@_3d^Q!&<0#o44 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3719a819202c30c63c85143bd031887457ada4ac GIT binary patch literal 2755 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 F{2xjX0s8;| literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..da94e91fbadcfa7485cc39aac8f1294763d14800 GIT binary patch literal 4948 zcmb_g-EZ606(=d`!?fg&Bwdqr*zVQ=t+1H()_p}wi)4wL8bckgb`ey-Mp3+179EOI zFR$##k@u1SaR+qUd(**w?9={_{Rw>C)1LRT6~ngQxs+r%ae+RJ1dlH7$GPX@cg{VO zU#mF=uD`tTyY}ms4dZY0GJ93is1M12O{u?jmw)=rd)L@a`bDGOsZOa_t#2^WsutLI~eU}=;b zgz+xp$-#Jvf2Nk}IIhe5fl7kNPt!(Ys^|Mt$sMN=B>kZbce|>=ezdmsGq&YNkx;4A zfO$lmiU#}T_T81YR_;XpAQjHv;a_93Zf3=8<*O8p@>nG_Yv_~e1CjO6_KQC)I6q^g&;q!Xk;x&U;pBH$IFFduIOWX!T7PCuZ zo#dIR{L5v-cp&{gTu)lD8B;Sq<`e&uvzd4#f`P_X($RQu7_KoUTsE-~U8SdrnM{>#_q=5r^3C2}UshOb3HhCB5(v%-TcN2XYDFt=43o*GXj0SFIL_ ztOW@bnZai;3Z`C%l8Cw}B4+tq1zrQqrqL6s+aU9~V>UWKH5>9E_f{j)Xz+$2n%lm)9?yc`!XIuBTL4^uj&40YK@2l?13#peS zlD#35M7_b%ZZe3tHeH-3_&-eHe{%nri-`PwDrO`YcQ9Z_Fo2GV#P*=`9b5R!ii8-D+tjJPeeMjj=vbsDX^(s);klm~Qla>Gvq2 z8rqyM#TQ_8fY8fLFrJ;qK!ZI1ya7K#eGWf>As=(u-7qD|b1_@3O<)ng(XvgrBvN_p zVT0XfYS712*e*z-K`++aQVfrIw}&p<7D6v3gO0H@8*eU6_p~VIcab;>B#eR6COx;+ z>;Op*!%%4E+I*cI`@sB#Th4@XgKZ-?rwM8%aCNxCUejrzZ2 zf?npyD3;UfQ!8PPkI>E$1Vj=5XtA#+YKsEi{m75=v)FGZ`(g|W9A9+gt+b;gc!=|> zKSb2Uc_5MpIx^|810f$CiovdXb{@N9-6acqeRAN-*?cM=Fvs4$V8WXisOMWjjC~f_R)Ed3Qm%1U*0IzcX4P3qviTWbmt9e|!<=$9LkqTEZ<)ObT($z_5te%C&>R3qW_J`2L3*%6E z-uu`!C2@?ok~z5#U)vhj#b-s3J6R!1B&ZEiFJ$F$*3TA@w~zo~7hM3#C5#6JkjX`Q z(@N?~@1hRhH9oQUm1ov7yQ4o9p3Z%O&j((3Zay=fndmQcY^wL3R*wqGcw!vc$~-Yo zjichoKCwoHQxgS$>7;OMotj6bd~8&_Y8;i13wt&<2B!S0DxzI_V#>qg!b$1a#LPYFmd4f-cQ}bkw&vEC}>i?O~kIKAy#mKqx+NbtWMLB!(*bTf#l~e1e z0x7C!K??NMXum(1@*TA>vi1AIr`FNjXl`#2Z%co`$BbI$)UNTRPc5u5PcES%T?Quy zBbP?bXV&M|**I2S#@m(2%Fhgb`P_JE*F?Sg%H}yElX1y2_)as@OCZMpJV0+fDPT)u z573s&=tePK0=7lW;X{O-uLfyW?h2nH+hrB;C;&V<2?D$}@u=5M_)vZei*ux2Lo0g~ zpHV>fi`os0@9q;}1o%inFZO(1o-g(d4*nIc? zm*#3_x|vNC@zDhay-=)%$=~z{B0ntRy6?&|%$kI9Y`ZDEss>nPqb38Bq69et4=Y2fz zqwz@D^LP@VyO0i3$^<+aDEWQT)Y`a@UL~{22Ea~^$%-GwD21{DjF=TWQR1tta=%Zd ztslv6(xPH}s6;Anqn!uB^i-3iy`-r94xW^@sF?PeZCd&LFUzuEfC`kWP|rWB%eGnh zk6ux~EY~qVD<`Q-=9V|`Cf_AOSk6jn*hdo5ayLtPS)Rk8GWpj3ezmcAuesoXl}NjSy9eoRs1t;)QSwud#J@>6Qu4N4 TBW38WLa`-y>=Ha$rMvJyO=yrr literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0594c4543de9300e8bb73c33c296d2660076f752 GIT binary patch literal 6172 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 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0724122e53eff7dcf51c9f6bfe15418f0a219df8 GIT binary patch literal 9105 zcmbVR-ESLLcAqbjBZ`z{S@B0cXY*w}VHQxrhUF7mKz}n*@-HKGaVI3KV@QioSLKhIuN`r#u(k2N!Gicg_qyWZB!a zBhBT#ckY~f?m55naqrmWa#6wc_ve1H_2x^8@*mWgzVc{X!X4IBMRAn6;;4@1sdbfq zwYtW?dR^yVqi*nTuAaxQ?iG54dO@Xk4AjlK$@QE!(<|1CT+e&6z1jLK*9%^$SFV>) zH=P-8t~Xzw=Xw$Kh57>5XT1}>#rh)GOWw)eQhkZ*W$%gJsro6d&!K+0ep*#Te)~*^ z%Coqi6i=O1L_s{=*3T+!?W|INhMwboRy=oB>8RN_ZgKB3={O#1q31ilRONZBW!`(f z_d@*z%%wUDsJ~c$k?SW=f2sbGs(h$8i_XbgigWTntH11M8%kwq__xIkA#Vt4qiajy zSR0WYxh?Ah*Arp!?Z;ikVzp}7gD7Zub{N)b+1u~ik^QmjIG)%Av7&{m))T!gA;X&G zh7H^Ef?eShi?vqJ-;-{q8`Z2=FJ64Zx`sz03X3(*Z3#aVHS4{N_m^K=UiIujD2m^Z z?$;}7VmfvtBDW`~PQSyzr+VSNy-0*>S5Y;x#|0aF$k$%|M#H=4pXo+Xzd`S#u>@|U z2!nxaiAFDQ+_ozm8Wh@X(bx`LAB}~Mh#IZHkAxpJqP;%7Sf;+d9d#S7-wx=FU1|3l zZODtBLVPm%kqG+%7J-iWPc}YWd$-@mvLM%hsB+h3|As3AzX!@KTHEwhLgNzd@HZ%g z0!%A}XJGj`Cohcc9PT_2Lp3T*lm$Y==tkd6*8kWs>1an2MKLQ1j^-4;DiFSJ}umG-uW+-7@NBwCA{8cIMEYM|*+W^Uea=Cun~3ocKy-d>QpcZZCnt6V54&I4PEB z7R+<{E5kYCoJHRg&Xdkl%;~AKit{wyea3kf{ihk1R|`e{6h=RL$}xWgcXu0pe3R~Kdf47 zQD_Z9yCVQz>-xZrFoFlxYDFeP2uDXCBP$5UJ#88EtX&~@hGNjEPWY^bY-5B$d-U3) zRym<<_xsk{k2J3Hcyz(~v+7fuwcL&)jVY~pkQVKr6XTH9*&cRFJy7dA=E69w%BgNaxo z0p4g0Q+$Ij7AkW_?k%(!*L}OSLl!~noHm31GgR3~0oC*8dV5nVKS!WUpFIkcSOg;u z-1;el%y_ezz5_sJigZ)mHjfZ*@@lT_MO~;qTS+FcO)Nj?laIDNtLeBQ2dgGVN!UyT z*b|Bfvc>I&8u91#G*OgBFOg3;>-V5HS0`{)WA<_N8VY6#Dktz>l|C0gFz z!zy(GD3PWQ2YvQge&8>^yRo{q#ypa5Ag9Nu;yH!iLTJQHnW4~1tZ*-kM9=C%XNc5< zUtT>=HhCe1=8u20X1Ngt>@mIFK<-#u1FVV6z7-5SXJnVw)*eX({u}GCKEX5*;$sJk z2nU@GECn`5oG`mgEb#G=Ibz1i(8w=P_QDdM((4qg89W`B9yn*fL$`?R8FlK)(9!H6 zyP!v@I*}tlp{au0=p5pL&yEhuZ@ZlVG!XE*;56anNpDy;Pu3>G--6XJ*BIZV9_na} zr^tA%G1x3fw#M8|nFYz2GL4i2vR)_f&tVGNCy4Mf%TB#6#e&f_O=4v8edKJ!UQOHt zeAk2M1NcLyS!D(@9>h&T2-3C@+z~_F7Q;S$1Rs_Hn>^;&_t3N%g^>wONIc$REVh;- z46qT@ERl+tLO4v44CW#9AAhMq2_UqQ%8=<;S(gQ`5DIv9_+!Eg={vKcBXo{wsD?-d zTg?;)KbgUXhz$H4#6SNC>X05IkqF^U00+M#9OTH~tzKjalZ=R(Bii=Bix5snbSHoy z>mLtpHm9_>610#3FT*^9-J=)^d$oCPG6TyCf}Ic^YKI(EByOhZ4ox}Y`2w%H*&Iae zXmUrsWU>x^hE-gwzCLE`T^|2P{xd{R-k-?fV)gsSD6p1Bio>dS z!20Gl|N3`|a_`LJmM`a#Ay*2CjsZy_gDmz4ne$F^Og1SWp`M&LChjDU^kX3XRsr-z z7i~auxOLp&uTjKmtTdF4f>MnQlvX=p9DI?b*XpY~E3&A1jAts_oBQzm57_TKDIoc}I=S zFSW0=1NCR%Vp~02hzs#dTf3vG%Ju4PY=H-={1>G0IyRywzCiEi%I9iZa||bU%LJE; zaUSJKN5Q5qzdkIDKnoCB5_@RcAr-O!)}r?4qB@D-B<_&5Cbz-BZRJ2Kfz(}f{Vs|` zy?IxYr|?idMa45H?l~*npeI(g2e!ZR2^{~*uJg7uM0DpyS0S>ntuyY!jcN!u&lY-A0yOfrYkqtl3(Fx)5 zBOE!$U?{spL?Y2COSSQEHXd#LS%lQD{VgHx@AIW`g#jpM=m-UV_Ut5 zN(4)F)B`P2x3x&$HV$*Ql{;#b-^Pyr=UQZP-wgE~sBN7ICYs!WMQhQJU={#{lK4)_ zl&De|g-P`K@)h*S-=ha6u*?r6@tEj?sFmohA0-7m2;HGb1*A^NhQ;zcM*lVL&_toA zrg}=9`|Ys$NZ~Yy4U3aA$#Yq(347D9X|cLh(BKJb0CqqQ=Br6 z1WyniT~sF|v*5`VBl6K23HG*nsMBv7$8GXyJgOMe!rQWuxs#c!;*oq71)#(zVmvXF z#^U;t#=L-H`1&JP@{pVP-^F#A2r~I))P99~B&rv`%>)%aDP+z%DPvz;IlnB6#Rm43#)(`Vk`$CHf+h#O#R>5y^s%}QJ+0m8yl}1YW zTx;tT_imN;jo1K$jde(nkeM>l$gOqRBo#vi1JXqqogL9Vn|DLxL3A4cJPdTxZN4@^PEQ|=IDGgwTv-{ z{t0AL5Uo8{$0J>)QDcImhufnN+5*iZ*LV@+Cuj-Vtn5SMwz8eeJdg?x1OObGX&?I^ zZC%#zMrDSbj(i*SiM7ag&`bS0-bAGN>19TFFcZmNb>MEImqQ|Ay?O|F&h8+lDF-XFg4|I|jMlsae~n-F%v zEEX8%PG^9FtfWX@Ayr&*lIkN|pu$Ou8YSk{?BqjMz-yA*D^+e~mj_ zKta$VVC6Lf`PwOM_=Cqvcr4Eh4-XqQ^!zCZ$~qN<1o_8Qe1@W;r%W(A6P-8cIqSTN z+P~pW!#VglbANGRSozkxRE#9YX+$!^nKES#Nf{9JICGw)lBAi@Mad4`tGL7Op`fS| zBc>pdz;RA`i;XW8M~^iwb6+Z7=NSVY!Rf(IAN*8ThWXuL==7HF zsmocUMlOpOjgv5u%uEs>nig7Q%`{P$HWgb`2o!Y_XLzlhaL`MQV;soo3ldTpe1>X> z$nGQ8=N}`osh1?_U6OH81kS!?By-5jB%3#XeL5b4=`Gsfvb6qEC27S- z{PuMRa-v-&cCB6PT66n(>}>TNP1fSPgSf*xSwvUfW#WtL^*GKQ;*-=JHM|n%9Q6&z z7Li+z;o2qbG-*$qgVdEj$7iXB-p5DM>+$tPrly3yz&p+8x+sR5&!L z7yIX#*mOXp{}14>=;#R0GqG`?e5UUg_he74ljVuUGW@RGt}y6SVK9Q$Ncm0tW*5C{!2A{JuV(D+(CGc z@hL1WA80Ce{|Mye!xK&^nvE6@lz8qm#bw@y`$c|Irad`oC!IOkp*!=@Qe2`j&O$UB z&r+=ogfi6=Db?r+%v(Glf3&!MPhH^+`7p;PG>L(Ytf(880hW8}^Y_ZDbUM7eimwwg z@P=m3zPXI^__v4V1*<>U!sm&KS})_XY&8C^Ib3+{;`c0^^I0EfUpniB%QySjeuju= z9uSe_(^rQjqKhNgW!j1k=SHn7!tX@gVfhNkE{})|^Z0aYUHxI@l%$Ob@1GMByVh{m z#pbujaOAoqC(8RE-m)e$qqC?G(TUDt`Rl5jrBSrOm6W7Sw&Jo)O?>%7WNLW*s|44Q&o0mWViJa^CFNxVexfl zlBrYq>KS(3 zi|8w=ODO4C9{B;~2y^%Ixdn_bB5QaO*@B_vQ7`^hdtelb>SH(I>AXmUHznnelHyq9 z3~lzwi#8fbu|e3tc{b{$M&tUx_Od61M#BkOjRwboB==(?0=yhm{j} z@G|a@=$o3c%K5gc{6<3-WvG_=@&oMw1Os{T-+z_PFBI^nFTS#Ha;adb=6y*tD(B=r zeq^5tN=oG)QbBr2^3XR91=853Q8$HyL~{eq`BI=6L!4Ae^7@HEA2m~qGAK 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/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/http_proxy.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/http_proxy.py new file mode 100644 index 0000000..1cde458 --- /dev/null +++ b/zhdo.space/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/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/lint.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/lint.py new file mode 100644 index 0000000..3a74718 --- /dev/null +++ b/zhdo.space/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.IO[bytes]) -> None: + self._stream = stream + + def read(self, *args: t.Any) -> bytes: + if len(args) == 0: + warn( + "WSGI does not guarantee an EOF marker on the input stream, thus making" + " calls to 'wsgi.input.read()' unsafe. Conforming servers may never" + " return from this call.", + WSGIWarning, + stacklevel=2, + ) + elif len(args) != 1: + warn( + "Too many parameters passed to 'wsgi.input.read()'.", + WSGIWarning, + stacklevel=2, + ) + return self._stream.read(*args) + + def readline(self, *args: t.Any) -> bytes: + if len(args) == 0: + warn( + "Calls to 'wsgi.input.readline()' without arguments are unsafe. Use" + " 'wsgi.input.read()' instead.", + WSGIWarning, + stacklevel=2, + ) + elif len(args) == 1: + warn( + "'wsgi.input.readline()' was called with a size hint. WSGI does not" + " support this, although it's available on all major servers.", + WSGIWarning, + stacklevel=2, + ) + else: + raise TypeError("Too many arguments passed to 'wsgi.input.readline()'.") + return self._stream.readline(*args) + + def __iter__(self) -> t.Iterator[bytes]: + try: + return iter(self._stream) + except TypeError: + warn("'wsgi.input' is not iterable.", WSGIWarning, stacklevel=2) + return iter(()) + + def close(self) -> None: + warn("The application closed the input stream!", WSGIWarning, stacklevel=2) + self._stream.close() + + +class ErrorStream: + def __init__(self, stream: t.IO[str]) -> None: + self._stream = stream + + def write(self, s: str) -> None: + check_type("wsgi.error.write()", s, str) + self._stream.write(s) + + def flush(self) -> None: + self._stream.flush() + + def writelines(self, seq: t.Iterable[str]) -> None: + for line in seq: + self.write(line) + + def close(self) -> None: + warn("The application closed the error stream!", WSGIWarning, stacklevel=2) + self._stream.close() + + +class GuardedWrite: + def __init__(self, write: t.Callable[[bytes], object], chunks: t.List[int]) -> None: + self._write = write + self._chunks = chunks + + def __call__(self, s: bytes) -> None: + check_type("write()", s, bytes) + self._write(s) + self._chunks.append(len(s)) + + +class GuardedIterator: + def __init__( + self, + iterator: t.Iterable[bytes], + headers_set: t.Tuple[int, Headers], + chunks: t.List[int], + ) -> None: + self._iterator = iterator + self._next = iter(iterator).__next__ + self.closed = False + self.headers_set = headers_set + self.chunks = chunks + + def __iter__(self) -> "GuardedIterator": + return self + + def __next__(self) -> bytes: + if self.closed: + warn("Iterated over closed 'app_iter'.", WSGIWarning, stacklevel=2) + + rv = self._next() + + if not self.headers_set: + warn( + "The application returned before it started the response.", + WSGIWarning, + stacklevel=2, + ) + + check_type("application iterator items", rv, bytes) + self.chunks.append(len(rv)) + return rv + + def close(self) -> None: + self.closed = True + + if hasattr(self._iterator, "close"): + self._iterator.close() # type: ignore + + if self.headers_set: + status_code, headers = self.headers_set + bytes_sent = sum(self.chunks) + content_length = headers.get("content-length", type=int) + + if status_code == 304: + for key, _value in headers: + key = key.lower() + if key not in ("expires", "content-location") and is_entity_header( + key + ): + warn( + f"Entity header {key!r} found in 304 response.", HTTPWarning + ) + if bytes_sent: + warn("304 responses must not have a body.", HTTPWarning) + elif 100 <= status_code < 200 or status_code == 204: + if content_length != 0: + warn( + f"{status_code} responses must have an empty content length.", + HTTPWarning, + ) + if bytes_sent: + warn(f"{status_code} responses must not have a body.", HTTPWarning) + elif content_length is not None and content_length != bytes_sent: + warn( + "Content-Length and the number of bytes sent to the" + " client do not match.", + WSGIWarning, + ) + + def __del__(self) -> None: + if not self.closed: + try: + warn( + "Iterator was garbage collected before it was closed.", WSGIWarning + ) + except Exception: + pass + + +class LintMiddleware: + """Warns about common errors in the WSGI and HTTP behavior of the + server and wrapped application. Some of the issues it checks are: + + - invalid status codes + - non-bytes sent to the WSGI server + - strings returned from the WSGI application + - non-empty conditional responses + - unquoted etags + - relative URLs in the Location header + - unsafe calls to wsgi.input + - unclosed iterators + + Error information is emitted using the :mod:`warnings` module. + + :param app: The WSGI application to wrap. + + .. code-block:: python + + from werkzeug.middleware.lint import LintMiddleware + app = LintMiddleware(app) + """ + + def __init__(self, app: "WSGIApplication") -> None: + self.app = app + + def check_environ(self, environ: "WSGIEnvironment") -> None: + if type(environ) is not dict: + warn( + "WSGI environment is not a standard Python dict.", + WSGIWarning, + stacklevel=4, + ) + for key in ( + "REQUEST_METHOD", + "SERVER_NAME", + "SERVER_PORT", + "wsgi.version", + "wsgi.input", + "wsgi.errors", + "wsgi.multithread", + "wsgi.multiprocess", + "wsgi.run_once", + ): + if key not in environ: + warn( + f"Required environment key {key!r} not found", + WSGIWarning, + stacklevel=3, + ) + if environ["wsgi.version"] != (1, 0): + warn("Environ is not a WSGI 1.0 environ.", WSGIWarning, stacklevel=3) + + script_name = environ.get("SCRIPT_NAME", "") + path_info = environ.get("PATH_INFO", "") + + if script_name and script_name[0] != "/": + warn( + f"'SCRIPT_NAME' does not start with a slash: {script_name!r}", + WSGIWarning, + stacklevel=3, + ) + + if path_info and path_info[0] != "/": + warn( + f"'PATH_INFO' does not start with a slash: {path_info!r}", + WSGIWarning, + stacklevel=3, + ) + + def check_start_response( + self, + status: str, + headers: t.List[t.Tuple[str, str]], + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ], + ) -> t.Tuple[int, Headers]: + check_type("status", status, str) + status_code_str = status.split(None, 1)[0] + + if len(status_code_str) != 3 or not status_code_str.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/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/profiler.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/profiler.py new file mode 100644 index 0000000..200dae0 --- /dev/null +++ b/zhdo.space/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.IO[str] = sys.stdout, + sort_by: t.Iterable[str] = ("time", "calls"), + restrictions: t.Iterable[t.Union[str, int, float]] = (), + profile_dir: t.Optional[str] = None, + filename_format: str = "{method}.{path}.{elapsed:.0f}ms.{time:.0f}.prof", + ) -> None: + self._app = app + self._stream = stream + self._sort_by = sort_by + self._restrictions = restrictions + self._profile_dir = profile_dir + self._filename_format = filename_format + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + response_body: t.List[bytes] = [] + + def catching_start_response(status, headers, exc_info=None): # type: ignore + start_response(status, headers, exc_info) + return response_body.append + + def runapp() -> None: + app_iter = self._app( + environ, t.cast("StartResponse", catching_start_response) + ) + response_body.extend(app_iter) + + if hasattr(app_iter, "close"): + app_iter.close() # type: ignore + + profile = Profile() + start = time.time() + profile.runcall(runapp) + body = b"".join(response_body) + elapsed = time.time() - start + + if self._profile_dir is not None: + if callable(self._filename_format): + filename = self._filename_format(environ) + else: + filename = self._filename_format.format( + method=environ["REQUEST_METHOD"], + path=environ["PATH_INFO"].strip("/").replace("/", ".") or "root", + elapsed=elapsed * 1000.0, + time=time.time(), + ) + filename = os.path.join(self._profile_dir, filename) + profile.dump_stats(filename) + + if self._stream is not None: + stats = Stats(profile, stream=self._stream) + stats.sort_stats(*self._sort_by) + print("-" * 80, file=self._stream) + path_info = environ.get("PATH_INFO", "") + print(f"PATH: {path_info!r}", file=self._stream) + stats.print_stats(*self._restrictions) + print(f"{'-' * 80}\n", file=self._stream) + + return [body] diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/proxy_fix.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/proxy_fix.py new file mode 100644 index 0000000..4cef7cc --- /dev/null +++ b/zhdo.space/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"] = environ["SERVER_NAME"] = x_host + # "]" to check for IPv6 address without port + if ":" in x_host and not x_host.endswith("]"): + environ["SERVER_NAME"], environ["SERVER_PORT"] = x_host.rsplit(":", 1) + + x_port = self._get_real_value(self.x_port, environ_get("HTTP_X_FORWARDED_PORT")) + if x_port: + host = environ.get("HTTP_HOST") + if host: + # "]" to check for IPv6 address without port + if ":" in host and not host.endswith("]"): + host = host.rsplit(":", 1)[0] + environ["HTTP_HOST"] = f"{host}:{x_port}" + environ["SERVER_PORT"] = x_port + + x_prefix = self._get_real_value( + self.x_prefix, environ_get("HTTP_X_FORWARDED_PREFIX") + ) + if x_prefix: + environ["SCRIPT_NAME"] = x_prefix + + return self.app(environ, start_response) diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/shared_data.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/shared_data.py new file mode 100644 index 0000000..2ec396c --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/middleware/shared_data.py @@ -0,0 +1,280 @@ +""" +Serve Shared Static Files +========================= + +.. autoclass:: SharedDataMiddleware + :members: is_allowed + +:copyright: 2007 Pallets +:license: BSD-3-Clause +""" +import mimetypes +import os +import pkgutil +import posixpath +import typing as t +from datetime import datetime +from datetime import timezone +from io import BytesIO +from time import time +from zlib import adler32 + +from ..http import http_date +from ..http import is_resource_modified +from ..security import safe_join +from ..utils import get_content_type +from ..wsgi import get_path_info +from ..wsgi import wrap_file + +_TOpener = t.Callable[[], t.Tuple[t.IO[bytes], datetime, int]] +_TLoader = t.Callable[[t.Optional[str]], t.Tuple[t.Optional[str], t.Optional[_TOpener]]] + +if t.TYPE_CHECKING: + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + +class SharedDataMiddleware: + + """A WSGI middleware which provides static content for development + environments or simple server setups. Its usage is quite simple:: + + import os + from werkzeug.middleware.shared_data import SharedDataMiddleware + + app = SharedDataMiddleware(app, { + '/shared': os.path.join(os.path.dirname(__file__), 'shared') + }) + + The contents of the folder ``./shared`` will now be available on + ``http://example.com/shared/``. This is pretty useful during development + because a standalone media server is not required. Files can also be + mounted on the root folder and still continue to use the application because + the shared data middleware forwards all unhandled requests to the + application, even if the requests are below one of the shared folders. + + If `pkg_resources` is available you can also tell the middleware to serve + files from package data:: + + app = SharedDataMiddleware(app, { + '/static': ('myapplication', 'static') + }) + + This will then serve the ``static`` folder in the `myapplication` + Python package. + + The optional `disallow` parameter can be a list of :func:`~fnmatch.fnmatch` + rules for files that are not accessible from the web. If `cache` is set to + `False` no caching headers are sent. + + Currently the middleware does not support non-ASCII filenames. If the + encoding on the file system happens to match the encoding of the URI it may + work but this could also be by accident. We strongly suggest using ASCII + only file names for static files. + + The middleware will guess the mimetype using the Python `mimetype` + module. If it's unable to figure out the charset it will fall back + to `fallback_mimetype`. + + :param app: the application to wrap. If you don't want to wrap an + application you can pass it :exc:`NotFound`. + :param exports: a list or dict of exported files and folders. + :param disallow: a list of :func:`~fnmatch.fnmatch` rules. + :param cache: enable or disable caching headers. + :param cache_timeout: the cache timeout in seconds for the headers. + :param fallback_mimetype: The fallback mimetype for unknown files. + + .. versionchanged:: 1.0 + The default ``fallback_mimetype`` is + ``application/octet-stream``. If a filename looks like a text + mimetype, the ``utf-8`` charset is added to it. + + .. versionadded:: 0.6 + Added ``fallback_mimetype``. + + .. versionchanged:: 0.5 + Added ``cache_timeout``. + """ + + def __init__( + self, + app: "WSGIApplication", + exports: t.Union[ + t.Dict[str, t.Union[str, t.Tuple[str, str]]], + t.Iterable[t.Tuple[str, t.Union[str, t.Tuple[str, str]]]], + ], + disallow: None = None, + cache: bool = True, + cache_timeout: int = 60 * 60 * 12, + fallback_mimetype: str = "application/octet-stream", + ) -> None: + self.app = app + self.exports: t.List[t.Tuple[str, _TLoader]] = [] + self.cache = cache + self.cache_timeout = cache_timeout + + if isinstance(exports, dict): + exports = exports.items() + + for key, value in exports: + if isinstance(value, tuple): + loader = self.get_package_loader(*value) + elif isinstance(value, str): + if os.path.isfile(value): + loader = self.get_file_loader(value) + else: + loader = self.get_directory_loader(value) + else: + raise TypeError(f"unknown def {value!r}") + + self.exports.append((key, loader)) + + if disallow is not None: + from fnmatch import fnmatch + + self.is_allowed = lambda x: not fnmatch(x, disallow) + + self.fallback_mimetype = fallback_mimetype + + def is_allowed(self, filename: str) -> bool: + """Subclasses can override this method to disallow the access to + certain files. However by providing `disallow` in the constructor + this method is overwritten. + """ + return True + + def _opener(self, filename: str) -> _TOpener: + return lambda: ( + open(filename, "rb"), + datetime.fromtimestamp(os.path.getmtime(filename), tz=timezone.utc), + int(os.path.getsize(filename)), + ) + + def get_file_loader(self, filename: str) -> _TLoader: + return lambda x: (os.path.basename(filename), self._opener(filename)) + + def get_package_loader(self, package: str, package_path: str) -> _TLoader: + load_time = datetime.now(timezone.utc) + provider = pkgutil.get_loader(package) + reader = provider.get_resource_reader(package) # type: ignore + + def loader( + path: t.Optional[str], + ) -> t.Tuple[t.Optional[str], t.Optional[_TOpener]]: + if path is None: + return None, None + + path = safe_join(package_path, path) + + if path is None: + return None, None + + basename = posixpath.basename(path) + + try: + resource = reader.open_resource(path) + except OSError: + return None, None + + if isinstance(resource, BytesIO): + return ( + basename, + lambda: (resource, load_time, len(resource.getvalue())), + ) + + return ( + basename, + lambda: ( + resource, + datetime.fromtimestamp( + os.path.getmtime(resource.name), tz=timezone.utc + ), + os.path.getsize(resource.name), + ), + ) + + return loader + + def get_directory_loader(self, directory: str) -> _TLoader: + def loader( + path: t.Optional[str], + ) -> t.Tuple[t.Optional[str], t.Optional[_TOpener]]: + if path is not None: + path = safe_join(directory, path) + + if path is None: + return None, None + else: + path = directory + + if os.path.isfile(path): + return os.path.basename(path), self._opener(path) + + return None, None + + return loader + + def generate_etag(self, mtime: datetime, file_size: int, real_filename: str) -> str: + real_filename = os.fsencode(real_filename) + timestamp = mtime.timestamp() + checksum = adler32(real_filename) & 0xFFFFFFFF + return f"wzsdm-{timestamp}-{file_size}-{checksum}" + + def __call__( + self, environ: "WSGIEnvironment", start_response: "StartResponse" + ) -> t.Iterable[bytes]: + path = get_path_info(environ) + file_loader = None + + for search_path, loader in self.exports: + if search_path == path: + real_filename, file_loader = loader(None) + + if file_loader is not None: + break + + if not search_path.endswith("/"): + search_path += "/" + + if path.startswith(search_path): + real_filename, file_loader = loader(path[len(search_path) :]) + + if file_loader is not None: + break + + if file_loader is None or not self.is_allowed(real_filename): # type: ignore + return self.app(environ, start_response) + + guessed_type = mimetypes.guess_type(real_filename) # type: ignore + mime_type = get_content_type(guessed_type[0] or self.fallback_mimetype, "utf-8") + f, mtime, file_size = file_loader() + + headers = [("Date", http_date())] + + if self.cache: + timeout = self.cache_timeout + etag = self.generate_etag(mtime, file_size, real_filename) # type: ignore + headers += [ + ("Etag", f'"{etag}"'), + ("Cache-Control", f"max-age={timeout}, public"), + ] + + if not is_resource_modified(environ, etag, last_modified=mtime): + f.close() + start_response("304 Not Modified", headers) + return [] + + headers.append(("Expires", http_date(time() + timeout))) + else: + headers.append(("Cache-Control", "public")) + + headers.extend( + ( + ("Content-Type", mime_type), + ("Content-Length", str(file_size)), + ("Last-Modified", http_date(mtime)), + ) + ) + start_response("200 OK", headers) + return wrap_file(environ, f) diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/py.typed b/zhdo.space/lib/python3.9/site-packages/werkzeug/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/routing.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/routing.py new file mode 100644 index 0000000..1d3027b --- /dev/null +++ b/zhdo.space/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 .urls import url_unquote +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.request import Request + 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[t.Union["WSGIEnvironment", "Request"]] = 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[RuleFactory]) -> 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[RuleFactory]) -> 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[RuleFactory]) -> 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[RuleFactory], 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: + params = self._encode_query_vars(kwargs) + q = "?" if params else "" +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`` they 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. + + .. versionchanged:: 2.1 + Percent-encoded newlines (``%0a``), which are decoded by WSGI + servers, are considered when routing instead of terminating the + match early. + + .. 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) + self._build_unknown: t.Callable[..., t.Tuple[str, str]] + self._build_unknown = self._compile_builder(True).__get__(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 = "" + + # Use \Z instead of $ to avoid matching before a %0a decoded to + # a \n by WSGI. + regex = rf"^{''.join(regex_parts)}{tail}$\Z" + 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("/"): + # The URL will be encoded when MapAdapter.match + # handles the RequestPath raised below. Decode + # the URL here to avoid a double encoding. + path = url_unquote(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 as e: + raise BadHost() from e + + return MapAdapter( + self, + server_name, + script_name, + subdomain, + url_scheme, + path_info, + default_method, + query_args, + ) + + def bind_to_environ( + self, + environ: t.Union["WSGIEnvironment", "Request"], + 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). + """ + env = _get_environ(environ) + wsgi_server_name = get_host(env).lower() + scheme = env["wsgi.url_scheme"] + upgrade = any( + v.strip() == "upgrade" + for v in env.get("HTTP_CONNECTION", "").lower().split(",") + ) + + if upgrade and env.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 = env.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, + env["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, + ) + ) from None + except RequestAliasRedirect as e: + raise RequestRedirect( + self.make_alias_redirect_url( + path, rule.endpoint, e.matched_values, method, query_args + ) + ) from None + 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: + if isinstance(values, MultiDict): + values = { + k: (v[0] if len(v) == 1 else v) + for k, v in dict.items(values) + if len(v) != 0 + } + else: # plain dict + values = {k: v for k, v in values.items() if v is not None} + 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/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/__init__.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..566ddaa1350b7432a2230e9fc459fa64885e499c GIT binary patch literal 184 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 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/request.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/__pycache__/request.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f32920cbdbcac39f2c5c771e139611cfcb9ae367 GIT binary patch literal 17127 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 Up!ZGlhWVfM4b9Ok{k#|d0WNzx@Bjb+ literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/multipart.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/multipart.py new file mode 100644 index 0000000..2d54422 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/multipart.py @@ -0,0 +1,260 @@ +import re +from dataclasses import dataclass +from enum import auto +from enum import Enum +from typing import cast +from typing import List +from typing import Optional +from typing import Tuple + +from .._internal import _to_bytes +from .._internal import _to_str +from ..datastructures import Headers +from ..exceptions import RequestEntityTooLarge +from ..http import parse_options_header + + +class Event: + pass + + +@dataclass(frozen=True) +class Preamble(Event): + data: bytes + + +@dataclass(frozen=True) +class Field(Event): + name: str + headers: Headers + + +@dataclass(frozen=True) +class File(Event): + name: str + filename: str + headers: Headers + + +@dataclass(frozen=True) +class Data(Event): + data: bytes + more_data: bool + + +@dataclass(frozen=True) +class Epilogue(Event): + data: bytes + + +class NeedData(Event): + pass + + +NEED_DATA = NeedData() + + +class State(Enum): + PREAMBLE = auto() + PART = auto() + DATA = auto() + EPILOGUE = auto() + COMPLETE = auto() + + +# Multipart line breaks MUST be CRLF (\r\n) by RFC-7578, except that +# many implementations break this and either use CR or LF alone. +LINE_BREAK = b"(?:\r\n|\n|\r)" +BLANK_LINE_RE = re.compile(b"(?:\r\n\r\n|\r\r|\n\n)", re.MULTILINE) +LINE_BREAK_RE = re.compile(LINE_BREAK, re.MULTILINE) +# Header values can be continued via a space or tab after the linebreak, as +# per RFC2231 +HEADER_CONTINUATION_RE = re.compile(b"%s[ \t]" % LINE_BREAK, re.MULTILINE) + + +class MultipartDecoder: + """Decodes a multipart message as bytes into Python events. + + The part data is returned as available to allow the caller to save + the data from memory to disk, if desired. + """ + + def __init__( + self, + boundary: bytes, + max_form_memory_size: Optional[int] = None, + ) -> 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( + rb"%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( + rb"%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/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/request.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/request.py new file mode 100644 index 0000000..3802403 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/request.py @@ -0,0 +1,547 @@ +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 ..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: t.Type[UserAgent] = UserAgent + """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/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/response.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/response.py new file mode 100644 index 0000000..82817e8 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/response.py @@ -0,0 +1,704 @@ +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 ContentSecurityPolicy +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_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: CallbackDict) -> 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 + + @property + def content_security_policy(self) -> ContentSecurityPolicy: + """The ``Content-Security-Policy`` header as a + :class:`~werkzeug.datastructures.ContentSecurityPolicy` object. Available + even if the header is not set. + + The Content-Security-Policy header adds an additional layer of + security to help detect and mitigate certain types of attacks. + """ + + def on_update(csp: ContentSecurityPolicy) -> None: + if not csp: + del self.headers["content-security-policy"] + else: + self.headers["Content-Security-Policy"] = csp.to_header() + + rv = parse_csp_header(self.headers.get("content-security-policy"), on_update) + if rv is None: + rv = ContentSecurityPolicy(None, on_update=on_update) + return rv + + @content_security_policy.setter + def content_security_policy( + self, value: t.Optional[t.Union[ContentSecurityPolicy, str]] + ) -> None: + if not value: + del self.headers["content-security-policy"] + elif isinstance(value, str): + self.headers["Content-Security-Policy"] = value + else: + self.headers["Content-Security-Policy"] = value.to_header() + + @property + def content_security_policy_report_only(self) -> ContentSecurityPolicy: + """The ``Content-Security-policy-report-only`` header as a + :class:`~werkzeug.datastructures.ContentSecurityPolicy` object. Available + even if the header is not set. + + 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. + """ + + def on_update(csp: ContentSecurityPolicy) -> None: + if not csp: + del self.headers["content-security-policy-report-only"] + else: + self.headers["Content-Security-policy-report-only"] = csp.to_header() + + rv = parse_csp_header( + self.headers.get("content-security-policy-report-only"), on_update + ) + if rv is None: + rv = ContentSecurityPolicy(None, on_update=on_update) + return rv + + @content_security_policy_report_only.setter + def content_security_policy_report_only( + self, value: t.Optional[t.Union[ContentSecurityPolicy, str]] + ) -> None: + if not value: + del self.headers["content-security-policy-report-only"] + elif isinstance(value, str): + self.headers["Content-Security-policy-report-only"] = value + else: + self.headers["Content-Security-policy-report-only"] = value.to_header() + + # 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/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/utils.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/sansio/utils.py new file mode 100644 index 0000000..1b4d892 --- /dev/null +++ b/zhdo.space/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/zhdo.space/lib/python3.9/site-packages/werkzeug/security.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/security.py new file mode 100644 index 0000000..18d0919 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/security.py @@ -0,0 +1,140 @@ +import hashlib +import hmac +import os +import posixpath +import secrets +import typing as t + +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 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``. + """ + if not directory: + # Ensure we end up with ./path if directory="" is given, + # otherwise the first untrusted part could become trusted. + directory = "." + + 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/zhdo.space/lib/python3.9/site-packages/werkzeug/serving.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/serving.py new file mode 100644 index 0000000..7123076 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/serving.py @@ -0,0 +1,1091 @@ +"""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 errno +import io +import os +import socket +import socketserver +import sys +import typing as t +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( # noqa: B904 + "SSL is unavailable because this Python runtime was not" + " compiled with SSL/TLS support." + ) + + 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 + +_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.IO[bytes]) -> 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 as e: + raise OSError("Invalid chunk header") from e + 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) + 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.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( # type: ignore[attr-defined] + 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 + chunk_response: bool = False + + def write(data: bytes) -> None: + nonlocal status_sent, headers_sent, chunk_response + 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) + header_keys.add(key.lower()) + + # Use chunked transfer encoding if there is no content + # length. Do not use for 1xx and 204 responses. 304 + # responses and HEAD requests are also excluded, which + # is the more conservative behavior and matches other + # parts of the code. + # https://httpwg.org/specs/rfc7230.html#rfc.section.3.3.1 + if ( + not ( + "content-length" in header_keys + or environ["REQUEST_METHOD"] == "HEAD" + or (100 <= code < 200) + or code in {204, 304} + ) + and self.protocol_version >= "HTTP/1.1" + ): + chunk_response = True + self.send_header("Transfer-Encoding", "chunked") + + # Always close the connection. This disables HTTP/1.1 + # keep-alive connections. They aren't handled well by + # Python's http.server because it doesn't know how to + # drain the stream before the next request line. + self.send_header("Connection", "close") + self.end_headers() + + assert isinstance(data, bytes), "applications must write bytes" + + if data: + if chunk_response: + self.wfile.write(hex(len(data))[2:].encode()) + self.wfile.write(b"\r\n") + + self.wfile.write(data) + + if chunk_response: + self.wfile.write(b"\r\n") + + 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"") + if chunk_response: + self.wfile.write(b"0\r\n\r\n") + 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 as e: + if self.server.passthrough_errors: + raise + + if status_sent is not None and chunk_response: + self.close_connection = 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 + + from .debug.tbtools import DebugTraceback + + msg = DebugTraceback(e).render_traceback_text() + self.server.log("error", f"Error on request:\n{msg}") + + def handle(self) -> None: + """Handles a request ignoring dropped connections.""" + try: + super().handle() + 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 + + 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 __getattr__(self, name: str) -> t.Any: + # All HTTP methods are handled by run_wsgi. + if name.startswith("do_"): + return self.run_wsgi + + # All other attributes are forwarded to the base class. + return getattr(super(), name) + + 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." + ) from None + + 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(cn)]), 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): + """A WSGI server that that handles one request at a time. + + Use :func:`make_server` to create a server instance. + """ + + 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 + + # If the handler doesn't directly set a protocol version and + # thread or process workers are used, then allow chunked + # responses and keep-alive connections by enabling HTTP/1.1. + if "protocol_version" not in vars(handler) and ( + self.multithread or self.multiprocess + ): + handler.protocol_version = "HTTP/1.1" + + self.host = host + self.port = port + self.app = app + self.passthrough_errors = passthrough_errors + + self.address_family = address_family = select_address_family(host, port) + server_address = get_sockaddr(host, int(port), address_family) + + # Remove a leftover Unix socket file from a previous run. Don't + # remove a file that was set up by run_simple. + if address_family == af_unix and fd is None: + server_address = t.cast(str, server_address) + + if os.path.exists(server_address): + os.unlink(server_address) + + # Bind and activate will be handled manually, it should only + # happen if we're not using a socket that was already set up. + super().__init__( + server_address, # type: ignore[arg-type] + handler, + bind_and_activate=False, + ) + + if fd is None: + # No existing socket descriptor, do bind_and_activate=True. + try: + self.server_bind() + self.server_activate() + except BaseException: + self.server_close() + raise + else: + # Use the passed in socket directly. + self.socket = socket.fromfd(fd, address_family, socket.SOCK_STREAM) + self.server_address = self.socket.getsockname() + + if address_family != af_unix: + # If port was 0, this will record the bound port. + self.port = self.server_address[1] + + if ssl_context is not None: + if isinstance(ssl_context, tuple): + ssl_context = load_ssl_context(*ssl_context) + elif 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: + 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.Union[t.Tuple[str, int], str] + ) -> None: + if self.passthrough_errors: + raise + + return super().handle_error(request, client_address) + + def log_startup(self) -> None: + """Show information about the address when starting the server.""" + if self.address_family == af_unix: + _log("info", f" * Running on {self.host} (Press CTRL+C to quit)") + else: + scheme = "http" if self.ssl_context is None else "https" + messages = [] + all_addresses_message = ( + f" * Running on all addresses ({self.host})\n" + " WARNING: This is a development server. Do not use it in" + " a production deployment." + ) + + if self.host == "0.0.0.0": + messages.append(all_addresses_message) + messages.append(f" * Running on {scheme}://127.0.0.1:{self.port}") + display_hostname = get_interface_ip(socket.AF_INET) + elif self.host == "::": + messages.append(all_addresses_message) + messages.append(f" * Running on {scheme}://[::1]:{self.port}") + display_hostname = get_interface_ip(socket.AF_INET6) + else: + display_hostname = self.host + + if ":" in display_hostname: + display_hostname = f"[{display_hostname}]" + + messages.append( + f" * Running on {scheme}://{display_hostname}:{self.port}" + " (Press CTRL+C to quit)" + ) + _log("info", "\n".join(messages)) + + +class ThreadedWSGIServer(socketserver.ThreadingMixIn, BaseWSGIServer): + """A WSGI server that handles concurrent requests in separate + threads. + + Use :func:`make_server` to create a server instance. + """ + + multithread = True + daemon_threads = True + + +class ForkingWSGIServer(ForkingMixIn, BaseWSGIServer): + """A WSGI server that handles concurrent requests in separate forked + processes. + + Use :func:`make_server` to create a server instance. + """ + + 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.") + + super().__init__(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 an appropriate WSGI server instance based on the value of + ``threaded`` and ``processes``. + + This is called from :func:`run_simple`, but can be used separately + to have access to the server object, such as to run it in a separate + thread. + + See :func:`run_simple` for parameter docs. + """ + if threaded and processes > 1: + raise ValueError("Cannot have a multi-thread and multi-process server.") + + if threaded: + return ThreadedWSGIServer( + host, port, app, request_handler, passthrough_errors, ssl_context, fd=fd + ) + + if processes > 1: + return ForkingWSGIServer( + host, + port, + app, + processes, + request_handler, + passthrough_errors, + ssl_context, + fd=fd, + ) + + return BaseWSGIServer( + host, port, app, request_handler, passthrough_errors, ssl_context, fd=fd + ) + + +def is_running_from_reloader() -> bool: + """Check if the server is running as a subprocess within the + Werkzeug reloader. + + .. versionadded:: 0.10 + """ + return os.environ.get("WERKZEUG_RUN_MAIN") == "true" + + +def prepare_socket(hostname: str, port: int) -> socket.socket: + """Prepare a socket for use by the WSGI server and reloader. + + The socket is marked inheritable so that it can be kept across + reloads instead of breaking connections. + + Catch errors during bind and show simpler error messages. For + "address already in use", show instructions for resolving the issue, + with special instructions for macOS. + + This is called from :func:`run_simple`, but can be used separately + to control server creation with :func:`make_server`. + """ + 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.set_inheritable(True) + + # Remove the socket file if it already exists. + if address_family == af_unix: + server_address = t.cast(str, server_address) + + if os.path.exists(server_address): + os.unlink(server_address) + + # Catch connection issues and show them without the traceback. Show + # extra instructions for address not found, and for macOS. + try: + s.bind(server_address) + except OSError as e: + print(e.strerror, file=sys.stderr) + + if e.errno == errno.EADDRINUSE: + print( + f"Port {port} is in use by another program. Either" + " identify and stop that program, or start the" + " server with a different port.", + file=sys.stderr, + ) + + if sys.platform == "darwin" and port == 5000: + print( + "On macOS, try disabling the 'AirPlay Receiver'" + " service from System Preferences -> Sharing.", + file=sys.stderr, + ) + + sys.exit(1) + + s.listen(LISTEN_QUEUE) + return s + + +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 development server for a WSGI application. Various + optional features can be enabled. + + .. warning:: + + Do not use the development server when deploying to production. + It is intended for use only during local development. It is not + designed to be particularly efficient, stable, or secure. + + :param hostname: The host to bind to, for example ``'localhost'``. + Can be a domain, IPv4 or IPv6 address, or file path starting + with ``unix://`` for a Unix socket. + :param port: The port to bind to, for example ``8080``. Using ``0`` + tells the OS to pick a random free port. + :param application: The WSGI application to run. + :param use_reloader: Use a reloader process to restart the server + process when files are changed. + :param use_debugger: Use Werkzeug's debugger, which will show + formatted tracebacks on unhandled exceptions. + :param use_evalex: Make the debugger interactive. A Python terminal + can be opened for any frame in the traceback. Some protection is + provided by requiring a PIN, but this should never be enabled + on a publicly visible server. + :param extra_files: The reloader will watch these files for changes + in addition to Python modules. For example, watch a + configuration file. + :param exclude_patterns: The reloader will ignore changes to any + files matching these :mod:`fnmatch` patterns. For example, + ignore cache files. + :param reloader_interval: How often the reloader tries to check for + changes. + :param reloader_type: The reloader to use. The ``'stat'`` reloader + is built in, but may require significant CPU to watch files. The + ``'watchdog'`` reloader is much more efficient but requires + installing the ``watchdog`` package first. + :param threaded: Handle concurrent requests using threads. Cannot be + used with ``processes``. + :param processes: Handle concurrent requests using up to this number + of processes. Cannot be used with ``threaded``. + :param request_handler: Use a different + :class:`~BaseHTTPServer.BaseHTTPRequestHandler` subclass to + handle requests. + :param static_files: A dict mapping URL prefixes to directories to + serve static files from using + :class:`~werkzeug.middleware.SharedDataMiddleware`. + :param passthrough_errors: Don't catch unhandled exceptions at the + server level, let the serve crash instead. If ``use_debugger`` + is enabled, the debugger will still catch such errors. + :param ssl_context: Configure TLS to serve over HTTPS. Can be an + :class:`ssl.SSLContext` object, a ``(cert_file, key_file)`` + tuple to create a typical context, or the string ``'adhoc'`` to + generate a temporary self-signed certificate. + + .. versionchanged:: 2.1 + Instructions are shown for dealing with an "address already in + use" error. + + .. versionchanged:: 2.1 + Running on ``0.0.0.0`` or ``::`` shows the loopback IP in + addition to a real IP. + + .. versionchanged:: 2.1 + The command-line interface was removed. + + .. versionchanged:: 2.0 + Running on ``0.0.0.0`` or ``::`` shows a real IP address that + was bound as well as a warning not to run the development server + in production. + + .. versionchanged:: 2.0 + The ``exclude_patterns`` parameter was added. + + .. versionchanged:: 0.15 + Bind to a Unix socket by passing a ``hostname`` that starts with + ``unix://``. + + .. versionchanged:: 0.10 + Improved the reloader and added support for changing the backend + through the ``reloader_type`` parameter. + + .. versionchanged:: 0.9 + A command-line interface was added. + + .. versionchanged:: 0.8 + ``ssl_context`` can be a tuple of paths to the certificate and + private key files. + + .. versionchanged:: 0.6 + The ``ssl_context`` parameter was added. + + .. versionchanged:: 0.5 + The ``static_files`` and ``passthrough_errors`` parameters were + added. + """ + if not isinstance(port, int): + raise TypeError("port must be an integer") + + if static_files: + from .middleware.shared_data import SharedDataMiddleware + + application = SharedDataMiddleware(application, static_files) + + if use_debugger: + from .debug import DebuggedApplication + + application = DebuggedApplication(application, evalex=use_evalex) + + if not is_running_from_reloader(): + s = prepare_socket(hostname, port) + fd = s.fileno() + os.environ["WERKZEUG_SERVER_FD"] = str(fd) + else: + fd = int(os.environ["WERKZEUG_SERVER_FD"]) + + srv = make_server( + hostname, + port, + application, + threaded, + processes, + request_handler, + passthrough_errors, + ssl_context, + fd=fd, + ) + + if not is_running_from_reloader(): + srv.log_startup() + + if use_reloader: + from ._reloader import run_with_reloader + + run_with_reloader( + srv.serve_forever, + extra_files=extra_files, + exclude_patterns=exclude_patterns, + interval=reloader_interval, + reloader_type=reloader_type, + ) + else: + srv.serve_forever() diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/test.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/test.py new file mode 100644 index 0000000..75c5548 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/test.py @@ -0,0 +1,1325 @@ +import mimetypes +import sys +import typing as t +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 cached_property +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.IO[bytes], 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.IO[bytes] = BytesIO() + total_length = 0 + on_disk = False + write_binary: t.Callable[[bytes], int] + + 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.IO[bytes], 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.1 + ``CONTENT_TYPE`` and ``CONTENT_LENGTH`` are not duplicated as + header keys in the environ. + + .. 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 percent-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.IO[bytes]] + _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.IO[bytes]] = None, + content_type: t.Optional[str] = None, + content_length: t.Optional[int] = None, + errors_stream: t.Optional[t.IO[str]] = 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.IO[bytes], 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.IO[bytes], t.Tuple[t.IO[bytes], str], t.Tuple[t.IO[bytes], 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: CallbackDict) -> 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.IO[bytes]]: + """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.IO[bytes]]) -> 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() + # Don't send these as headers, they're part of the environ. + headers.remove("Content-Type") + headers.remove("Content-Length") + + if content_type is not None: + result["CONTENT_TYPE"] = content_type + + if content_length is not None: + result["CONTENT_LENGTH"] = str(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.1 + Removed deprecated behavior of treating the response as a + tuple. All data is available as properties on the returned + response object. + + .. 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, path=path, 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, + 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.1 + Removed the ``as_tuple`` parameter. + + .. 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"] = [] + + if not follow_redirects: + return response + + while 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. + 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) + 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``. + + .. versionchanged:: 2.1 + Removed deprecated behavior for treating the response instance + as a tuple. + + .. versionadded:: 2.0 + Test client methods always return instances of this class. + """ + + 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. + """ + + # Tell Pytest to ignore this, it's not a test class. + __test__ = False + + 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 + + @cached_property + def text(self) -> str: + """The response data as text. A shortcut for + ``response.get_data(as_text=True)``. + + .. versionadded:: 2.1 + """ + return self.get_data(as_text=True) diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/testapp.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/testapp.py new file mode 100644 index 0000000..0829e33 --- /dev/null +++ b/zhdo.space/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"
  2. {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/zhdo.space/lib/python3.9/site-packages/werkzeug/urls.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/urls.py new file mode 100644 index 0000000..67c08b0 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/urls.py @@ -0,0 +1,1067 @@ +"""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 + +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"-._~" + b"$!'()*+,;" # RFC3986 sub-delims set, not including query string delimiters &= + ) +) + +_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", + 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 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.IO[bytes], + charset: str = "utf-8", + include_empty: bool = True, + errors: str = "replace", + separator: bytes = b"&", + cls: t.Optional[t.Type["ds.MultiDict"]] = None, + limit: t.Optional[int] = None, +) -> "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 + + pair_iter = make_chunk_iter(stream, separator, limit) + decoder = _url_decode_impl(pair_iter, charset, include_empty, errors) + + 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", + 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. + """ + 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.IO[str]] = None, + charset: str = "utf-8", + 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 + """ + 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)) diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/user_agent.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/user_agent.py new file mode 100644 index 0000000..66ffcbe --- /dev/null +++ b/zhdo.space/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/zhdo.space/lib/python3.9/site-packages/werkzeug/utils.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/utils.py new file mode 100644 index 0000000..f94444e --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/utils.py @@ -0,0 +1,705 @@ +import io +import mimetypes +import os +import pkgutil +import re +import sys +import typing as t +import unicodedata +from datetime import datetime +from time import time +from zlib import adler32 + +from ._internal import _DictAccessorProperty +from ._internal import _missing +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 + + If the class defines ``__slots__``, it must add ``_cache_{name}`` as + a slot. Alternatively, it can add ``__dict__``, but that's usually + not desirable. + + .. versionchanged:: 2.1 + Works with ``__slots__``. + + .. 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.slot_name = f"_cache_{self.__name__}" + self.__module__ = fget.__module__ + + def __set__(self, obj: object, value: _T) -> None: + if hasattr(obj, "__dict__"): + obj.__dict__[self.__name__] = value + else: + setattr(obj, self.slot_name, value) + + def __get__(self, obj: object, type: type = None) -> _T: # type: ignore + if obj is None: + return self # type: ignore + + obj_dict = getattr(obj, "__dict__", None) + + if obj_dict is not None: + value: _T = obj_dict.get(self.__name__, _missing) + else: + value = getattr(obj, self.slot_name, _missing) # type: ignore[arg-type] + + if value is _missing: + value = self.fget(obj) # type: ignore + + if obj_dict is not None: + obj.__dict__[self.__name__] = value + else: + setattr(obj, self.slot_name, value) + + return value + + def __delete__(self, obj: object) -> None: + if hasattr(obj, "__dict__"): + del obj.__dict__[self.__name__] + else: + setattr(obj, self.slot_name, _missing) + + +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 + + +# 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 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 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" + "\n" + "Redirecting...\n" + "

    Redirecting...

    \n" + "

    You should be redirected automatically to the target URL: " + f'{display_location}. If' + " not, click the link.\n", + code, + mimetype="text/html", + ) + response.headers["Location"] = location + return response + + +def append_slash_redirect(environ: "WSGIEnvironment", code: int = 308) -> "Response": + """Redirect to the current URL with a slash appended. + + If the current URL is ``/user/42``, the redirect URL will be + ``42/``. When joined to the current URL during response + processing or by the browser, this will produce ``/user/42/``. + + The behavior is undefined if the path ends with a slash already. If + called unconditionally on a URL, it may produce a redirect loop. + + :param environ: Use the path and query from this WSGI environment + to produce the redirect URL. + :param code: the status code for the redirect. + + .. versionchanged:: 2.1 + Produce a relative URL that only modifies the last segment. + Relevant when the current path has multiple segments. + + .. versionchanged:: 2.1 + The default status code is 308 instead of 301. This preserves + the request method and body. + """ + tail = environ["PATH_INFO"].rpartition("/")[2] + + if not tail: + new_path = "./" + else: + new_path = f"{tail}/" + + query_string = environ.get("QUERY_STRING") + + if query_string: + new_path = f"{new_path}?{query_string}" + + return redirect(new_path, code) + + +def send_file( + path_or_file: t.Union[os.PathLike, str, t.IO[bytes]], + 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. + + .. versionchanged:: 2.0.2 + ``send_file`` only sets a detected ``Content-Encoding`` if + ``as_attachment`` is disabled. + + .. 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.IO[bytes]] = 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" + + # Don't send encoding for attachments, it causes browsers to + # save decompress tar.gz files. + if encoding is not None and not as_attachment: + 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() from None + + 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) from None + + except ImportError as e: + if not silent: + raise ImportStringError(import_name, e).with_traceback( + sys.exc_info()[2] + ) from None + + 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 + + +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/zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__init__.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__init__.py new file mode 100644 index 0000000..b8c45d7 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__init__.py @@ -0,0 +1,3 @@ +from .request import Request as Request +from .response import Response as Response +from .response import ResponseStream diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb3d071e633ff48d3623226d96825c22e967dc31 GIT binary patch literal 303 zcmYk1v1-FG5QZh&!6qbqjn+f0Ayc80JVAzJD0mS{e8jFTOFhY?$Km44U&!>#$^Y(rFM)xb2>xsxLY26)3#VX!0%}dS$M_r`jGXCS3I4Kk2 zWW(~wH>Y^c$8-&^12|8Zt-)E-J0QNf@Wvx3y~-zJivLLrjbn!AFvestA^BjK1`hHg zMQt>QmqGR7*1M{TO1gQxI_3;i=b%or literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/request.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/request.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13ed403095e12b1b7a5f8a9a3f3fc65c95ef3e82 GIT binary patch literal 20119 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 ViZ0?}mUs%s?7rqtNCEE){|Bu|pNaqg literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/response.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/__pycache__/response.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ca1382ae36c48348ea97b6e9a85c4309e924ad8 GIT binary patch literal 29100 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 apPZDV-{ 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 + 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.IO[bytes]: + """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.IO[bytes]: + """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.IO[bytes]: + """ + 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.IO[bytes]]( + "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 + + @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 :attr:`is_json`). + + Calls :meth:`get_json` with default arguments. + + If the request content type is not ``application/json``, this + will raise a 400 Bad Request error. + + .. versionchanged:: 2.1 + Raise a 400 error if the content type is incorrect. + """ + 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 :attr:`is_json`), or parsing + fails, :meth:`on_json_loading_failed` is called and + its return value is used as the return value. By default this + raises a 400 Bad Request error. + + :param force: Ignore the mimetype and always try to parse JSON. + :param silent: Silence mimetype and parsing errors, and + return ``None`` instead. + :param cache: Store the parsed JSON to return for subsequent + calls. + + .. versionchanged:: 2.1 + Raise a 400 error if the content type is incorrect. + """ + if cache and self._cached_json[silent] is not Ellipsis: + return self._cached_json[silent] + + if not (force or self.is_json): + if not silent: + return self.on_json_loading_failed(None) + else: + 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: t.Optional[ValueError]) -> t.Any: + """Called if :meth:`get_json` 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`. + + :param e: If parsing failed, this is the exception. It will be + ``None`` if the content type wasn't ``application/json``. + """ + if e is not None: + raise BadRequest(f"Failed to decode JSON object: {e}") + + raise BadRequest( + "Did not attempt to load JSON data because the request" + " Content-Type was not 'application/json'." + ) diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/response.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/response.py new file mode 100644 index 0000000..7e888cb --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/werkzeug/wrappers/response.py @@ -0,0 +1,877 @@ +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 + from .request import Request + + +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 + + #: If a redirect ``Location`` header is a relative URL, make it an + #: absolute URL, including scheme and domain. + #: + #: .. versionchanged:: 2.1 + #: This is disabled by default, so responses will send relative + #: redirects. + #: + #: .. versionadded:: 0.8 + autocorrect_location_header = False + + #: 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) -> 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.1 + Removed the ``no_etag`` parameter. + + .. 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))) + 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 :attr:`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 :attr:`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: t.Union["WSGIEnvironment", "Request"], + 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 overridden 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 :meth:`Response.stream` 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 diff --git a/zhdo.space/lib/python3.9/site-packages/werkzeug/wsgi.py b/zhdo.space/lib/python3.9/site-packages/werkzeug/wsgi.py new file mode 100644 index 0000000..9cfa74d --- /dev/null +++ b/zhdo.space/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.IO[bytes]: + """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.IO[bytes], 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.IO[bytes], 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.IO[bytes], 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.IO[bytes], 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.IO[bytes]], + 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.IO[bytes]], + 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.IO[bytes], stream) + if not isinstance(stream, LimitedStream) and limit is not None: + stream = t.cast(t.IO[bytes], 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.IO[bytes]], + 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.IO[bytes]], + 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.IO[bytes], 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/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/INSTALLER b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/LICENSE.txt b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/LICENSE.txt new file mode 100644 index 0000000..c3441e6 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/LICENSE.txt @@ -0,0 +1,22 @@ +"wheel" copyright (c) 2012-2014 Daniel Holth and +contributors. + +The MIT License + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/METADATA b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/METADATA new file mode 100644 index 0000000..79b641b --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/METADATA @@ -0,0 +1,69 @@ +Metadata-Version: 2.1 +Name: wheel +Version: 0.37.1 +Summary: A built-package format for Python +Home-page: https://github.com/pypa/wheel +Author: Daniel Holth +Author-email: dholth@fastmail.fm +Maintainer: Alex Grönholm +Maintainer-email: alex.gronholm@nextday.fi +License: MIT +Project-URL: Documentation, https://wheel.readthedocs.io/ +Project-URL: Changelog, https://wheel.readthedocs.io/en/stable/news.html +Project-URL: Issue Tracker, https://github.com/pypa/wheel/issues +Keywords: wheel,packaging +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Topic :: System :: Archiving :: Packaging +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Requires-Python: !=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7 +Provides-Extra: test +Requires-Dist: pytest (>=3.0.0) ; extra == 'test' +Requires-Dist: pytest-cov ; extra == 'test' + +wheel +===== + +This library is the reference implementation of the Python wheel packaging +standard, as defined in `PEP 427`_. + +It has two different roles: + +#. A setuptools_ extension for building wheels that provides the + ``bdist_wheel`` setuptools command +#. A command line tool for working with wheel files + +It should be noted that wheel is **not** intended to be used as a library, and +as such there is no stable, public API. + +.. _PEP 427: https://www.python.org/dev/peps/pep-0427/ +.. _setuptools: https://pypi.org/project/setuptools/ + +Documentation +------------- + +The documentation_ can be found on Read The Docs. + +.. _documentation: https://wheel.readthedocs.io/ + +Code of Conduct +--------------- + +Everyone interacting in the wheel project's codebases, issue trackers, chat +rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_. + +.. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md + + + diff --git a/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/RECORD b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/RECORD new file mode 100644 index 0000000..f5af88f --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/RECORD @@ -0,0 +1,41 @@ +../../../bin/wheel,sha256=GOBdCVDwBgOEPhoQqphEKCZxkOwq-lqkgYFSQSQSaus,240 +wheel-0.37.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +wheel-0.37.1.dist-info/LICENSE.txt,sha256=zKniDGrx_Pv2lAjzd3aShsvuvN7TNhAMm0o_NfvmNeQ,1125 +wheel-0.37.1.dist-info/METADATA,sha256=YmebdXwPQlF98dp9V-Cy4BlE-M-fFM-J9cPVVvlSUi8,2328 +wheel-0.37.1.dist-info/RECORD,, +wheel-0.37.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +wheel-0.37.1.dist-info/WHEEL,sha256=z9j0xAa_JmUKMpmz72K0ZGALSM_n-wQVmGbleXx2VHg,110 +wheel-0.37.1.dist-info/entry_points.txt,sha256=N8HbYFST3yrNQYeB2wXWBEPUhFsEtKNRPaCFGJPyqyc,108 +wheel-0.37.1.dist-info/top_level.txt,sha256=HxSBIbgEstMPe4eFawhA66Mq-QYHMopXVoAncfjb_1c,6 +wheel/__init__.py,sha256=yLOqsEZUPaM3VNKOMxQraLgCCyF8q3k10KY4C1Hi_Lo,23 +wheel/__main__.py,sha256=lF-YLO4hdQmoWuh4eWZd8YL1U95RSdm76sNLBXa0vjE,417 +wheel/__pycache__/__init__.cpython-39.pyc,, +wheel/__pycache__/__main__.cpython-39.pyc,, +wheel/__pycache__/bdist_wheel.cpython-39.pyc,, +wheel/__pycache__/macosx_libfile.cpython-39.pyc,, +wheel/__pycache__/metadata.cpython-39.pyc,, +wheel/__pycache__/pkginfo.cpython-39.pyc,, +wheel/__pycache__/util.cpython-39.pyc,, +wheel/__pycache__/wheelfile.cpython-39.pyc,, +wheel/bdist_wheel.py,sha256=2vfv3g_b8BvZ5Do9bpLEBdu9dQEcvoMQ1flXpKYFJDU,19075 +wheel/cli/__init__.py,sha256=GWSoGUpRabTf8bk3FsNTPrc5Fsr8YOv2dX55iY2W7eY,2572 +wheel/cli/__pycache__/__init__.cpython-39.pyc,, +wheel/cli/__pycache__/convert.cpython-39.pyc,, +wheel/cli/__pycache__/pack.cpython-39.pyc,, +wheel/cli/__pycache__/unpack.cpython-39.pyc,, +wheel/cli/convert.py,sha256=7F4vj23A2OghDDWn9gX2V-_TeXMza1a5nIejmFGEUJM,9498 +wheel/cli/pack.py,sha256=Bfq6KrHicZKrpbktkreeRxIaWwBozUP99JQy2D8-ddY,3364 +wheel/cli/unpack.py,sha256=0VWzT7U_xyenTPwEVavxqvdee93GPvAFHnR3Uu91aRc,673 +wheel/macosx_libfile.py,sha256=Xvp-IrFyRJ9RThIrPxfEpVCDGfljJPWRTZiyopk70hI,15930 +wheel/metadata.py,sha256=b3kPhZn2w2D9wengltX5nGIZQ3ERUOQ5U-K5vHKPdeg,4344 +wheel/pkginfo.py,sha256=GR76kupQzn1x9sKDaXuE6B6FsZ4OkfRtG7pndlXPvQ4,1257 +wheel/util.py,sha256=mnNZkJCi9DHLI_q4lTudoD0mW97h_AoAWl7prNPLXJc,938 +wheel/vendored/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +wheel/vendored/__pycache__/__init__.cpython-39.pyc,, +wheel/vendored/packaging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +wheel/vendored/packaging/__pycache__/__init__.cpython-39.pyc,, +wheel/vendored/packaging/__pycache__/_typing.cpython-39.pyc,, +wheel/vendored/packaging/__pycache__/tags.cpython-39.pyc,, +wheel/vendored/packaging/_typing.py,sha256=x59EhQ57TMT-kTRyLZV25HZvYGGwbucTo6iKh_O0tMw,1812 +wheel/vendored/packaging/tags.py,sha256=noDvA--vVKVKlg49XMuZ5_Epi85jW7gMOKfiGuJ2sqU,29560 +wheel/wheelfile.py,sha256=NyH8VcFLvu7jUwH6r4KoL_U45OKFVpUyJ5Z7gRAI_Lc,7574 diff --git a/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/REQUESTED b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/WHEEL b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/WHEEL new file mode 100644 index 0000000..0b18a28 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/entry_points.txt b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/entry_points.txt new file mode 100644 index 0000000..b27acad --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/entry_points.txt @@ -0,0 +1,6 @@ +[console_scripts] +wheel = wheel.cli:main + +[distutils.commands] +bdist_wheel = wheel.bdist_wheel:bdist_wheel + diff --git a/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/top_level.txt b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/top_level.txt new file mode 100644 index 0000000..2309722 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel-0.37.1.dist-info/top_level.txt @@ -0,0 +1 @@ +wheel diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/__init__.py b/zhdo.space/lib/python3.9/site-packages/wheel/__init__.py new file mode 100644 index 0000000..a4b3835 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel/__init__.py @@ -0,0 +1 @@ +__version__ = '0.37.1' diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/__main__.py b/zhdo.space/lib/python3.9/site-packages/wheel/__main__.py new file mode 100644 index 0000000..b3773a2 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel/__main__.py @@ -0,0 +1,19 @@ +""" +Wheel command line tool (enable python -m wheel syntax) +""" + +import sys + + +def main(): # needed for console script + if __package__ == '': + # To be able to run 'python wheel-0.9.whl/wheel': + import os.path + path = os.path.dirname(os.path.dirname(__file__)) + sys.path[0:0] = [path] + import wheel.cli + sys.exit(wheel.cli.main()) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/__init__.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6511cc546c01fd57d06478bdc5275c6b5546467e GIT binary patch literal 196 zcmYe~<>g`kf;jcMByk}97{oyaj6jY95EpX*i4=w?h7`tN22G|aHUm9lb3H>pO~zZ? z@$qG;Ma7x|3 zenDkPMt+{Lo~3?qW=X0pP)T-TdTOzLc}8k#j(&W6W?p7Ve7s&k}| zYwRm=?UYx@)T7)MKHz@v$e+BACr(aMg7NvyxA_2s{0_xoL|A;pv~N))nGp$+YM6nH zWc-87sETB=r2UzKU99MLG5`=sZ%BUhc#+=LO6jaJZ7VvN>84YeGe&1;suOdqvenwv zrpwOT?Ca>X>&}UXJbl7u(!a#&`KGK* ztIEZ_=*nBuFU!YTn!;jpb-2{cyxb4#U2##`#;Nnae6}3lD>)C1I4@S~{up0onDzw< z0Y(|ThF8E~JPF);Z=U!G=h9T1_rd@FID8NHreQB&9>^({o?W&^-fQ(CjLU|ram*r? GGWY{vl$G-U literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/bdist_wheel.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/bdist_wheel.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed3c059c09e224184d8f7a841e78f012eea146e8 GIT binary patch literal 13141 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 literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/pkginfo.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/wheel/__pycache__/pkginfo.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8199b6fd7a8e598594dd95ec25dd28219d7b4034 GIT binary patch literal 1635 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 IAs$Nq3scYZl>h($ literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/bdist_wheel.py b/zhdo.space/lib/python3.9/site-packages/wheel/bdist_wheel.py new file mode 100644 index 0000000..80e43d0 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel/bdist_wheel.py @@ -0,0 +1,492 @@ +""" +Create a wheel (.whl) distribution. + +A wheel is a built archive format. +""" + +import distutils +import os +import shutil +import stat +import sys +import re +import warnings +from collections import OrderedDict +from distutils.core import Command +from distutils import log as logger +from io import BytesIO +from glob import iglob +from shutil import rmtree +from sysconfig import get_config_var +from zipfile import ZIP_DEFLATED, ZIP_STORED + +import pkg_resources + +from .pkginfo import write_pkg_info +from .macosx_libfile import calculate_macosx_platform_tag +from .metadata import pkginfo_to_metadata +from .vendored.packaging import tags +from .wheelfile import WheelFile +from . import __version__ as wheel_version + +if sys.version_info < (3,): + from email.generator import Generator as BytesGenerator +else: + from email.generator import BytesGenerator + +safe_name = pkg_resources.safe_name +safe_version = pkg_resources.safe_version + +PY_LIMITED_API_PATTERN = r'cp3\d' + + +def python_tag(): + return 'py{}'.format(sys.version_info[0]) + + +def get_platform(archive_root): + """Return our platform name 'win32', 'linux_x86_64'""" + # XXX remove distutils dependency + result = distutils.util.get_platform() + if result.startswith("macosx") and archive_root is not None: + result = calculate_macosx_platform_tag(archive_root, result) + if result == "linux_x86_64" and sys.maxsize == 2147483647: + # pip pull request #3497 + result = "linux_i686" + return result + + +def get_flag(var, fallback, expected=True, warn=True): + """Use a fallback value for determining SOABI flags if the needed config + var is unset or unavailable.""" + val = get_config_var(var) + if val is None: + if warn: + warnings.warn("Config variable '{0}' is unset, Python ABI tag may " + "be incorrect".format(var), RuntimeWarning, 2) + return fallback + return val == expected + + +def get_abi_tag(): + """Return the ABI tag based on SOABI (if available) or emulate SOABI + (CPython 2, PyPy).""" + soabi = get_config_var('SOABI') + impl = tags.interpreter_name() + if not soabi and impl in ('cp', 'pp') and hasattr(sys, 'maxunicode'): + d = '' + m = '' + u = '' + if get_flag('Py_DEBUG', + hasattr(sys, 'gettotalrefcount'), + warn=(impl == 'cp')): + d = 'd' + if get_flag('WITH_PYMALLOC', + impl == 'cp', + warn=(impl == 'cp' and + sys.version_info < (3, 8))) \ + and sys.version_info < (3, 8): + m = 'm' + if get_flag('Py_UNICODE_SIZE', + sys.maxunicode == 0x10ffff, + expected=4, + warn=(impl == 'cp' and + sys.version_info < (3, 3))) \ + and sys.version_info < (3, 3): + u = 'u' + abi = '%s%s%s%s%s' % (impl, tags.interpreter_version(), d, m, u) + elif soabi and soabi.startswith('cpython-'): + abi = 'cp' + soabi.split('-')[1] + elif soabi and soabi.startswith('pypy-'): + # we want something like pypy36-pp73 + abi = '-'.join(soabi.split('-')[:2]) + abi = abi.replace('.', '_').replace('-', '_') + elif soabi: + abi = soabi.replace('.', '_').replace('-', '_') + else: + abi = None + return abi + + +def safer_name(name): + return safe_name(name).replace('-', '_') + + +def safer_version(version): + return safe_version(version).replace('-', '_') + + +def remove_readonly(func, path, excinfo): + print(str(excinfo[1])) + os.chmod(path, stat.S_IWRITE) + func(path) + + +class bdist_wheel(Command): + + description = 'create a wheel distribution' + + supported_compressions = OrderedDict([ + ('stored', ZIP_STORED), + ('deflated', ZIP_DEFLATED) + ]) + + user_options = [('bdist-dir=', 'b', + "temporary directory for creating the distribution"), + ('plat-name=', 'p', + "platform name to embed in generated filenames " + "(default: %s)" % get_platform(None)), + ('keep-temp', 'k', + "keep the pseudo-installation tree around after " + + "creating the distribution archive"), + ('dist-dir=', 'd', + "directory to put final built distributions in"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + ('relative', None, + "build the archive using relative paths " + "(default: false)"), + ('owner=', 'u', + "Owner name used when creating a tar file" + " [default: current user]"), + ('group=', 'g', + "Group name used when creating a tar file" + " [default: current group]"), + ('universal', None, + "make a universal wheel" + " (default: false)"), + ('compression=', None, + "zipfile compression (one of: {})" + " (default: 'deflated')" + .format(', '.join(supported_compressions))), + ('python-tag=', None, + "Python implementation compatibility tag" + " (default: '%s')" % (python_tag())), + ('build-number=', None, + "Build number for this particular version. " + "As specified in PEP-0427, this must start with a digit. " + "[default: None]"), + ('py-limited-api=', None, + "Python tag (cp32|cp33|cpNN) for abi3 wheel tag" + " (default: false)"), + ] + + boolean_options = ['keep-temp', 'skip-build', 'relative', 'universal'] + + def initialize_options(self): + self.bdist_dir = None + self.data_dir = None + self.plat_name = None + self.plat_tag = None + self.format = 'zip' + self.keep_temp = False + self.dist_dir = None + self.egginfo_dir = None + self.root_is_pure = None + self.skip_build = None + self.relative = False + self.owner = None + self.group = None + self.universal = False + self.compression = 'deflated' + self.python_tag = python_tag() + self.build_number = None + self.py_limited_api = False + self.plat_name_supplied = False + + def finalize_options(self): + if self.bdist_dir is None: + bdist_base = self.get_finalized_command('bdist').bdist_base + self.bdist_dir = os.path.join(bdist_base, 'wheel') + + self.data_dir = self.wheel_dist_name + '.data' + self.plat_name_supplied = self.plat_name is not None + + try: + self.compression = self.supported_compressions[self.compression] + except KeyError: + raise ValueError('Unsupported compression: {}'.format(self.compression)) + + need_options = ('dist_dir', 'plat_name', 'skip_build') + + self.set_undefined_options('bdist', + *zip(need_options, need_options)) + + self.root_is_pure = not (self.distribution.has_ext_modules() + or self.distribution.has_c_libraries()) + + if self.py_limited_api and not re.match(PY_LIMITED_API_PATTERN, self.py_limited_api): + raise ValueError("py-limited-api must match '%s'" % PY_LIMITED_API_PATTERN) + + # Support legacy [wheel] section for setting universal + wheel = self.distribution.get_option_dict('wheel') + if 'universal' in wheel: + # please don't define this in your global configs + logger.warn('The [wheel] section is deprecated. Use [bdist_wheel] instead.') + val = wheel['universal'][1].strip() + if val.lower() in ('1', 'true', 'yes'): + self.universal = True + + if self.build_number is not None and not self.build_number[:1].isdigit(): + raise ValueError("Build tag (build-number) must start with a digit.") + + @property + def wheel_dist_name(self): + """Return distribution full name with - replaced with _""" + components = (safer_name(self.distribution.get_name()), + safer_version(self.distribution.get_version())) + if self.build_number: + components += (self.build_number,) + return '-'.join(components) + + def get_tag(self): + # bdist sets self.plat_name if unset, we should only use it for purepy + # wheels if the user supplied it. + if self.plat_name_supplied: + plat_name = self.plat_name + elif self.root_is_pure: + plat_name = 'any' + else: + # macosx contains system version in platform name so need special handle + if self.plat_name and not self.plat_name.startswith("macosx"): + plat_name = self.plat_name + else: + # on macosx always limit the platform name to comply with any + # c-extension modules in bdist_dir, since the user can specify + # a higher MACOSX_DEPLOYMENT_TARGET via tools like CMake + + # on other platforms, and on macosx if there are no c-extension + # modules, use the default platform name. + plat_name = get_platform(self.bdist_dir) + + if plat_name in ('linux-x86_64', 'linux_x86_64') and sys.maxsize == 2147483647: + plat_name = 'linux_i686' + + plat_name = plat_name.lower().replace('-', '_').replace('.', '_') + + if self.root_is_pure: + if self.universal: + impl = 'py2.py3' + else: + impl = self.python_tag + tag = (impl, 'none', plat_name) + else: + impl_name = tags.interpreter_name() + impl_ver = tags.interpreter_version() + impl = impl_name + impl_ver + # We don't work on CPython 3.1, 3.0. + if self.py_limited_api and (impl_name + impl_ver).startswith('cp3'): + impl = self.py_limited_api + abi_tag = 'abi3' + else: + abi_tag = str(get_abi_tag()).lower() + tag = (impl, abi_tag, plat_name) + # issue gh-374: allow overriding plat_name + supported_tags = [(t.interpreter, t.abi, plat_name) + for t in tags.sys_tags()] + assert tag in supported_tags, "would build wheel with unsupported tag {}".format(tag) + return tag + + def run(self): + build_scripts = self.reinitialize_command('build_scripts') + build_scripts.executable = 'python' + build_scripts.force = True + + build_ext = self.reinitialize_command('build_ext') + build_ext.inplace = False + + if not self.skip_build: + self.run_command('build') + + install = self.reinitialize_command('install', + reinit_subcommands=True) + install.root = self.bdist_dir + install.compile = False + install.skip_build = self.skip_build + install.warn_dir = False + + # A wheel without setuptools scripts is more cross-platform. + # Use the (undocumented) `no_ep` option to setuptools' + # install_scripts command to avoid creating entry point scripts. + install_scripts = self.reinitialize_command('install_scripts') + install_scripts.no_ep = True + + # Use a custom scheme for the archive, because we have to decide + # at installation time which scheme to use. + for key in ('headers', 'scripts', 'data', 'purelib', 'platlib'): + setattr(install, + 'install_' + key, + os.path.join(self.data_dir, key)) + + basedir_observed = '' + + if os.name == 'nt': + # win32 barfs if any of these are ''; could be '.'? + # (distutils.command.install:change_roots bug) + basedir_observed = os.path.normpath(os.path.join(self.data_dir, '..')) + self.install_libbase = self.install_lib = basedir_observed + + setattr(install, + 'install_purelib' if self.root_is_pure else 'install_platlib', + basedir_observed) + + logger.info("installing to %s", self.bdist_dir) + + self.run_command('install') + + impl_tag, abi_tag, plat_tag = self.get_tag() + archive_basename = "{}-{}-{}-{}".format(self.wheel_dist_name, impl_tag, abi_tag, plat_tag) + if not self.relative: + archive_root = self.bdist_dir + else: + archive_root = os.path.join( + self.bdist_dir, + self._ensure_relative(install.install_base)) + + self.set_undefined_options('install_egg_info', ('target', 'egginfo_dir')) + distinfo_dirname = '{}-{}.dist-info'.format( + safer_name(self.distribution.get_name()), + safer_version(self.distribution.get_version())) + distinfo_dir = os.path.join(self.bdist_dir, distinfo_dirname) + self.egg2dist(self.egginfo_dir, distinfo_dir) + + self.write_wheelfile(distinfo_dir) + + # Make the archive + if not os.path.exists(self.dist_dir): + os.makedirs(self.dist_dir) + + wheel_path = os.path.join(self.dist_dir, archive_basename + '.whl') + with WheelFile(wheel_path, 'w', self.compression) as wf: + wf.write_files(archive_root) + + # Add to 'Distribution.dist_files' so that the "upload" command works + getattr(self.distribution, 'dist_files', []).append( + ('bdist_wheel', + '{}.{}'.format(*sys.version_info[:2]), # like 3.7 + wheel_path)) + + if not self.keep_temp: + logger.info('removing %s', self.bdist_dir) + if not self.dry_run: + rmtree(self.bdist_dir, onerror=remove_readonly) + + def write_wheelfile(self, wheelfile_base, generator='bdist_wheel (' + wheel_version + ')'): + from email.message import Message + + # Workaround for Python 2.7 for when "generator" is unicode + if sys.version_info < (3,) and not isinstance(generator, str): + generator = generator.encode('utf-8') + + msg = Message() + msg['Wheel-Version'] = '1.0' # of the spec + msg['Generator'] = generator + msg['Root-Is-Purelib'] = str(self.root_is_pure).lower() + if self.build_number is not None: + msg['Build'] = self.build_number + + # Doesn't work for bdist_wininst + impl_tag, abi_tag, plat_tag = self.get_tag() + for impl in impl_tag.split('.'): + for abi in abi_tag.split('.'): + for plat in plat_tag.split('.'): + msg['Tag'] = '-'.join((impl, abi, plat)) + + wheelfile_path = os.path.join(wheelfile_base, 'WHEEL') + logger.info('creating %s', wheelfile_path) + buffer = BytesIO() + BytesGenerator(buffer, maxheaderlen=0).flatten(msg) + with open(wheelfile_path, 'wb') as f: + f.write(buffer.getvalue().replace(b'\r\n', b'\r')) + + def _ensure_relative(self, path): + # copied from dir_util, deleted + drive, path = os.path.splitdrive(path) + if path[0:1] == os.sep: + path = drive + path[1:] + return path + + @property + def license_paths(self): + metadata = self.distribution.get_option_dict('metadata') + files = set() + patterns = sorted({ + option for option in metadata.get('license_files', ('', ''))[1].split() + }) + + if 'license_file' in metadata: + warnings.warn('The "license_file" option is deprecated. Use ' + '"license_files" instead.', DeprecationWarning) + files.add(metadata['license_file'][1]) + + if 'license_file' not in metadata and 'license_files' not in metadata: + patterns = ('LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*') + + for pattern in patterns: + for path in iglob(pattern): + if path.endswith('~'): + logger.debug('ignoring license file "%s" as it looks like a backup', path) + continue + + if path not in files and os.path.isfile(path): + logger.info('adding license file "%s" (matched pattern "%s")', path, pattern) + files.add(path) + + return files + + def egg2dist(self, egginfo_path, distinfo_path): + """Convert an .egg-info directory into a .dist-info directory""" + def adios(p): + """Appropriately delete directory, file or link.""" + if os.path.exists(p) and not os.path.islink(p) and os.path.isdir(p): + shutil.rmtree(p) + elif os.path.exists(p): + os.unlink(p) + + adios(distinfo_path) + + if not os.path.exists(egginfo_path): + # There is no egg-info. This is probably because the egg-info + # file/directory is not named matching the distribution name used + # to name the archive file. Check for this case and report + # accordingly. + import glob + pat = os.path.join(os.path.dirname(egginfo_path), '*.egg-info') + possible = glob.glob(pat) + err = "Egg metadata expected at %s but not found" % (egginfo_path,) + if possible: + alt = os.path.basename(possible[0]) + err += " (%s found - possible misnamed archive file?)" % (alt,) + + raise ValueError(err) + + if os.path.isfile(egginfo_path): + # .egg-info is a single file + pkginfo_path = egginfo_path + pkg_info = pkginfo_to_metadata(egginfo_path, egginfo_path) + os.mkdir(distinfo_path) + else: + # .egg-info is a directory + pkginfo_path = os.path.join(egginfo_path, 'PKG-INFO') + pkg_info = pkginfo_to_metadata(egginfo_path, pkginfo_path) + + # ignore common egg metadata that is useless to wheel + shutil.copytree(egginfo_path, distinfo_path, + ignore=lambda x, y: {'PKG-INFO', 'requires.txt', 'SOURCES.txt', + 'not-zip-safe'} + ) + + # delete dependency_links if it is only whitespace + dependency_links_path = os.path.join(distinfo_path, 'dependency_links.txt') + with open(dependency_links_path, 'r') as dependency_links_file: + dependency_links = dependency_links_file.read().strip() + if not dependency_links: + adios(dependency_links_path) + + write_pkg_info(os.path.join(distinfo_path, 'METADATA'), pkg_info) + + for license_path in self.license_paths: + filename = os.path.basename(license_path) + shutil.copy(license_path, os.path.join(distinfo_path, filename)) + + adios(egginfo_path) diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/cli/__init__.py b/zhdo.space/lib/python3.9/site-packages/wheel/cli/__init__.py new file mode 100644 index 0000000..95740bf --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel/cli/__init__.py @@ -0,0 +1,88 @@ +""" +Wheel command-line utility. +""" + +from __future__ import print_function + +import argparse +import os +import sys + + +def require_pkgresources(name): + try: + import pkg_resources # noqa: F401 + except ImportError: + raise RuntimeError("'{0}' needs pkg_resources (part of setuptools).".format(name)) + + +class WheelError(Exception): + pass + + +def unpack_f(args): + from .unpack import unpack + unpack(args.wheelfile, args.dest) + + +def pack_f(args): + from .pack import pack + pack(args.directory, args.dest_dir, args.build_number) + + +def convert_f(args): + from .convert import convert + convert(args.files, args.dest_dir, args.verbose) + + +def version_f(args): + from .. import __version__ + print("wheel %s" % __version__) + + +def parser(): + p = argparse.ArgumentParser() + s = p.add_subparsers(help="commands") + + unpack_parser = s.add_parser('unpack', help='Unpack wheel') + unpack_parser.add_argument('--dest', '-d', help='Destination directory', + default='.') + unpack_parser.add_argument('wheelfile', help='Wheel file') + unpack_parser.set_defaults(func=unpack_f) + + repack_parser = s.add_parser('pack', help='Repack wheel') + repack_parser.add_argument('directory', help='Root directory of the unpacked wheel') + repack_parser.add_argument('--dest-dir', '-d', default=os.path.curdir, + help="Directory to store the wheel (default %(default)s)") + repack_parser.add_argument('--build-number', help="Build tag to use in the wheel name") + repack_parser.set_defaults(func=pack_f) + + convert_parser = s.add_parser('convert', help='Convert egg or wininst to wheel') + convert_parser.add_argument('files', nargs='*', help='Files to convert') + convert_parser.add_argument('--dest-dir', '-d', default=os.path.curdir, + help="Directory to store wheels (default %(default)s)") + convert_parser.add_argument('--verbose', '-v', action='store_true') + convert_parser.set_defaults(func=convert_f) + + version_parser = s.add_parser('version', help='Print version and exit') + version_parser.set_defaults(func=version_f) + + help_parser = s.add_parser('help', help='Show this help') + help_parser.set_defaults(func=lambda args: p.print_help()) + + return p + + +def main(): + p = parser() + args = p.parse_args() + if not hasattr(args, 'func'): + p.print_help() + else: + try: + args.func(args) + return 0 + except WheelError as e: + print(e, file=sys.stderr) + + return 1 diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/cli/__pycache__/__init__.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/wheel/cli/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3f4de7f12d4ac79b235584568e6715803e657b6 GIT binary patch literal 3080 zcmb_e&5zVJ6t|sBCNrBEmaGmycvCcYoT1Ns z-h%NKZ}SCc+dSYMXcu^wpMW;ti~JAb;a7QUO#a;fi2nM)HqDl(l+MMZhzTux)%W5&(msgMqw z_=-rx{?FQAl2658vxu|7S}vaq$_dX`)GQu}qun%FAI!G&B+ouy`D&mNE&9OnB;F8e z@Dv3(7^TS|ijpkRQM5AKGD}kYTqIIN0Q2B70UW9DTtXQQ;FoAABOEyTp-ApPQOGaI z5TrU}oPxZVsq|(qw%T)yA4PblC^GFRn&!Mnu^&Xy&qbV8GxnlKsupZ27oa+YM_4UV zOTVRE6qMEOhtL7tvXo3gyOhl7oNQuYJ7}_%CSN0LFdDDOP&PeBF2aCmS^12UR2Y{F zWz`VN4P|GK!7_feHX6SVOBFf_K`AXk`xZK!wdk%u=iTT4p|j&0Ae1M76A-!h;n1GRz*rya?1=Fb{N&SE{8-QRm>p&YYeh zJJ7cpcUNDd@qj!Rq6lCph!9a!`c~iJH3im5zwjIh8TRX*BSo4 z-OHIfz;~8^z|ZmXyI_)*KHTj>y&G~}qi>8RWhCD9`ob zo*3fw1d@=2B6tm^U4iMt+2zf9`>q=5JXGMb!Y-*S?s|~B z{1#mk$M=1fnMP*A9ZIVlyyFIT2gq~pf?u}!{o2Dp9lw~iy>z5yf%5fYo0e@5K<_Kh zJj8q**3J|{Vh_c$MAx@}JjtKJ^%51L=HKvq4BhC=HYH$!dO=>2Jv17+3J0~TcK|Ny zQ5y_jQA1~y7h^s#{;f2guJicz1EBtfLdvs{xRsDAx6*tRr|LFzDwbZy_#hHHZMt8} zjbbV?{m^ooZp?Y4iuG!-GHs+Q!UWidm6qQG@F0k4p(&dp49gV;cRexQsE}YX5<{`X zKqoPj^gKh=uu~_QYS&>$TGOl#8Fu%hWj)>94^1__fKsTLD*>$F_Erjz4e-jJ!hre$ zDnfl4ur6&=_OAym_VGWY7HewJ&f)wLleb{y8&MCV9ljLqLQ$JgX|h8w&SC7^rkc$u zr#nntfe~j99$eYIa&b;yx^ub*QEiQI_L#tftg*!@*@l=`p3~l(VI<=Y#=tf5BLwwr z_8ZIEReOWL6U_w!XspU*IMKe-tWSf5SBbP`fr4@1rBN@+G$*l&wU)AvOYAy)X-G^w z#!*|!cuI32CAIDrOds5qVv+-aO--@}~3)K91ff^5?^V^Dh_va3v@EP5wQGm3aV zs@^~2LKpDjiX@t{#3!lz6018{q5Mqi{QE$4R`77Mp9Z#~gCZA=p2lP7CB@AlPFLh5_gIsyQ4=-e5V? z^xpG@$C072K#>zqYiP>Cb6;}P3)?8x?Y!Uf7tFa~I8*G`aAm3#A zU9G$1!;lB9!J`8nq{)zXg7oBrl84{UjrZS*{eJLv|x^}d!??rydBl&^G;8VuisG3^&5@g;NVJ!_@Dm~DhGt*8XPo{yc zzF)WGQg;|dM6#6*2ZJaKm~_vYcmbrOa}Wp`K(bGRsQYV;FQWak`+L2lAM70t{dn&| z!XNFO^jOkJ2Yx4*FGgW|Z*VMnN&H&ln|o;}f?W)G(D`+{gzO0@hL%HLyv%nCk6?1YzT8=Wd=%SW~Mu$!1Ret z^(XpI^~{_&r`p&O?qQJ`%>21NE~vRBn#+G8%99F}ez85aGka3a3a7fRJ-|U(_+EL>li4ZL&bKzN>xk?$}ZE7Bek#PK~iUrS5|Ie~H>;DRV*70G)qE zZ8^*P7qbG5&f7DKSzFq;m=*b-vf^Zg6_|Z$Sk!`^w=|^AmNxh^b5&pQ)IeTh$j7Cu z#N0>b$2z~v%2^R6t^Jd+rEO@j!K&kOJ`<{_jVoCNqi%^+u{K#h)t>0%YFrT;=e4Yo zRa=``5$P6NK)RjJ{#YLjn2Y)aqLBWJ>br<><*d{-(f-_Y{{^;qXm_;`{QgS+R~_7e z%H-0lw{~h|3$){`diZ>{z?RtZ&rxG5hqj_+oXs3B3U4|~&lXP&w)(`t`P8!7o5sp$fh?GVI&KkWN>_4x|9hXfGiIN5j>A_ zS)5E(R=$g=JZxh^5-U@d6`mxb6{fAh5ImQ1w?w{8E@QUH{m9G@7H4he{zJMXMv|{w z9C0|a{K}!7aPn8OoVQX#DsA2;?&?cTn%2q%$O2qcv?Z4Yktq2~G*b;Bc}kOdP0Wzy z03tV2-r?&Q!nbIg>9<3xRdec9kd z_bI1Io|SGAHG@Zm!9e5Ix{1^A`FJsuD%YZ0EekfOlF?y56!VTw#J3b zN^fC=m1(mPaImaEZU()D3GPfa+Qw)nv-nRlXF?84N6E$rXJS)a0(aoV7As;5&2iKm z7jxj`(*JyB1%v-CGbRozDW^`QGD>b{!kHE`hgJUF!aZ8`1-5rHS6Z(h2%q`F_qsgk zD-)+9P8%f^4NOO+p6CVM>$Aa7q<-qfLBIm$?a+j49xOS9=3euZN#;dz19e4NQ6nN@ zoRXyke72V7$4t>DI$qLMWoVP~2p%*e=)mxgy`bL?7%dpaGip;~^mf87$Q;+FY~RB| zpg^j1zD&>0w~?Fsn{Vbjq#%kG-Ua_VyNdVv&aPsd0wKjjK9Y$3AKd@{WE({7jCLdV zFv#iMML2@JhVcRTO1wA`!IY<08{S`8EQHh(;jy3_#-Ruw2MzDr@f=qjKla*z$CaHj zB_`~T1Uy2>;|&7dg*2mMZxlq42Z3PxY)=jEZsPS5PV=MCZ^PRw%}9I6Fq#nq`C*Dv zfVIW}gys#BGz~Ghp_aRz^L{3}c?!hYfCt@xbIivvoS!;zI8&f@(DAXv8TZhdH1Ikk zEjUO&Jm`sBS-!&K0*3I7omn{D^Y?0s2Iq^DuriH5n!s%L`F4mmp4$`q#_LRowMSsa|SUMsP+HSgA!TIOJKa=}c=)dz5#ZX)ur$V612sD81fvMlEHN&BCY! zhG``6^vwN_kjLjK;ul&A5eY5v4`3sG8Hx4+@J}8PSTza@%!*ON6_1i*p+tcK^_L9( zLyUgvx+i(hFw$=oM#41@l=89uiyw~-rU4%r6XR3^YFQmyOwX*x8b_2rCY1Blqitad z>#zXqggKe{#25nx0~O)=RdY6RbvuXdq(~P&-)Gj?#=PFqerEH>gjqsd(XormUX_3u z3hTfy47dh)=|CHonXP!p>HWu)UWuM1PK}4gxH7J0l}QuKx{R_cEE_A07)z| z1VHGymet1Q(I>2u)gTS(sZrRW!k?w_^3f+^>2R4<*#eN`3S_a8tz_W#X^f~ah@Ogh z48j)2t67275GJi5U)s`ur2dU9PgdCqTLp$&Wowj=*E1V@{Dv)~w9b|ln)`jWhW>T7 zf&MkNHd#a1vzD!9>sUhV%l0yUo_cDF?=2 zlP#nE94Hv+>#Fb4l(LET=amMmWh)FwaGj*Tm2FPEv)0T6hTBpYZu9VkY>RENZNhNV zemx_8x5edbn_W;%||NCc5(ltIE!2EHJ$f=@a=m) zxbyBU>5w-<h&;aff3y}Co*B0X`hrVYCG_de72xC7%jDa{D(0rj=7 zkN7H@IX!xu$N7Als>&5zpc0uC|2s;aLvm6fs<^9FJSD4BE6xEP_h{HB1`)qaxb}q!P52z zgCNF(5t7`G-KDAIK=><^>`_9#jlW6>fdGZg_#0FrT)@9h$u}tZCM9oDa{gNLH&lI# z5&~EJTa;X<m4N0qTTS@RCEy2QVoC_05)wFXDF%Z(76y) za{3eu^HiFTf@39*rUJS&qv<3OBhfXTI2ciZKcIEgsk}?2Ta?TI8vhcN{R(d_l6ZP=)0jj^mm;NIXO*z(zPKe7kmf>W9#;A<1WVk?Lu0^i7qAz0%jUx=^ zs;>l8R#G#lWf{HKObew;7G|3zHRmbxrchkPSSIvl5Y_{FBW^k-aWegp;OSH7O`srv z-=2^IBM06dn}VD)Jwe^W^OkW)k6>^P47iM$j|~2XD2xlSB?yBV{JwCQHF0SK(GbPM z5;1H#MnCop1++Qg^=^&f2>!TADX+50C|1!pN9fL)2)k}R^M6B|zzjfN+U_r71R z@FIBRw1aaEm#$J|dRHKHsx}FA;0W&c4jKTlkAc?l(vS?H?%imZ_UbkYgyK2rmvpdb zJ4q1(;2>pj78FT~7<%SRr8DL7b4*PslF-!IRe+Ig!@?OY;G_s|^AY;$Thd9=hSCtS zN@?&QSMvn5+@8pcrBYoLo##&+7CnLIdnMay7L|x*j}gi>sW%xV6ymBsz?P(Q|K{Jn z``+D~DrU*;P|1bvawQza*4(C)%96H9_pSVi^=*1{R&UKv$=P52bWqW2hHY7&TTZR! KzTw_>n|}dSxuM|z literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/cli/__pycache__/pack.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/wheel/cli/__pycache__/pack.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fbf254e9ed2b80df2a3ef678b96ca42093466bc1 GIT binary patch literal 2937 zcmbtW&2JmW6`z^iC6}L)DOn$OQY;Dw743?2kRnA@K`vZbjnPCYEC)sxN{AI_NUpWq zWoCv^Mep`d31}`w(*6a@qk*F5{4I;#dh)G6Z@#4OEh$Ut7YbwvzMc8aoA)vAW5=u2 z$^@Rze(>9)J2gW7hLfw00h6D>UmXJBgwucwsY@x2S-@N)f19qEzb)5-w-FSEMYovq zn1MYkxg|=3nU=XVrEVo36<}25MQ)!Hx5n84X_j7r2GXQieI)%*cY5QntNke42dMmP zAVly;%1FYjl+X73Kuq5MY~#VNwnJ|yz7TTfV!YG3_n^6nGei%0>+XYQ^RUHzr8oVs z7u`_{pz7h+5BQd|amWu(?l$jq(bbD*83s1|5mV=kkl&LY<&?8?Ta%Q2Nv3p{oYBP4 zEH=(4H;zsDBW-XqHF52X{*H!?*id_bS(jLB@WMJtOl_rw*qqX|$cs~&Slmtunmo7D z(w8JQd1-1SMO}`IXY{L4V)sc>itSzU>26Yv%V~v|r&RtqE~QnN)p%tJ`qxQXpMqve zK0nWSs=$MzYwJk?R!i!yU{x(O(E_ye8R51`Omb#W5-z?=)ZgzDn*V+cG-li$)32$t zV-~Wwkgzw%H!%ZzBer-wW~=1KB(Y-PI5q&Ct?luJn5~d>fiF&J$oP$0bA^Jd5SjK=}q7Uo|DXzoW;(KBK1~2*sMC`^a zS~2BoaE?}dW6Gv1Y3S9s!PmjJ_md^P#&5w|19sl#Z~cK$qSv3_N^j@(FQso`p8N;< znF_DjzsBD_13qp;iG0s{NC|l&Mqc;W@tlzqU-;2j1*gt9L`-n!1PjICz7$;@$x{a^ zDFW6|oXnScP&Tb{*@5TjKsc90(SG*9qemY)xb6(cN;};s)Se$YQ7D{9I>Sf`M|*wc zsL0U+PXj?f_Jz*H%~a?6u^^qU7dl76;X(^J^h3etYPUw7^oEx1vwjB^t^GPl><(rb=|R)BGi{G&0Jg;PVvnH#hsV>61>%YAbk>( zPd5?@A*LzIsR3n4A;eUg+Dt7N!ziYIWS^S{<>S-t`jGxK@mhgo&^ z@xjy1ybw6Xh@Fn!JH=&Xi=ze|B9z;XYem?fX_OnPHw2GTpb4fQG0Z%2T}N5>nCmHYq5z5;Pr)S=W%Fv1HX+>Yjm2Gw*zQ>-Do)4Swk;P zAU1Wrovh^?+d>}#t}uwXnpu|q6q75AAg~w7HBZDV zNscOB)6Gd`F7O>yD`%Fcy1xGpuz^erd35jJG692d0DpB0$N)2;ky(2FFLl*B8HtRQ0bWi%eiA_64@ z%xEOStgN6=#0l3H+yC6!tE%_TF`se%Q~qp{AcUNBYzx017Wusf>e zvc&sGX7hPJ%c@6s7wLrK;gOJT9WN>!yr^KaQ(5iW+^u3}ci?8Dp!>Nu#czNc&aiV$ z#zNi&a($h=Ezw?PVmW1I0KGV?NHGeasSKgA+{P7V?D~jR!I;jRiMy6R90kfPdPhDg z&PuRZ1uGBas`vTyI04VV>Zm6holt-?B@HY-pY5S!jL8WexuH&$R3dG9j$0JJpgS-At3 zNIjOK(~+2{Sus*AG;fwrObYoPz-}owyagRIPb+tJc95m;DaC-zf?LG?iL*T0eh3?L iJy*&rFSOiOdwUr1aUgcE+bM*q%m!<1@EJWR8~+5J^$_a- literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/cli/__pycache__/unpack.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/wheel/cli/__pycache__/unpack.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f2d15d322113982ceea369c3eb12ac1097adf7d GIT binary patch literal 965 zcmYjQ&2G~`5Z+z?ByrPHfdm})Mk7%hgoH$d5E6(BQbB^M!iPq#cT+oc>}YpQNRx0W zSHvqMM_y^Kocaog12axQooFXBv-9)K%sScK4G7TbgRf_6M#wKzZjuAaOE~%|FhK+@ z$e6~IqRa{wJI%ivyTTD};f?*+hr71$Me7@lTY`Ncz0Nhnk{-2t6P1@{Fs#eek310Ca9+XD2AClWaz%fwM()a6(1o*R zOV{{3i~K79oD`1=G0a`;!+ zrUwnQF8>^tlO(<137;a=FbFtM1DmH+X=G{mG%pH%CVAbsO2JLV=R#_;jOJxBmdnHW zXQ`GCF@=(RV{7u{nwv~=tdN{bj?O$O1#kR$ZZwBL4HMhe?N1VwjKSYzeg3hDG#Qq| zEL(txZ|jE``usKUyi9QLT;xiorcyJ0AmlKq3xm;VtrRx$|F#!4@N5ea0ffstn=$0& zIr#Vad>MwJ#SJ>L6i1f5d)wbAF^MBN43 z@8c+|#xfe!Ng16~>LR+#L=|e7vAii3`B^lXnXD?GgwGMrn~po0W!> zne{hf2TJHYV5Ae!F5RQIX+RH{x(}8fRrqXsZ5s^Wt(#iO!9d}wwyjEs*u2^SP3;4V mJ53cFQ!}_GL({.+?)-(?P.+?) + (-(?Ppy\d\.\d+) + (-(?P.+?))? + )?.egg$''', re.VERBOSE) + + +class _bdist_wheel_tag(bdist_wheel): + # allow the client to override the default generated wheel tag + # The default bdist_wheel implementation uses python and abi tags + # of the running python process. This is not suitable for + # generating/repackaging prebuild binaries. + + full_tag_supplied = False + full_tag = None # None or a (pytag, soabitag, plattag) triple + + def get_tag(self): + if self.full_tag_supplied and self.full_tag is not None: + return self.full_tag + else: + return bdist_wheel.get_tag(self) + + +def egg2wheel(egg_path, dest_dir): + filename = os.path.basename(egg_path) + match = egg_info_re.match(filename) + if not match: + raise WheelError('Invalid egg file name: {}'.format(filename)) + + egg_info = match.groupdict() + dir = tempfile.mkdtemp(suffix="_e2w") + if os.path.isfile(egg_path): + # assume we have a bdist_egg otherwise + with zipfile.ZipFile(egg_path) as egg: + egg.extractall(dir) + else: + # support buildout-style installed eggs directories + for pth in os.listdir(egg_path): + src = os.path.join(egg_path, pth) + if os.path.isfile(src): + shutil.copy2(src, dir) + else: + shutil.copytree(src, os.path.join(dir, pth)) + + pyver = egg_info['pyver'] + if pyver: + pyver = egg_info['pyver'] = pyver.replace('.', '') + + arch = (egg_info['arch'] or 'any').replace('.', '_').replace('-', '_') + + # assume all binary eggs are for CPython + abi = 'cp' + pyver[2:] if arch != 'any' else 'none' + + root_is_purelib = egg_info['arch'] is None + if root_is_purelib: + bw = bdist_wheel(dist.Distribution()) + else: + bw = _bdist_wheel_tag(dist.Distribution()) + + bw.root_is_pure = root_is_purelib + bw.python_tag = pyver + bw.plat_name_supplied = True + bw.plat_name = egg_info['arch'] or 'any' + if not root_is_purelib: + bw.full_tag_supplied = True + bw.full_tag = (pyver, abi, arch) + + dist_info_dir = os.path.join(dir, '{name}-{ver}.dist-info'.format(**egg_info)) + bw.egg2dist(os.path.join(dir, 'EGG-INFO'), dist_info_dir) + bw.write_wheelfile(dist_info_dir, generator='egg2wheel') + wheel_name = '{name}-{ver}-{pyver}-{}-{}.whl'.format(abi, arch, **egg_info) + with WheelFile(os.path.join(dest_dir, wheel_name), 'w') as wf: + wf.write_files(dir) + + shutil.rmtree(dir) + + +def parse_wininst_info(wininfo_name, egginfo_name): + """Extract metadata from filenames. + + Extracts the 4 metadataitems needed (name, version, pyversion, arch) from + the installer filename and the name of the egg-info directory embedded in + the zipfile (if any). + + The egginfo filename has the format:: + + name-ver(-pyver)(-arch).egg-info + + The installer filename has the format:: + + name-ver.arch(-pyver).exe + + Some things to note: + + 1. The installer filename is not definitive. An installer can be renamed + and work perfectly well as an installer. So more reliable data should + be used whenever possible. + 2. The egg-info data should be preferred for the name and version, because + these come straight from the distutils metadata, and are mandatory. + 3. The pyver from the egg-info data should be ignored, as it is + constructed from the version of Python used to build the installer, + which is irrelevant - the installer filename is correct here (even to + the point that when it's not there, any version is implied). + 4. The architecture must be taken from the installer filename, as it is + not included in the egg-info data. + 5. Architecture-neutral installers still have an architecture because the + installer format itself (being executable) is architecture-specific. We + should therefore ignore the architecture if the content is pure-python. + """ + + egginfo = None + if egginfo_name: + egginfo = egg_info_re.search(egginfo_name) + if not egginfo: + raise ValueError("Egg info filename %s is not valid" % (egginfo_name,)) + + # Parse the wininst filename + # 1. Distribution name (up to the first '-') + w_name, sep, rest = wininfo_name.partition('-') + if not sep: + raise ValueError("Installer filename %s is not valid" % (wininfo_name,)) + + # Strip '.exe' + rest = rest[:-4] + # 2. Python version (from the last '-', must start with 'py') + rest2, sep, w_pyver = rest.rpartition('-') + if sep and w_pyver.startswith('py'): + rest = rest2 + w_pyver = w_pyver.replace('.', '') + else: + # Not version specific - use py2.py3. While it is possible that + # pure-Python code is not compatible with both Python 2 and 3, there + # is no way of knowing from the wininst format, so we assume the best + # here (the user can always manually rename the wheel to be more + # restrictive if needed). + w_pyver = 'py2.py3' + # 3. Version and architecture + w_ver, sep, w_arch = rest.rpartition('.') + if not sep: + raise ValueError("Installer filename %s is not valid" % (wininfo_name,)) + + if egginfo: + w_name = egginfo.group('name') + w_ver = egginfo.group('ver') + + return {'name': w_name, 'ver': w_ver, 'arch': w_arch, 'pyver': w_pyver} + + +def wininst2wheel(path, dest_dir): + with zipfile.ZipFile(path) as bdw: + # Search for egg-info in the archive + egginfo_name = None + for filename in bdw.namelist(): + if '.egg-info' in filename: + egginfo_name = filename + break + + info = parse_wininst_info(os.path.basename(path), egginfo_name) + + root_is_purelib = True + for zipinfo in bdw.infolist(): + if zipinfo.filename.startswith('PLATLIB'): + root_is_purelib = False + break + if root_is_purelib: + paths = {'purelib': ''} + else: + paths = {'platlib': ''} + + dist_info = "%(name)s-%(ver)s" % info + datadir = "%s.data/" % dist_info + + # rewrite paths to trick ZipFile into extracting an egg + # XXX grab wininst .ini - between .exe, padding, and first zip file. + members = [] + egginfo_name = '' + for zipinfo in bdw.infolist(): + key, basename = zipinfo.filename.split('/', 1) + key = key.lower() + basepath = paths.get(key, None) + if basepath is None: + basepath = datadir + key.lower() + '/' + oldname = zipinfo.filename + newname = basepath + basename + zipinfo.filename = newname + del bdw.NameToInfo[oldname] + bdw.NameToInfo[newname] = zipinfo + # Collect member names, but omit '' (from an entry like "PLATLIB/" + if newname: + members.append(newname) + # Remember egg-info name for the egg2dist call below + if not egginfo_name: + if newname.endswith('.egg-info'): + egginfo_name = newname + elif '.egg-info/' in newname: + egginfo_name, sep, _ = newname.rpartition('/') + dir = tempfile.mkdtemp(suffix="_b2w") + bdw.extractall(dir, members) + + # egg2wheel + abi = 'none' + pyver = info['pyver'] + arch = (info['arch'] or 'any').replace('.', '_').replace('-', '_') + # Wininst installers always have arch even if they are not + # architecture-specific (because the format itself is). + # So, assume the content is architecture-neutral if root is purelib. + if root_is_purelib: + arch = 'any' + # If the installer is architecture-specific, it's almost certainly also + # CPython-specific. + if arch != 'any': + pyver = pyver.replace('py', 'cp') + wheel_name = '-'.join((dist_info, pyver, abi, arch)) + if root_is_purelib: + bw = bdist_wheel(dist.Distribution()) + else: + bw = _bdist_wheel_tag(dist.Distribution()) + + bw.root_is_pure = root_is_purelib + bw.python_tag = pyver + bw.plat_name_supplied = True + bw.plat_name = info['arch'] or 'any' + + if not root_is_purelib: + bw.full_tag_supplied = True + bw.full_tag = (pyver, abi, arch) + + dist_info_dir = os.path.join(dir, '%s.dist-info' % dist_info) + bw.egg2dist(os.path.join(dir, egginfo_name), dist_info_dir) + bw.write_wheelfile(dist_info_dir, generator='wininst2wheel') + + wheel_path = os.path.join(dest_dir, wheel_name) + with WheelFile(wheel_path, 'w') as wf: + wf.write_files(dir) + + shutil.rmtree(dir) + + +def convert(files, dest_dir, verbose): + # Only support wheel convert if pkg_resources is present + require_pkgresources('wheel convert') + + for pat in files: + for installer in iglob(pat): + if os.path.splitext(installer)[1] == '.egg': + conv = egg2wheel + else: + conv = wininst2wheel + + if verbose: + print("{}... ".format(installer)) + sys.stdout.flush() + + conv(installer, dest_dir) + if verbose: + print("OK") diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/cli/pack.py b/zhdo.space/lib/python3.9/site-packages/wheel/cli/pack.py new file mode 100644 index 0000000..9403c51 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel/cli/pack.py @@ -0,0 +1,82 @@ +from __future__ import print_function + +import os.path +import re +import sys + +from wheel.cli import WheelError +from wheel.wheelfile import WheelFile + +DIST_INFO_RE = re.compile(r"^(?P(?P.+?)-(?P\d.*?))\.dist-info$") +BUILD_NUM_RE = re.compile(br'Build: (\d\w*)$') + + +def pack(directory, dest_dir, build_number): + """Repack a previously unpacked wheel directory into a new wheel file. + + The .dist-info/WHEEL file must contain one or more tags so that the target + wheel file name can be determined. + + :param directory: The unpacked wheel directory + :param dest_dir: Destination directory (defaults to the current directory) + """ + # Find the .dist-info directory + dist_info_dirs = [fn for fn in os.listdir(directory) + if os.path.isdir(os.path.join(directory, fn)) and DIST_INFO_RE.match(fn)] + if len(dist_info_dirs) > 1: + raise WheelError('Multiple .dist-info directories found in {}'.format(directory)) + elif not dist_info_dirs: + raise WheelError('No .dist-info directories found in {}'.format(directory)) + + # Determine the target wheel filename + dist_info_dir = dist_info_dirs[0] + name_version = DIST_INFO_RE.match(dist_info_dir).group('namever') + + # Read the tags and the existing build number from .dist-info/WHEEL + existing_build_number = None + wheel_file_path = os.path.join(directory, dist_info_dir, 'WHEEL') + with open(wheel_file_path) as f: + tags = [] + for line in f: + if line.startswith('Tag: '): + tags.append(line.split(' ')[1].rstrip()) + elif line.startswith('Build: '): + existing_build_number = line.split(' ')[1].rstrip() + + if not tags: + raise WheelError('No tags present in {}/WHEEL; cannot determine target wheel filename' + .format(dist_info_dir)) + + # Set the wheel file name and add/replace/remove the Build tag in .dist-info/WHEEL + build_number = build_number if build_number is not None else existing_build_number + if build_number is not None: + if build_number: + name_version += '-' + build_number + + if build_number != existing_build_number: + replacement = ('Build: %s\r\n' % build_number).encode('ascii') if build_number else b'' + with open(wheel_file_path, 'rb+') as f: + wheel_file_content = f.read() + wheel_file_content, num_replaced = BUILD_NUM_RE.subn(replacement, + wheel_file_content) + if not num_replaced: + wheel_file_content += replacement + + f.seek(0) + f.truncate() + f.write(wheel_file_content) + + # Reassemble the tags for the wheel file + impls = sorted({tag.split('-')[0] for tag in tags}) + abivers = sorted({tag.split('-')[1] for tag in tags}) + platforms = sorted({tag.split('-')[2] for tag in tags}) + tagline = '-'.join(['.'.join(impls), '.'.join(abivers), '.'.join(platforms)]) + + # Repack the wheel + wheel_path = os.path.join(dest_dir, '{}-{}.whl'.format(name_version, tagline)) + with WheelFile(wheel_path, 'w') as wf: + print("Repacking wheel as {}...".format(wheel_path), end='') + sys.stdout.flush() + wf.write_files(directory) + + print('OK') diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/cli/unpack.py b/zhdo.space/lib/python3.9/site-packages/wheel/cli/unpack.py new file mode 100644 index 0000000..2e9857a --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel/cli/unpack.py @@ -0,0 +1,25 @@ +from __future__ import print_function + +import os.path +import sys + +from ..wheelfile import WheelFile + + +def unpack(path, dest='.'): + """Unpack a wheel. + + Wheel content will be unpacked to {dest}/{name}-{ver}, where {name} + is the package name and {ver} its version. + + :param path: The path to the wheel. + :param dest: Destination directory (default to current directory). + """ + with WheelFile(path) as wf: + namever = wf.parsed_filename.group('namever') + destination = os.path.join(dest, namever) + print("Unpacking to: {}...".format(destination), end='') + sys.stdout.flush() + wf.extractall(destination) + + print('OK') diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/macosx_libfile.py b/zhdo.space/lib/python3.9/site-packages/wheel/macosx_libfile.py new file mode 100644 index 0000000..39006fb --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel/macosx_libfile.py @@ -0,0 +1,428 @@ +""" +This module contains function to analyse dynamic library +headers to extract system information + +Currently only for MacOSX + +Library file on macosx system starts with Mach-O or Fat field. +This can be distinguish by first 32 bites and it is called magic number. +Proper value of magic number is with suffix _MAGIC. Suffix _CIGAM means +reversed bytes order. +Both fields can occur in two types: 32 and 64 bytes. + +FAT field inform that this library contains few version of library +(typically for different types version). It contains +information where Mach-O headers starts. + +Each section started with Mach-O header contains one library +(So if file starts with this field it contains only one version). + +After filed Mach-O there are section fields. +Each of them starts with two fields: +cmd - magic number for this command +cmdsize - total size occupied by this section information. + +In this case only sections LC_VERSION_MIN_MACOSX (for macosx 10.13 and earlier) +and LC_BUILD_VERSION (for macosx 10.14 and newer) are interesting, +because them contains information about minimal system version. + +Important remarks: +- For fat files this implementation looks for maximum number version. + It not check if it is 32 or 64 and do not compare it with currently built package. + So it is possible to false report higher version that needed. +- All structures signatures are taken form macosx header files. +- I think that binary format will be more stable than `otool` output. + and if apple introduce some changes both implementation will need to be updated. +- The system compile will set the deployment target no lower than + 11.0 for arm64 builds. For "Universal 2" builds use the x86_64 deployment + target when the arm64 target is 11.0. +""" + +import ctypes +import os +import sys + +"""here the needed const and struct from mach-o header files""" + +FAT_MAGIC = 0xcafebabe +FAT_CIGAM = 0xbebafeca +FAT_MAGIC_64 = 0xcafebabf +FAT_CIGAM_64 = 0xbfbafeca +MH_MAGIC = 0xfeedface +MH_CIGAM = 0xcefaedfe +MH_MAGIC_64 = 0xfeedfacf +MH_CIGAM_64 = 0xcffaedfe + +LC_VERSION_MIN_MACOSX = 0x24 +LC_BUILD_VERSION = 0x32 + +CPU_TYPE_ARM64 = 0x0100000c + +mach_header_fields = [ + ("magic", ctypes.c_uint32), ("cputype", ctypes.c_int), + ("cpusubtype", ctypes.c_int), ("filetype", ctypes.c_uint32), + ("ncmds", ctypes.c_uint32), ("sizeofcmds", ctypes.c_uint32), + ("flags", ctypes.c_uint32) + ] +""" +struct mach_header { + uint32_t magic; /* mach magic number identifier */ + cpu_type_t cputype; /* cpu specifier */ + cpu_subtype_t cpusubtype; /* machine specifier */ + uint32_t filetype; /* type of file */ + uint32_t ncmds; /* number of load commands */ + uint32_t sizeofcmds; /* the size of all the load commands */ + uint32_t flags; /* flags */ +}; +typedef integer_t cpu_type_t; +typedef integer_t cpu_subtype_t; +""" + +mach_header_fields_64 = mach_header_fields + [("reserved", ctypes.c_uint32)] +""" +struct mach_header_64 { + uint32_t magic; /* mach magic number identifier */ + cpu_type_t cputype; /* cpu specifier */ + cpu_subtype_t cpusubtype; /* machine specifier */ + uint32_t filetype; /* type of file */ + uint32_t ncmds; /* number of load commands */ + uint32_t sizeofcmds; /* the size of all the load commands */ + uint32_t flags; /* flags */ + uint32_t reserved; /* reserved */ +}; +""" + +fat_header_fields = [("magic", ctypes.c_uint32), ("nfat_arch", ctypes.c_uint32)] +""" +struct fat_header { + uint32_t magic; /* FAT_MAGIC or FAT_MAGIC_64 */ + uint32_t nfat_arch; /* number of structs that follow */ +}; +""" + +fat_arch_fields = [ + ("cputype", ctypes.c_int), ("cpusubtype", ctypes.c_int), + ("offset", ctypes.c_uint32), ("size", ctypes.c_uint32), + ("align", ctypes.c_uint32) +] +""" +struct fat_arch { + cpu_type_t cputype; /* cpu specifier (int) */ + cpu_subtype_t cpusubtype; /* machine specifier (int) */ + uint32_t offset; /* file offset to this object file */ + uint32_t size; /* size of this object file */ + uint32_t align; /* alignment as a power of 2 */ +}; +""" + +fat_arch_64_fields = [ + ("cputype", ctypes.c_int), ("cpusubtype", ctypes.c_int), + ("offset", ctypes.c_uint64), ("size", ctypes.c_uint64), + ("align", ctypes.c_uint32), ("reserved", ctypes.c_uint32) +] +""" +struct fat_arch_64 { + cpu_type_t cputype; /* cpu specifier (int) */ + cpu_subtype_t cpusubtype; /* machine specifier (int) */ + uint64_t offset; /* file offset to this object file */ + uint64_t size; /* size of this object file */ + uint32_t align; /* alignment as a power of 2 */ + uint32_t reserved; /* reserved */ +}; +""" + +segment_base_fields = [("cmd", ctypes.c_uint32), ("cmdsize", ctypes.c_uint32)] +"""base for reading segment info""" + +segment_command_fields = [ + ("cmd", ctypes.c_uint32), ("cmdsize", ctypes.c_uint32), + ("segname", ctypes.c_char * 16), ("vmaddr", ctypes.c_uint32), + ("vmsize", ctypes.c_uint32), ("fileoff", ctypes.c_uint32), + ("filesize", ctypes.c_uint32), ("maxprot", ctypes.c_int), + ("initprot", ctypes.c_int), ("nsects", ctypes.c_uint32), + ("flags", ctypes.c_uint32), + ] +""" +struct segment_command { /* for 32-bit architectures */ + uint32_t cmd; /* LC_SEGMENT */ + uint32_t cmdsize; /* includes sizeof section structs */ + char segname[16]; /* segment name */ + uint32_t vmaddr; /* memory address of this segment */ + uint32_t vmsize; /* memory size of this segment */ + uint32_t fileoff; /* file offset of this segment */ + uint32_t filesize; /* amount to map from the file */ + vm_prot_t maxprot; /* maximum VM protection */ + vm_prot_t initprot; /* initial VM protection */ + uint32_t nsects; /* number of sections in segment */ + uint32_t flags; /* flags */ +}; +typedef int vm_prot_t; +""" + +segment_command_fields_64 = [ + ("cmd", ctypes.c_uint32), ("cmdsize", ctypes.c_uint32), + ("segname", ctypes.c_char * 16), ("vmaddr", ctypes.c_uint64), + ("vmsize", ctypes.c_uint64), ("fileoff", ctypes.c_uint64), + ("filesize", ctypes.c_uint64), ("maxprot", ctypes.c_int), + ("initprot", ctypes.c_int), ("nsects", ctypes.c_uint32), + ("flags", ctypes.c_uint32), + ] +""" +struct segment_command_64 { /* for 64-bit architectures */ + uint32_t cmd; /* LC_SEGMENT_64 */ + uint32_t cmdsize; /* includes sizeof section_64 structs */ + char segname[16]; /* segment name */ + uint64_t vmaddr; /* memory address of this segment */ + uint64_t vmsize; /* memory size of this segment */ + uint64_t fileoff; /* file offset of this segment */ + uint64_t filesize; /* amount to map from the file */ + vm_prot_t maxprot; /* maximum VM protection */ + vm_prot_t initprot; /* initial VM protection */ + uint32_t nsects; /* number of sections in segment */ + uint32_t flags; /* flags */ +}; +""" + +version_min_command_fields = segment_base_fields + \ + [("version", ctypes.c_uint32), ("sdk", ctypes.c_uint32)] +""" +struct version_min_command { + uint32_t cmd; /* LC_VERSION_MIN_MACOSX or + LC_VERSION_MIN_IPHONEOS or + LC_VERSION_MIN_WATCHOS or + LC_VERSION_MIN_TVOS */ + uint32_t cmdsize; /* sizeof(struct min_version_command) */ + uint32_t version; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ + uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ +}; +""" + +build_version_command_fields = segment_base_fields + \ + [("platform", ctypes.c_uint32), ("minos", ctypes.c_uint32), + ("sdk", ctypes.c_uint32), ("ntools", ctypes.c_uint32)] +""" +struct build_version_command { + uint32_t cmd; /* LC_BUILD_VERSION */ + uint32_t cmdsize; /* sizeof(struct build_version_command) plus */ + /* ntools * sizeof(struct build_tool_version) */ + uint32_t platform; /* platform */ + uint32_t minos; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ + uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ + uint32_t ntools; /* number of tool entries following this */ +}; +""" + + +def swap32(x): + return (((x << 24) & 0xFF000000) | + ((x << 8) & 0x00FF0000) | + ((x >> 8) & 0x0000FF00) | + ((x >> 24) & 0x000000FF)) + + +def get_base_class_and_magic_number(lib_file, seek=None): + if seek is None: + seek = lib_file.tell() + else: + lib_file.seek(seek) + magic_number = ctypes.c_uint32.from_buffer_copy( + lib_file.read(ctypes.sizeof(ctypes.c_uint32))).value + + # Handle wrong byte order + if magic_number in [FAT_CIGAM, FAT_CIGAM_64, MH_CIGAM, MH_CIGAM_64]: + if sys.byteorder == "little": + BaseClass = ctypes.BigEndianStructure + else: + BaseClass = ctypes.LittleEndianStructure + + magic_number = swap32(magic_number) + else: + BaseClass = ctypes.Structure + + lib_file.seek(seek) + return BaseClass, magic_number + + +def read_data(struct_class, lib_file): + return struct_class.from_buffer_copy(lib_file.read( + ctypes.sizeof(struct_class))) + + +def extract_macosx_min_system_version(path_to_lib): + with open(path_to_lib, "rb") as lib_file: + BaseClass, magic_number = get_base_class_and_magic_number(lib_file, 0) + if magic_number not in [FAT_MAGIC, FAT_MAGIC_64, MH_MAGIC, MH_MAGIC_64]: + return + + if magic_number in [FAT_MAGIC, FAT_CIGAM_64]: + class FatHeader(BaseClass): + _fields_ = fat_header_fields + + fat_header = read_data(FatHeader, lib_file) + if magic_number == FAT_MAGIC: + + class FatArch(BaseClass): + _fields_ = fat_arch_fields + else: + + class FatArch(BaseClass): + _fields_ = fat_arch_64_fields + + fat_arch_list = [read_data(FatArch, lib_file) for _ in range(fat_header.nfat_arch)] + + versions_list = [] + for el in fat_arch_list: + try: + version = read_mach_header(lib_file, el.offset) + if version is not None: + if el.cputype == CPU_TYPE_ARM64 and len(fat_arch_list) != 1: + # Xcode will not set the deployment target below 11.0.0 + # for the arm64 architecture. Ignore the arm64 deployment + # in fat binaries when the target is 11.0.0, that way + # the other architectures can select a lower deployment + # target. + # This is safe because there is no arm64 variant for + # macOS 10.15 or earlier. + if version == (11, 0, 0): + continue + versions_list.append(version) + except ValueError: + pass + + if len(versions_list) > 0: + return max(versions_list) + else: + return None + + else: + try: + return read_mach_header(lib_file, 0) + except ValueError: + """when some error during read library files""" + return None + + +def read_mach_header(lib_file, seek=None): + """ + This funcition parse mach-O header and extract + information about minimal system version + + :param lib_file: reference to opened library file with pointer + """ + if seek is not None: + lib_file.seek(seek) + base_class, magic_number = get_base_class_and_magic_number(lib_file) + arch = "32" if magic_number == MH_MAGIC else "64" + + class SegmentBase(base_class): + _fields_ = segment_base_fields + + if arch == "32": + + class MachHeader(base_class): + _fields_ = mach_header_fields + + else: + + class MachHeader(base_class): + _fields_ = mach_header_fields_64 + + mach_header = read_data(MachHeader, lib_file) + for _i in range(mach_header.ncmds): + pos = lib_file.tell() + segment_base = read_data(SegmentBase, lib_file) + lib_file.seek(pos) + if segment_base.cmd == LC_VERSION_MIN_MACOSX: + class VersionMinCommand(base_class): + _fields_ = version_min_command_fields + + version_info = read_data(VersionMinCommand, lib_file) + return parse_version(version_info.version) + elif segment_base.cmd == LC_BUILD_VERSION: + class VersionBuild(base_class): + _fields_ = build_version_command_fields + + version_info = read_data(VersionBuild, lib_file) + return parse_version(version_info.minos) + else: + lib_file.seek(pos + segment_base.cmdsize) + continue + + +def parse_version(version): + x = (version & 0xffff0000) >> 16 + y = (version & 0x0000ff00) >> 8 + z = (version & 0x000000ff) + return x, y, z + + +def calculate_macosx_platform_tag(archive_root, platform_tag): + """ + Calculate proper macosx platform tag basing on files which are included to wheel + + Example platform tag `macosx-10.14-x86_64` + """ + prefix, base_version, suffix = platform_tag.split('-') + base_version = tuple([int(x) for x in base_version.split(".")]) + base_version = base_version[:2] + if base_version[0] > 10: + base_version = (base_version[0], 0) + assert len(base_version) == 2 + if "MACOSX_DEPLOYMENT_TARGET" in os.environ: + deploy_target = tuple([int(x) for x in os.environ[ + "MACOSX_DEPLOYMENT_TARGET"].split(".")]) + deploy_target = deploy_target[:2] + if deploy_target[0] > 10: + deploy_target = (deploy_target[0], 0) + if deploy_target < base_version: + sys.stderr.write( + "[WARNING] MACOSX_DEPLOYMENT_TARGET is set to a lower value ({}) than the " + "version on which the Python interpreter was compiled ({}), and will be " + "ignored.\n".format('.'.join(str(x) for x in deploy_target), + '.'.join(str(x) for x in base_version)) + ) + else: + base_version = deploy_target + + assert len(base_version) == 2 + start_version = base_version + versions_dict = {} + for (dirpath, dirnames, filenames) in os.walk(archive_root): + for filename in filenames: + if filename.endswith('.dylib') or filename.endswith('.so'): + lib_path = os.path.join(dirpath, filename) + min_ver = extract_macosx_min_system_version(lib_path) + if min_ver is not None: + min_ver = min_ver[0:2] + if min_ver[0] > 10: + min_ver = (min_ver[0], 0) + versions_dict[lib_path] = min_ver + + if len(versions_dict) > 0: + base_version = max(base_version, max(versions_dict.values())) + + # macosx platform tag do not support minor bugfix release + fin_base_version = "_".join([str(x) for x in base_version]) + if start_version < base_version: + problematic_files = [k for k, v in versions_dict.items() if v > start_version] + problematic_files = "\n".join(problematic_files) + if len(problematic_files) == 1: + files_form = "this file" + else: + files_form = "these files" + error_message = \ + "[WARNING] This wheel needs a higher macOS version than {} " \ + "To silence this warning, set MACOSX_DEPLOYMENT_TARGET to at least " +\ + fin_base_version + " or recreate " + files_form + " with lower " \ + "MACOSX_DEPLOYMENT_TARGET: \n" + problematic_files + + if "MACOSX_DEPLOYMENT_TARGET" in os.environ: + error_message = error_message.format("is set in MACOSX_DEPLOYMENT_TARGET variable.") + else: + error_message = error_message.format( + "the version your Python interpreter is compiled against.") + + sys.stderr.write(error_message) + + platform_tag = prefix + "_" + fin_base_version + "_" + suffix + return platform_tag diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/metadata.py b/zhdo.space/lib/python3.9/site-packages/wheel/metadata.py new file mode 100644 index 0000000..37efa74 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel/metadata.py @@ -0,0 +1,133 @@ +""" +Tools for converting old- to new-style metadata. +""" + +import os.path +import textwrap + +import pkg_resources + +from .pkginfo import read_pkg_info + + +def requires_to_requires_dist(requirement): + """Return the version specifier for a requirement in PEP 345/566 fashion.""" + if getattr(requirement, 'url', None): + return " @ " + requirement.url + + requires_dist = [] + for op, ver in requirement.specs: + requires_dist.append(op + ver) + if not requires_dist: + return '' + return " (%s)" % ','.join(sorted(requires_dist)) + + +def convert_requirements(requirements): + """Yield Requires-Dist: strings for parsed requirements strings.""" + for req in requirements: + parsed_requirement = pkg_resources.Requirement.parse(req) + spec = requires_to_requires_dist(parsed_requirement) + extras = ",".join(sorted(parsed_requirement.extras)) + if extras: + extras = "[%s]" % extras + yield (parsed_requirement.project_name + extras + spec) + + +def generate_requirements(extras_require): + """ + Convert requirements from a setup()-style dictionary to ('Requires-Dist', 'requirement') + and ('Provides-Extra', 'extra') tuples. + + extras_require is a dictionary of {extra: [requirements]} as passed to setup(), + using the empty extra {'': [requirements]} to hold install_requires. + """ + for extra, depends in extras_require.items(): + condition = '' + extra = extra or '' + if ':' in extra: # setuptools extra:condition syntax + extra, condition = extra.split(':', 1) + + extra = pkg_resources.safe_extra(extra) + if extra: + yield 'Provides-Extra', extra + if condition: + condition = "(" + condition + ") and " + condition += "extra == '%s'" % extra + + if condition: + condition = ' ; ' + condition + + for new_req in convert_requirements(depends): + yield 'Requires-Dist', new_req + condition + + +def pkginfo_to_metadata(egg_info_path, pkginfo_path): + """ + Convert .egg-info directory with PKG-INFO to the Metadata 2.1 format + """ + pkg_info = read_pkg_info(pkginfo_path) + pkg_info.replace_header('Metadata-Version', '2.1') + # Those will be regenerated from `requires.txt`. + del pkg_info['Provides-Extra'] + del pkg_info['Requires-Dist'] + requires_path = os.path.join(egg_info_path, 'requires.txt') + if os.path.exists(requires_path): + with open(requires_path) as requires_file: + requires = requires_file.read() + + parsed_requirements = sorted(pkg_resources.split_sections(requires), + key=lambda x: x[0] or '') + for extra, reqs in parsed_requirements: + for key, value in generate_requirements({extra: reqs}): + if (key, value) not in pkg_info.items(): + pkg_info[key] = value + + description = pkg_info['Description'] + if description: + pkg_info.set_payload(dedent_description(pkg_info)) + del pkg_info['Description'] + + return pkg_info + + +def pkginfo_unicode(pkg_info, field): + """Hack to coax Unicode out of an email Message() - Python 3.3+""" + text = pkg_info[field] + field = field.lower() + if not isinstance(text, str): + for item in pkg_info.raw_items(): + if item[0].lower() == field: + text = item[1].encode('ascii', 'surrogateescape') \ + .decode('utf-8') + break + + return text + + +def dedent_description(pkg_info): + """ + Dedent and convert pkg_info['Description'] to Unicode. + """ + description = pkg_info['Description'] + + # Python 3 Unicode handling, sorta. + surrogates = False + if not isinstance(description, str): + surrogates = True + description = pkginfo_unicode(pkg_info, 'Description') + + description_lines = description.splitlines() + description_dedent = '\n'.join( + # if the first line of long_description is blank, + # the first line here will be indented. + (description_lines[0].lstrip(), + textwrap.dedent('\n'.join(description_lines[1:])), + '\n')) + + if surrogates: + description_dedent = description_dedent \ + .encode("utf8") \ + .decode("ascii", "surrogateescape") + + return description_dedent diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/pkginfo.py b/zhdo.space/lib/python3.9/site-packages/wheel/pkginfo.py new file mode 100644 index 0000000..115be45 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel/pkginfo.py @@ -0,0 +1,43 @@ +"""Tools for reading and writing PKG-INFO / METADATA without caring +about the encoding.""" + +from email.parser import Parser + +try: + unicode + _PY3 = False +except NameError: + _PY3 = True + +if not _PY3: + from email.generator import Generator + + def read_pkg_info_bytes(bytestr): + return Parser().parsestr(bytestr) + + def read_pkg_info(path): + with open(path, "r") as headers: + message = Parser().parse(headers) + return message + + def write_pkg_info(path, message): + with open(path, 'w') as metadata: + Generator(metadata, mangle_from_=False, maxheaderlen=0).flatten(message) +else: + from email.generator import BytesGenerator + + def read_pkg_info_bytes(bytestr): + headers = bytestr.decode(encoding="ascii", errors="surrogateescape") + message = Parser().parsestr(headers) + return message + + def read_pkg_info(path): + with open(path, "r", + encoding="ascii", + errors="surrogateescape") as headers: + message = Parser().parse(headers) + return message + + def write_pkg_info(path, message): + with open(path, "wb") as out: + BytesGenerator(out, mangle_from_=False, maxheaderlen=0).flatten(message) diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/util.py b/zhdo.space/lib/python3.9/site-packages/wheel/util.py new file mode 100644 index 0000000..3ae2b44 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel/util.py @@ -0,0 +1,46 @@ +import base64 +import io +import sys + + +if sys.version_info[0] < 3: + text_type = unicode # noqa: F821 + + StringIO = io.BytesIO + + def native(s, encoding='utf-8'): + if isinstance(s, unicode): # noqa: F821 + return s.encode(encoding) + return s +else: + text_type = str + + StringIO = io.StringIO + + def native(s, encoding='utf-8'): + if isinstance(s, bytes): + return s.decode(encoding) + return s + + +def urlsafe_b64encode(data): + """urlsafe_b64encode without padding""" + return base64.urlsafe_b64encode(data).rstrip(b'=') + + +def urlsafe_b64decode(data): + """urlsafe_b64decode without padding""" + pad = b'=' * (4 - (len(data) & 3)) + return base64.urlsafe_b64decode(data + pad) + + +def as_unicode(s): + if isinstance(s, bytes): + return s.decode('utf-8') + return s + + +def as_bytes(s): + if isinstance(s, text_type): + return s.encode('utf-8') + return s diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/vendored/__init__.py b/zhdo.space/lib/python3.9/site-packages/wheel/vendored/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/vendored/__pycache__/__init__.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/wheel/vendored/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2dc25127d570fa162f174b8217374329a26bffb GIT binary patch literal 183 zcmYe~<>g`kf;jcMBoO@=L?8o3AjbiSi&=m~3PUi1CZpdg`kf;jcMBoO@=L?8o3AjbiSi&=m~3PUi1CZpd1KIx>h#3HLZ8GHm literal 0 HcmV?d00001 diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/vendored/packaging/__pycache__/_typing.cpython-39.pyc b/zhdo.space/lib/python3.9/site-packages/wheel/vendored/packaging/__pycache__/_typing.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..929855cf5af05680f873adafd0bfeaa0fcf0e2f1 GIT binary patch literal 1488 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 None + self._interpreter = interpreter.lower() + self._abi = abi.lower() + self._platform = platform.lower() + # The __hash__ of every single element in a Set[Tag] will be evaluated each time + # that a set calls its `.disjoint()` method, which may be called hundreds of + # times when scanning a page of links for packages with tags matching that + # Set[Tag]. Pre-computing the value here produces significant speedups for + # downstream consumers. + self._hash = hash((self._interpreter, self._abi, self._platform)) + + @property + def interpreter(self): + # type: () -> str + return self._interpreter + + @property + def abi(self): + # type: () -> str + return self._abi + + @property + def platform(self): + # type: () -> str + return self._platform + + def __eq__(self, other): + # type: (object) -> bool + if not isinstance(other, Tag): + return NotImplemented + + return ( + (self.platform == other.platform) + and (self.abi == other.abi) + and (self.interpreter == other.interpreter) + ) + + def __hash__(self): + # type: () -> int + return self._hash + + def __str__(self): + # type: () -> str + return "{}-{}-{}".format(self._interpreter, self._abi, self._platform) + + def __repr__(self): + # type: () -> str + return "<{self} @ {self_id}>".format(self=self, self_id=id(self)) + + +def parse_tag(tag): + # type: (str) -> FrozenSet[Tag] + """ + Parses the provided tag (e.g. `py3-none-any`) into a frozenset of Tag instances. + + Returning a set is required due to the possibility that the tag is a + compressed tag set. + """ + tags = set() + interpreters, abis, platforms = tag.split("-") + for interpreter in interpreters.split("."): + for abi in abis.split("."): + for platform_ in platforms.split("."): + tags.add(Tag(interpreter, abi, platform_)) + return frozenset(tags) + + +def _warn_keyword_parameter(func_name, kwargs): + # type: (str, Dict[str, bool]) -> bool + """ + Backwards-compatibility with Python 2.7 to allow treating 'warn' as keyword-only. + """ + if not kwargs: + return False + elif len(kwargs) > 1 or "warn" not in kwargs: + kwargs.pop("warn", None) + arg = next(iter(kwargs.keys())) + raise TypeError( + "{}() got an unexpected keyword argument {!r}".format(func_name, arg) + ) + return kwargs["warn"] + + +def _get_config_var(name, warn=False): + # type: (str, bool) -> Union[int, str, None] + value = sysconfig.get_config_var(name) + if value is None and warn: + logger.debug( + "Config variable '%s' is unset, Python ABI tag may be incorrect", name + ) + return value + + +def _normalize_string(string): + # type: (str) -> str + return string.replace(".", "_").replace("-", "_") + + +def _abi3_applies(python_version): + # type: (PythonVersion) -> bool + """ + Determine if the Python version supports abi3. + + PEP 384 was first implemented in Python 3.2. + """ + return len(python_version) > 1 and tuple(python_version) >= (3, 2) + + +def _cpython_abis(py_version, warn=False): + # type: (PythonVersion, bool) -> List[str] + py_version = tuple(py_version) # To allow for version comparison. + abis = [] + version = _version_nodot(py_version[:2]) + debug = pymalloc = ucs4 = "" + with_debug = _get_config_var("Py_DEBUG", warn) + has_refcount = hasattr(sys, "gettotalrefcount") + # Windows doesn't set Py_DEBUG, so checking for support of debug-compiled + # extension modules is the best option. + # https://github.com/pypa/pip/issues/3383#issuecomment-173267692 + has_ext = "_d.pyd" in EXTENSION_SUFFIXES + if with_debug or (with_debug is None and (has_refcount or has_ext)): + debug = "d" + if py_version < (3, 8): + with_pymalloc = _get_config_var("WITH_PYMALLOC", warn) + if with_pymalloc or with_pymalloc is None: + pymalloc = "m" + if py_version < (3, 3): + unicode_size = _get_config_var("Py_UNICODE_SIZE", warn) + if unicode_size == 4 or ( + unicode_size is None and sys.maxunicode == 0x10FFFF + ): + ucs4 = "u" + elif debug: + # Debug builds can also load "normal" extension modules. + # We can also assume no UCS-4 or pymalloc requirement. + abis.append("cp{version}".format(version=version)) + abis.insert( + 0, + "cp{version}{debug}{pymalloc}{ucs4}".format( + version=version, debug=debug, pymalloc=pymalloc, ucs4=ucs4 + ), + ) + return abis + + +def cpython_tags( + python_version=None, # type: Optional[PythonVersion] + abis=None, # type: Optional[Iterable[str]] + platforms=None, # type: Optional[Iterable[str]] + **kwargs # type: bool +): + # type: (...) -> Iterator[Tag] + """ + Yields the tags for a CPython interpreter. + + The tags consist of: + - cp-- + - cp-abi3- + - cp-none- + - cp-abi3- # Older Python versions down to 3.2. + + If python_version only specifies a major version then user-provided ABIs and + the 'none' ABItag will be used. + + If 'abi3' or 'none' are specified in 'abis' then they will be yielded at + their normal position and not at the beginning. + """ + warn = _warn_keyword_parameter("cpython_tags", kwargs) + if not python_version: + python_version = sys.version_info[:2] + + interpreter = "cp{}".format(_version_nodot(python_version[:2])) + + if abis is None: + if len(python_version) > 1: + abis = _cpython_abis(python_version, warn) + else: + abis = [] + abis = list(abis) + # 'abi3' and 'none' are explicitly handled later. + for explicit_abi in ("abi3", "none"): + try: + abis.remove(explicit_abi) + except ValueError: + pass + + platforms = list(platforms or _platform_tags()) + for abi in abis: + for platform_ in platforms: + yield Tag(interpreter, abi, platform_) + if _abi3_applies(python_version): + for tag in (Tag(interpreter, "abi3", platform_) for platform_ in platforms): + yield tag + for tag in (Tag(interpreter, "none", platform_) for platform_ in platforms): + yield tag + + if _abi3_applies(python_version): + for minor_version in range(python_version[1] - 1, 1, -1): + for platform_ in platforms: + interpreter = "cp{version}".format( + version=_version_nodot((python_version[0], minor_version)) + ) + yield Tag(interpreter, "abi3", platform_) + + +def _generic_abi(): + # type: () -> Iterator[str] + abi = sysconfig.get_config_var("SOABI") + if abi: + yield _normalize_string(abi) + + +def generic_tags( + interpreter=None, # type: Optional[str] + abis=None, # type: Optional[Iterable[str]] + platforms=None, # type: Optional[Iterable[str]] + **kwargs # type: bool +): + # type: (...) -> Iterator[Tag] + """ + Yields the tags for a generic interpreter. + + The tags consist of: + - -- + + The "none" ABI will be added if it was not explicitly provided. + """ + warn = _warn_keyword_parameter("generic_tags", kwargs) + if not interpreter: + interp_name = interpreter_name() + interp_version = interpreter_version(warn=warn) + interpreter = "".join([interp_name, interp_version]) + if abis is None: + abis = _generic_abi() + platforms = list(platforms or _platform_tags()) + abis = list(abis) + if "none" not in abis: + abis.append("none") + for abi in abis: + for platform_ in platforms: + yield Tag(interpreter, abi, platform_) + + +def _py_interpreter_range(py_version): + # type: (PythonVersion) -> Iterator[str] + """ + Yields Python versions in descending order. + + After the latest version, the major-only version will be yielded, and then + all previous versions of that major version. + """ + if len(py_version) > 1: + yield "py{version}".format(version=_version_nodot(py_version[:2])) + yield "py{major}".format(major=py_version[0]) + if len(py_version) > 1: + for minor in range(py_version[1] - 1, -1, -1): + yield "py{version}".format(version=_version_nodot((py_version[0], minor))) + + +def compatible_tags( + python_version=None, # type: Optional[PythonVersion] + interpreter=None, # type: Optional[str] + platforms=None, # type: Optional[Iterable[str]] +): + # type: (...) -> Iterator[Tag] + """ + Yields the sequence of tags that are compatible with a specific version of Python. + + The tags consist of: + - py*-none- + - -none-any # ... if `interpreter` is provided. + - py*-none-any + """ + if not python_version: + python_version = sys.version_info[:2] + platforms = list(platforms or _platform_tags()) + for version in _py_interpreter_range(python_version): + for platform_ in platforms: + yield Tag(version, "none", platform_) + if interpreter: + yield Tag(interpreter, "none", "any") + for version in _py_interpreter_range(python_version): + yield Tag(version, "none", "any") + + +def _mac_arch(arch, is_32bit=_32_BIT_INTERPRETER): + # type: (str, bool) -> str + if not is_32bit: + return arch + + if arch.startswith("ppc"): + return "ppc" + + return "i386" + + +def _mac_binary_formats(version, cpu_arch): + # type: (MacVersion, str) -> List[str] + formats = [cpu_arch] + if cpu_arch == "x86_64": + if version < (10, 4): + return [] + formats.extend(["intel", "fat64", "fat32"]) + + elif cpu_arch == "i386": + if version < (10, 4): + return [] + formats.extend(["intel", "fat32", "fat"]) + + elif cpu_arch == "ppc64": + # TODO: Need to care about 32-bit PPC for ppc64 through 10.2? + if version > (10, 5) or version < (10, 4): + return [] + formats.append("fat64") + + elif cpu_arch == "ppc": + if version > (10, 6): + return [] + formats.extend(["fat32", "fat"]) + + if cpu_arch in {"arm64", "x86_64"}: + formats.append("universal2") + + if cpu_arch in {"x86_64", "i386", "ppc64", "ppc", "intel"}: + formats.append("universal") + + return formats + + +def mac_platforms(version=None, arch=None): + # type: (Optional[MacVersion], Optional[str]) -> Iterator[str] + """ + Yields the platform tags for a macOS system. + + The `version` parameter is a two-item tuple specifying the macOS version to + generate platform tags for. The `arch` parameter is the CPU architecture to + generate platform tags for. Both parameters default to the appropriate value + for the current system. + """ + version_str, _, cpu_arch = platform.mac_ver() # type: ignore + if version is None: + version = cast("MacVersion", tuple(map(int, version_str.split(".")[:2]))) + else: + version = version + if arch is None: + arch = _mac_arch(cpu_arch) + else: + arch = arch + + if (10, 0) <= version and version < (11, 0): + # Prior to Mac OS 11, each yearly release of Mac OS bumped the + # "minor" version number. The major version was always 10. + for minor_version in range(version[1], -1, -1): + compat_version = 10, minor_version + binary_formats = _mac_binary_formats(compat_version, arch) + for binary_format in binary_formats: + yield "macosx_{major}_{minor}_{binary_format}".format( + major=10, minor=minor_version, binary_format=binary_format + ) + + if version >= (11, 0): + # Starting with Mac OS 11, each yearly release bumps the major version + # number. The minor versions are now the midyear updates. + for major_version in range(version[0], 10, -1): + compat_version = major_version, 0 + binary_formats = _mac_binary_formats(compat_version, arch) + for binary_format in binary_formats: + yield "macosx_{major}_{minor}_{binary_format}".format( + major=major_version, minor=0, binary_format=binary_format + ) + + if version >= (11, 0): + # Mac OS 11 on x86_64 is compatible with binaries from previous releases. + # Arm64 support was introduced in 11.0, so no Arm binaries from previous + # releases exist. + # + # However, the "universal2" binary format can have a + # macOS version earlier than 11.0 when the x86_64 part of the binary supports + # that version of macOS. + if arch == "x86_64": + for minor_version in range(16, 3, -1): + compat_version = 10, minor_version + binary_formats = _mac_binary_formats(compat_version, arch) + for binary_format in binary_formats: + yield "macosx_{major}_{minor}_{binary_format}".format( + major=compat_version[0], + minor=compat_version[1], + binary_format=binary_format, + ) + else: + for minor_version in range(16, 3, -1): + compat_version = 10, minor_version + binary_format = "universal2" + yield "macosx_{major}_{minor}_{binary_format}".format( + major=compat_version[0], + minor=compat_version[1], + binary_format=binary_format, + ) + + +# From PEP 513, PEP 600 +def _is_manylinux_compatible(name, arch, glibc_version): + # type: (str, str, GlibcVersion) -> bool + sys_glibc = _get_glibc_version() + if sys_glibc < glibc_version: + return False + # Check for presence of _manylinux module. + try: + import _manylinux # noqa + except ImportError: + pass + else: + if hasattr(_manylinux, "manylinux_compatible"): + result = _manylinux.manylinux_compatible( + glibc_version[0], glibc_version[1], arch + ) + if result is not None: + return bool(result) + else: + if glibc_version == (2, 5): + if hasattr(_manylinux, "manylinux1_compatible"): + return bool(_manylinux.manylinux1_compatible) + if glibc_version == (2, 12): + if hasattr(_manylinux, "manylinux2010_compatible"): + return bool(_manylinux.manylinux2010_compatible) + if glibc_version == (2, 17): + if hasattr(_manylinux, "manylinux2014_compatible"): + return bool(_manylinux.manylinux2014_compatible) + return True + + +def _glibc_version_string(): + # type: () -> Optional[str] + # Returns glibc version string, or None if not using glibc. + return _glibc_version_string_confstr() or _glibc_version_string_ctypes() + + +def _glibc_version_string_confstr(): + # type: () -> Optional[str] + """ + Primary implementation of glibc_version_string using os.confstr. + """ + # os.confstr is quite a bit faster than ctypes.DLL. It's also less likely + # to be broken or missing. This strategy is used in the standard library + # platform module. + # https://github.com/python/cpython/blob/fcf1d003bf4f0100c9d0921ff3d70e1127ca1b71/Lib/platform.py#L175-L183 + try: + # os.confstr("CS_GNU_LIBC_VERSION") returns a string like "glibc 2.17". + version_string = os.confstr( # type: ignore[attr-defined] # noqa: F821 + "CS_GNU_LIBC_VERSION" + ) + assert version_string is not None + _, version = version_string.split() # type: Tuple[str, str] + except (AssertionError, AttributeError, OSError, ValueError): + # os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)... + return None + return version + + +def _glibc_version_string_ctypes(): + # type: () -> Optional[str] + """ + Fallback implementation of glibc_version_string using ctypes. + """ + try: + import ctypes + except ImportError: + return None + + # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen + # manpage says, "If filename is NULL, then the returned handle is for the + # main program". This way we can let the linker do the work to figure out + # which libc our process is actually using. + # + # We must also handle the special case where the executable is not a + # dynamically linked executable. This can occur when using musl libc, + # for example. In this situation, dlopen() will error, leading to an + # OSError. Interestingly, at least in the case of musl, there is no + # errno set on the OSError. The single string argument used to construct + # OSError comes from libc itself and is therefore not portable to + # hard code here. In any case, failure to call dlopen() means we + # can proceed, so we bail on our attempt. + try: + # Note: typeshed is wrong here so we are ignoring this line. + process_namespace = ctypes.CDLL(None) # type: ignore + except OSError: + return None + + try: + gnu_get_libc_version = process_namespace.gnu_get_libc_version + except AttributeError: + # Symbol doesn't exist -> therefore, we are not linked to + # glibc. + return None + + # Call gnu_get_libc_version, which returns a string like "2.5" + gnu_get_libc_version.restype = ctypes.c_char_p + version_str = gnu_get_libc_version() # type: str + # py2 / py3 compatibility: + if not isinstance(version_str, str): + version_str = version_str.decode("ascii") + + return version_str + + +def _parse_glibc_version(version_str): + # type: (str) -> Tuple[int, int] + # Parse glibc version. + # + # We use a regexp instead of str.split because we want to discard any + # random junk that might come after the minor version -- this might happen + # in patched/forked versions of glibc (e.g. Linaro's version of glibc + # uses version strings like "2.20-2014.11"). See gh-3588. + m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) + if not m: + warnings.warn( + "Expected glibc version with 2 components major.minor," + " got: %s" % version_str, + RuntimeWarning, + ) + return -1, -1 + return (int(m.group("major")), int(m.group("minor"))) + + +_glibc_version = [] # type: List[Tuple[int, int]] + + +def _get_glibc_version(): + # type: () -> Tuple[int, int] + if _glibc_version: + return _glibc_version[0] + version_str = _glibc_version_string() + if version_str is None: + _glibc_version.append((-1, -1)) + else: + _glibc_version.append(_parse_glibc_version(version_str)) + return _glibc_version[0] + + +# Python does not provide platform information at sufficient granularity to +# identify the architecture of the running executable in some cases, so we +# determine it dynamically by reading the information from the running +# process. This only applies on Linux, which uses the ELF format. +class _ELFFileHeader(object): + # https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header + class _InvalidELFFileHeader(ValueError): + """ + An invalid ELF file header was found. + """ + + ELF_MAGIC_NUMBER = 0x7F454C46 + ELFCLASS32 = 1 + ELFCLASS64 = 2 + ELFDATA2LSB = 1 + ELFDATA2MSB = 2 + EM_386 = 3 + EM_S390 = 22 + EM_ARM = 40 + EM_X86_64 = 62 + EF_ARM_ABIMASK = 0xFF000000 + EF_ARM_ABI_VER5 = 0x05000000 + EF_ARM_ABI_FLOAT_HARD = 0x00000400 + + def __init__(self, file): + # type: (IO[bytes]) -> None + def unpack(fmt): + # type: (str) -> int + try: + (result,) = struct.unpack( + fmt, file.read(struct.calcsize(fmt)) + ) # type: (int, ) + except struct.error: + raise _ELFFileHeader._InvalidELFFileHeader() + return result + + self.e_ident_magic = unpack(">I") + if self.e_ident_magic != self.ELF_MAGIC_NUMBER: + raise _ELFFileHeader._InvalidELFFileHeader() + self.e_ident_class = unpack("B") + if self.e_ident_class not in {self.ELFCLASS32, self.ELFCLASS64}: + raise _ELFFileHeader._InvalidELFFileHeader() + self.e_ident_data = unpack("B") + if self.e_ident_data not in {self.ELFDATA2LSB, self.ELFDATA2MSB}: + raise _ELFFileHeader._InvalidELFFileHeader() + self.e_ident_version = unpack("B") + self.e_ident_osabi = unpack("B") + self.e_ident_abiversion = unpack("B") + self.e_ident_pad = file.read(7) + format_h = "H" + format_i = "I" + format_q = "Q" + format_p = format_i if self.e_ident_class == self.ELFCLASS32 else format_q + self.e_type = unpack(format_h) + self.e_machine = unpack(format_h) + self.e_version = unpack(format_i) + self.e_entry = unpack(format_p) + self.e_phoff = unpack(format_p) + self.e_shoff = unpack(format_p) + self.e_flags = unpack(format_i) + self.e_ehsize = unpack(format_h) + self.e_phentsize = unpack(format_h) + self.e_phnum = unpack(format_h) + self.e_shentsize = unpack(format_h) + self.e_shnum = unpack(format_h) + self.e_shstrndx = unpack(format_h) + + +def _get_elf_header(): + # type: () -> Optional[_ELFFileHeader] + try: + with open(sys.executable, "rb") as f: + elf_header = _ELFFileHeader(f) + except (IOError, OSError, TypeError, _ELFFileHeader._InvalidELFFileHeader): + return None + return elf_header + + +def _is_linux_armhf(): + # type: () -> bool + # hard-float ABI can be detected from the ELF header of the running + # process + # https://static.docs.arm.com/ihi0044/g/aaelf32.pdf + elf_header = _get_elf_header() + if elf_header is None: + return False + result = elf_header.e_ident_class == elf_header.ELFCLASS32 + result &= elf_header.e_ident_data == elf_header.ELFDATA2LSB + result &= elf_header.e_machine == elf_header.EM_ARM + result &= ( + elf_header.e_flags & elf_header.EF_ARM_ABIMASK + ) == elf_header.EF_ARM_ABI_VER5 + result &= ( + elf_header.e_flags & elf_header.EF_ARM_ABI_FLOAT_HARD + ) == elf_header.EF_ARM_ABI_FLOAT_HARD + return result + + +def _is_linux_i686(): + # type: () -> bool + elf_header = _get_elf_header() + if elf_header is None: + return False + result = elf_header.e_ident_class == elf_header.ELFCLASS32 + result &= elf_header.e_ident_data == elf_header.ELFDATA2LSB + result &= elf_header.e_machine == elf_header.EM_386 + return result + + +def _have_compatible_manylinux_abi(arch): + # type: (str) -> bool + if arch == "armv7l": + return _is_linux_armhf() + if arch == "i686": + return _is_linux_i686() + return arch in {"x86_64", "aarch64", "ppc64", "ppc64le", "s390x"} + + +def _manylinux_tags(linux, arch): + # type: (str, str) -> Iterator[str] + # Oldest glibc to be supported regardless of architecture is (2, 17). + too_old_glibc2 = glibcVersion(2, 16) + if arch in {"x86_64", "i686"}: + # On x86/i686 also oldest glibc to be supported is (2, 5). + too_old_glibc2 = glibcVersion(2, 4) + current_glibc = glibcVersion(*_get_glibc_version()) + glibc_max_list = [current_glibc] + # We can assume compatibility across glibc major versions. + # https://sourceware.org/bugzilla/show_bug.cgi?id=24636 + # + # Build a list of maximum glibc versions so that we can + # output the canonical list of all glibc from current_glibc + # down to too_old_glibc2, including all intermediary versions. + for glibc_major in range(current_glibc.major - 1, 1, -1): + glibc_max_list.append(glibcVersion(glibc_major, _LAST_GLIBC_MINOR[glibc_major])) + for glibc_max in glibc_max_list: + if glibc_max.major == too_old_glibc2.major: + min_minor = too_old_glibc2.minor + else: + # For other glibc major versions oldest supported is (x, 0). + min_minor = -1 + for glibc_minor in range(glibc_max.minor, min_minor, -1): + glibc_version = (glibc_max.major, glibc_minor) + tag = "manylinux_{}_{}".format(*glibc_version) + if _is_manylinux_compatible(tag, arch, glibc_version): + yield linux.replace("linux", tag) + # Handle the legacy manylinux1, manylinux2010, manylinux2014 tags. + if glibc_version in _LEGACY_MANYLINUX_MAP: + legacy_tag = _LEGACY_MANYLINUX_MAP[glibc_version] + if _is_manylinux_compatible(legacy_tag, arch, glibc_version): + yield linux.replace("linux", legacy_tag) + + +def _linux_platforms(is_32bit=_32_BIT_INTERPRETER): + # type: (bool) -> Iterator[str] + linux = _normalize_string(distutils.util.get_platform()) + if is_32bit: + if linux == "linux_x86_64": + linux = "linux_i686" + elif linux == "linux_aarch64": + linux = "linux_armv7l" + _, arch = linux.split("_", 1) + if _have_compatible_manylinux_abi(arch): + for tag in _manylinux_tags(linux, arch): + yield tag + yield linux + + +def _generic_platforms(): + # type: () -> Iterator[str] + yield _normalize_string(distutils.util.get_platform()) + + +def _platform_tags(): + # type: () -> Iterator[str] + """ + Provides the platform tags for this installation. + """ + if platform.system() == "Darwin": + return mac_platforms() + elif platform.system() == "Linux": + return _linux_platforms() + else: + return _generic_platforms() + + +def interpreter_name(): + # type: () -> str + """ + Returns the name of the running interpreter. + """ + try: + name = sys.implementation.name # type: ignore + except AttributeError: # pragma: no cover + # Python 2.7 compatibility. + name = platform.python_implementation().lower() + return INTERPRETER_SHORT_NAMES.get(name) or name + + +def interpreter_version(**kwargs): + # type: (bool) -> str + """ + Returns the version of the running interpreter. + """ + warn = _warn_keyword_parameter("interpreter_version", kwargs) + version = _get_config_var("py_version_nodot", warn=warn) + if version: + version = str(version) + else: + version = _version_nodot(sys.version_info[:2]) + return version + + +def _version_nodot(version): + # type: (PythonVersion) -> str + return "".join(map(str, version)) + + +def sys_tags(**kwargs): + # type: (bool) -> Iterator[Tag] + """ + Returns the sequence of tag triples for the running interpreter. + + The order of the sequence corresponds to priority order for the + interpreter, from most to least important. + """ + warn = _warn_keyword_parameter("sys_tags", kwargs) + + interp_name = interpreter_name() + if interp_name == "cp": + for tag in cpython_tags(warn=warn): + yield tag + else: + for tag in generic_tags(): + yield tag + + for tag in compatible_tags(): + yield tag diff --git a/zhdo.space/lib/python3.9/site-packages/wheel/wheelfile.py b/zhdo.space/lib/python3.9/site-packages/wheel/wheelfile.py new file mode 100644 index 0000000..21e7361 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/wheel/wheelfile.py @@ -0,0 +1,181 @@ +from __future__ import print_function + +import csv +import hashlib +import os.path +import re +import stat +import sys +import time +from collections import OrderedDict +from distutils import log as logger +from zipfile import ZIP_DEFLATED, ZipInfo, ZipFile + +from wheel.cli import WheelError +from wheel.util import urlsafe_b64decode, as_unicode, native, urlsafe_b64encode, as_bytes, StringIO + +if sys.version_info >= (3,): + from io import TextIOWrapper + + def read_csv(fp): + return csv.reader(TextIOWrapper(fp, newline='', encoding='utf-8')) +else: + def read_csv(fp): + for line in csv.reader(fp): + yield [column.decode('utf-8') for column in line] + +# Non-greedy matching of an optional build number may be too clever (more +# invalid wheel filenames will match). Separate regex for .dist-info? +WHEEL_INFO_RE = re.compile( + r"""^(?P(?P.+?)-(?P.+?))(-(?P\d[^-]*))? + -(?P.+?)-(?P.+?)-(?P.+?)\.whl$""", + re.VERBOSE) + + +def get_zipinfo_datetime(timestamp=None): + # Some applications need reproducible .whl files, but they can't do this without forcing + # the timestamp of the individual ZipInfo objects. See issue #143. + timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', timestamp or time.time())) + return time.gmtime(timestamp)[0:6] + + +class WheelFile(ZipFile): + """A ZipFile derivative class that also reads SHA-256 hashes from + .dist-info/RECORD and checks any read files against those. + """ + + _default_algorithm = hashlib.sha256 + + def __init__(self, file, mode='r', compression=ZIP_DEFLATED): + basename = os.path.basename(file) + self.parsed_filename = WHEEL_INFO_RE.match(basename) + if not basename.endswith('.whl') or self.parsed_filename is None: + raise WheelError("Bad wheel filename {!r}".format(basename)) + + ZipFile.__init__(self, file, mode, compression=compression, allowZip64=True) + + self.dist_info_path = '{}.dist-info'.format(self.parsed_filename.group('namever')) + self.record_path = self.dist_info_path + '/RECORD' + self._file_hashes = OrderedDict() + self._file_sizes = {} + if mode == 'r': + # Ignore RECORD and any embedded wheel signatures + self._file_hashes[self.record_path] = None, None + self._file_hashes[self.record_path + '.jws'] = None, None + self._file_hashes[self.record_path + '.p7s'] = None, None + + # Fill in the expected hashes by reading them from RECORD + try: + record = self.open(self.record_path) + except KeyError: + raise WheelError('Missing {} file'.format(self.record_path)) + + with record: + for line in read_csv(record): + path, hash_sum, size = line + if not hash_sum: + continue + + algorithm, hash_sum = hash_sum.split(u'=') + try: + hashlib.new(algorithm) + except ValueError: + raise WheelError('Unsupported hash algorithm: {}'.format(algorithm)) + + if algorithm.lower() in {'md5', 'sha1'}: + raise WheelError( + 'Weak hash algorithm ({}) is not permitted by PEP 427' + .format(algorithm)) + + self._file_hashes[path] = ( + algorithm, urlsafe_b64decode(hash_sum.encode('ascii'))) + + def open(self, name_or_info, mode="r", pwd=None): + def _update_crc(newdata, eof=None): + if eof is None: + eof = ef._eof + update_crc_orig(newdata) + else: # Python 2 + update_crc_orig(newdata, eof) + + running_hash.update(newdata) + if eof and running_hash.digest() != expected_hash: + raise WheelError("Hash mismatch for file '{}'".format(native(ef_name))) + + ef_name = as_unicode(name_or_info.filename if isinstance(name_or_info, ZipInfo) + else name_or_info) + if mode == 'r' and not ef_name.endswith('/') and ef_name not in self._file_hashes: + raise WheelError("No hash found for file '{}'".format(native(ef_name))) + + ef = ZipFile.open(self, name_or_info, mode, pwd) + if mode == 'r' and not ef_name.endswith('/'): + algorithm, expected_hash = self._file_hashes[ef_name] + if expected_hash is not None: + # Monkey patch the _update_crc method to also check for the hash from RECORD + running_hash = hashlib.new(algorithm) + update_crc_orig, ef._update_crc = ef._update_crc, _update_crc + + return ef + + def write_files(self, base_dir): + logger.info("creating '%s' and adding '%s' to it", self.filename, base_dir) + deferred = [] + for root, dirnames, filenames in os.walk(base_dir): + # Sort the directory names so that `os.walk` will walk them in a + # defined order on the next iteration. + dirnames.sort() + for name in sorted(filenames): + path = os.path.normpath(os.path.join(root, name)) + if os.path.isfile(path): + arcname = os.path.relpath(path, base_dir).replace(os.path.sep, '/') + if arcname == self.record_path: + pass + elif root.endswith('.dist-info'): + deferred.append((path, arcname)) + else: + self.write(path, arcname) + + deferred.sort() + for path, arcname in deferred: + self.write(path, arcname) + + def write(self, filename, arcname=None, compress_type=None): + with open(filename, 'rb') as f: + st = os.fstat(f.fileno()) + data = f.read() + + zinfo = ZipInfo(arcname or filename, date_time=get_zipinfo_datetime(st.st_mtime)) + zinfo.external_attr = (stat.S_IMODE(st.st_mode) | stat.S_IFMT(st.st_mode)) << 16 + zinfo.compress_type = compress_type or self.compression + self.writestr(zinfo, data, compress_type) + + def writestr(self, zinfo_or_arcname, bytes, compress_type=None): + ZipFile.writestr(self, zinfo_or_arcname, bytes, compress_type) + fname = (zinfo_or_arcname.filename if isinstance(zinfo_or_arcname, ZipInfo) + else zinfo_or_arcname) + logger.info("adding '%s'", fname) + if fname != self.record_path: + hash_ = self._default_algorithm(bytes) + self._file_hashes[fname] = hash_.name, native(urlsafe_b64encode(hash_.digest())) + self._file_sizes[fname] = len(bytes) + + def close(self): + # Write RECORD + if self.fp is not None and self.mode == 'w' and self._file_hashes: + data = StringIO() + writer = csv.writer(data, delimiter=',', quotechar='"', lineterminator='\n') + writer.writerows(( + ( + fname, + algorithm + "=" + hash_, + self._file_sizes[fname] + ) + for fname, (algorithm, hash_) in self._file_hashes.items() + )) + writer.writerow((format(self.record_path), "", "")) + zinfo = ZipInfo(native(self.record_path), date_time=get_zipinfo_datetime()) + zinfo.compress_type = self.compression + zinfo.external_attr = 0o664 << 16 + self.writestr(zinfo, as_bytes(data.getvalue())) + + ZipFile.close(self) diff --git a/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/INSTALLER b/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/LICENSE b/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/LICENSE new file mode 100644 index 0000000..353924b --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/LICENSE @@ -0,0 +1,19 @@ +Copyright Jason R. Coombs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/METADATA b/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/METADATA new file mode 100644 index 0000000..94e90a0 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/METADATA @@ -0,0 +1,84 @@ +Metadata-Version: 2.1 +Name: zipp +Version: 3.8.0 +Summary: Backport of pathlib-compatible object wrapper for zip files +Home-page: https://github.com/jaraco/zipp +Author: Jason R. Coombs +Author-email: jaraco@jaraco.com +License: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Requires-Python: >=3.7 +License-File: LICENSE +Provides-Extra: docs +Requires-Dist: sphinx ; extra == 'docs' +Requires-Dist: jaraco.packaging (>=9) ; extra == 'docs' +Requires-Dist: rst.linker (>=1.9) ; extra == 'docs' +Provides-Extra: testing +Requires-Dist: pytest (>=6) ; extra == 'testing' +Requires-Dist: pytest-checkdocs (>=2.4) ; extra == 'testing' +Requires-Dist: pytest-flake8 ; extra == 'testing' +Requires-Dist: pytest-cov ; extra == 'testing' +Requires-Dist: pytest-enabler (>=1.0.1) ; extra == 'testing' +Requires-Dist: jaraco.itertools ; extra == 'testing' +Requires-Dist: func-timeout ; extra == 'testing' +Requires-Dist: pytest-black (>=0.3.7) ; (platform_python_implementation != "PyPy") and extra == 'testing' +Requires-Dist: pytest-mypy (>=0.9.1) ; (platform_python_implementation != "PyPy") and extra == 'testing' + +.. image:: https://img.shields.io/pypi/v/zipp.svg + :target: `PyPI link`_ + +.. image:: https://img.shields.io/pypi/pyversions/zipp.svg + :target: `PyPI link`_ + +.. _PyPI link: https://pypi.org/project/zipp + +.. image:: https://github.com/jaraco/zipp/workflows/tests/badge.svg + :target: https://github.com/jaraco/zipp/actions?query=workflow%3A%22tests%22 + :alt: tests + +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + :alt: Code style: Black + +.. .. image:: https://readthedocs.org/projects/skeleton/badge/?version=latest +.. :target: https://skeleton.readthedocs.io/en/latest/?badge=latest + +.. image:: https://img.shields.io/badge/skeleton-2022-informational + :target: https://blog.jaraco.com/skeleton + + +A pathlib-compatible Zipfile object wrapper. Official backport of the standard library +`Path object `_. + + +Compatibility +============= + +New features are introduced in this third-party library and later merged +into CPython. The following table indicates which versions of this library +were contributed to different versions in the standard library: + +.. list-table:: + :header-rows: 1 + + * - zipp + - stdlib + * - 3.5 + - 3.11 + * - 3.3 + - 3.9 + * - 1.0 + - 3.8 + + +Usage +===== + +Use ``zipp.Path`` in place of ``zipfile.Path`` on any Python. + + diff --git a/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/RECORD b/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/RECORD new file mode 100644 index 0000000..4ec5f9a --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/RECORD @@ -0,0 +1,8 @@ +__pycache__/zipp.cpython-39.pyc,, +zipp-3.8.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +zipp-3.8.0.dist-info/LICENSE,sha256=2z8CRrH5J48VhFuZ_sR4uLUG63ZIeZNyL4xuJUKF-vg,1050 +zipp-3.8.0.dist-info/METADATA,sha256=6KJo2_gKMNYNz52FNbITlpwbHwa_st0KWpNMFB9OQfE,2719 +zipp-3.8.0.dist-info/RECORD,, +zipp-3.8.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92 +zipp-3.8.0.dist-info/top_level.txt,sha256=iAbdoSHfaGqBfVb2XuR9JqSQHCoOsOtG6y9C_LSpqFw,5 +zipp.py,sha256=5hrx38_-kX0WCpfBk5LSwCIMYraThjaNj5HsriUSB-8,8029 diff --git a/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/WHEEL b/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/WHEEL new file mode 100644 index 0000000..becc9a6 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.37.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/top_level.txt b/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/top_level.txt new file mode 100644 index 0000000..e82f676 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/zipp-3.8.0.dist-info/top_level.txt @@ -0,0 +1 @@ +zipp diff --git a/zhdo.space/lib/python3.9/site-packages/zipp.py b/zhdo.space/lib/python3.9/site-packages/zipp.py new file mode 100644 index 0000000..52c82a0 --- /dev/null +++ b/zhdo.space/lib/python3.9/site-packages/zipp.py @@ -0,0 +1,312 @@ +import io +import posixpath +import zipfile +import itertools +import contextlib +import pathlib + + +__all__ = ['Path'] + + +def _parents(path): + """ + Given a path with elements separated by + posixpath.sep, generate all parents of that path. + + >>> list(_parents('b/d')) + ['b'] + >>> list(_parents('/b/d/')) + ['/b'] + >>> list(_parents('b/d/f/')) + ['b/d', 'b'] + >>> list(_parents('b')) + [] + >>> list(_parents('')) + [] + """ + return itertools.islice(_ancestry(path), 1, None) + + +def _ancestry(path): + """ + Given a path with elements separated by + posixpath.sep, generate all elements of that path + + >>> list(_ancestry('b/d')) + ['b/d', 'b'] + >>> list(_ancestry('/b/d/')) + ['/b/d', '/b'] + >>> list(_ancestry('b/d/f/')) + ['b/d/f', 'b/d', 'b'] + >>> list(_ancestry('b')) + ['b'] + >>> list(_ancestry('')) + [] + """ + path = path.rstrip(posixpath.sep) + while path and path != posixpath.sep: + yield path + path, tail = posixpath.split(path) + + +_dedupe = dict.fromkeys +"""Deduplicate an iterable in original order""" + + +def _difference(minuend, subtrahend): + """ + Return items in minuend not in subtrahend, retaining order + with O(1) lookup. + """ + return itertools.filterfalse(set(subtrahend).__contains__, minuend) + + +class CompleteDirs(zipfile.ZipFile): + """ + A ZipFile subclass that ensures that implied directories + are always included in the namelist. + """ + + @staticmethod + def _implied_dirs(names): + parents = itertools.chain.from_iterable(map(_parents, names)) + as_dirs = (p + posixpath.sep for p in parents) + return _dedupe(_difference(as_dirs, names)) + + def namelist(self): + names = super(CompleteDirs, self).namelist() + return names + list(self._implied_dirs(names)) + + def _name_set(self): + return set(self.namelist()) + + def resolve_dir(self, name): + """ + If the name represents a directory, return that name + as a directory (with the trailing slash). + """ + names = self._name_set() + dirname = name + '/' + dir_match = name not in names and dirname in names + return dirname if dir_match else name + + @classmethod + def make(cls, source): + """ + Given a source (filename or zipfile), return an + appropriate CompleteDirs subclass. + """ + if isinstance(source, CompleteDirs): + return source + + if not isinstance(source, zipfile.ZipFile): + return cls(source) + + # Only allow for FastLookup when supplied zipfile is read-only + if 'r' not in source.mode: + cls = CompleteDirs + + source.__class__ = cls + return source + + +class FastLookup(CompleteDirs): + """ + ZipFile subclass to ensure implicit + dirs exist and are resolved rapidly. + """ + + def namelist(self): + with contextlib.suppress(AttributeError): + return self.__names + self.__names = super(FastLookup, self).namelist() + return self.__names + + def _name_set(self): + with contextlib.suppress(AttributeError): + return self.__lookup + self.__lookup = super(FastLookup, self)._name_set() + return self.__lookup + + +class Path: + """ + A pathlib-compatible interface for zip files. + + Consider a zip file with this structure:: + + . + ├── a.txt + └── b + ├── c.txt + └── d + └── e.txt + + >>> data = io.BytesIO() + >>> zf = zipfile.ZipFile(data, 'w') + >>> zf.writestr('a.txt', 'content of a') + >>> zf.writestr('b/c.txt', 'content of c') + >>> zf.writestr('b/d/e.txt', 'content of e') + >>> zf.filename = 'mem/abcde.zip' + + Path accepts the zipfile object itself or a filename + + >>> root = Path(zf) + + From there, several path operations are available. + + Directory iteration (including the zip file itself): + + >>> a, b = root.iterdir() + >>> a + Path('mem/abcde.zip', 'a.txt') + >>> b + Path('mem/abcde.zip', 'b/') + + name property: + + >>> b.name + 'b' + + join with divide operator: + + >>> c = b / 'c.txt' + >>> c + Path('mem/abcde.zip', 'b/c.txt') + >>> c.name + 'c.txt' + + Read text: + + >>> c.read_text() + 'content of c' + + existence: + + >>> c.exists() + True + >>> (b / 'missing.txt').exists() + False + + Coercion to string: + + >>> import os + >>> str(c).replace(os.sep, posixpath.sep) + 'mem/abcde.zip/b/c.txt' + + At the root, ``name``, ``filename``, and ``parent`` + resolve to the zipfile. Note these attributes are not + valid and will raise a ``ValueError`` if the zipfile + has no filename. + + >>> root.name + 'abcde.zip' + >>> str(root.filename).replace(os.sep, posixpath.sep) + 'mem/abcde.zip' + >>> str(root.parent) + 'mem' + """ + + __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" + + def __init__(self, root, at=""): + """ + Construct a Path from a ZipFile or filename. + + Note: When the source is an existing ZipFile object, + its type (__class__) will be mutated to a + specialized type. If the caller wishes to retain the + original type, the caller should either create a + separate ZipFile object or pass a filename. + """ + self.root = FastLookup.make(root) + self.at = at + + def open(self, mode='r', *args, pwd=None, **kwargs): + """ + Open this entry as text or binary following the semantics + of ``pathlib.Path.open()`` by passing arguments through + to io.TextIOWrapper(). + """ + if self.is_dir(): + raise IsADirectoryError(self) + zip_mode = mode[0] + if not self.exists() and zip_mode == 'r': + raise FileNotFoundError(self) + stream = self.root.open(self.at, zip_mode, pwd=pwd) + if 'b' in mode: + if args or kwargs: + raise ValueError("encoding args invalid for binary operation") + return stream + return io.TextIOWrapper(stream, *args, **kwargs) + + @property + def name(self): + return pathlib.Path(self.at).name or self.filename.name + + @property + def suffix(self): + return pathlib.Path(self.at).suffix or self.filename.suffix + + @property + def suffixes(self): + return pathlib.Path(self.at).suffixes or self.filename.suffixes + + @property + def stem(self): + return pathlib.Path(self.at).stem or self.filename.stem + + @property + def filename(self): + return pathlib.Path(self.root.filename).joinpath(self.at) + + def read_text(self, *args, **kwargs): + with self.open('r', *args, **kwargs) as strm: + return strm.read() + + def read_bytes(self): + with self.open('rb') as strm: + return strm.read() + + def _is_child(self, path): + return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/") + + def _next(self, at): + return self.__class__(self.root, at) + + def is_dir(self): + return not self.at or self.at.endswith("/") + + def is_file(self): + return self.exists() and not self.is_dir() + + def exists(self): + return self.at in self.root._name_set() + + def iterdir(self): + if not self.is_dir(): + raise ValueError("Can't listdir a file") + subs = map(self._next, self.root.namelist()) + return filter(self._is_child, subs) + + def __str__(self): + return posixpath.join(self.root.filename, self.at) + + def __repr__(self): + return self.__repr.format(self=self) + + def joinpath(self, *other): + next = posixpath.join(self.at, *other) + return self._next(self.root.resolve_dir(next)) + + __truediv__ = joinpath + + @property + def parent(self): + if not self.at: + return self.filename.parent + parent_at = posixpath.dirname(self.at.rstrip('/')) + if parent_at: + parent_at += '/' + return self._next(parent_at) diff --git a/zhdo.space/lib64 b/zhdo.space/lib64 new file mode 120000 index 0000000..7951405 --- /dev/null +++ b/zhdo.space/lib64 @@ -0,0 +1 @@ +lib \ No newline at end of file diff --git a/zhdo.space/pyvenv.cfg b/zhdo.space/pyvenv.cfg new file mode 100644 index 0000000..bb122fb --- /dev/null +++ b/zhdo.space/pyvenv.cfg @@ -0,0 +1,3 @@ +home = /usr/lib/python-exec/python3.9 +include-system-site-packages = false +version = 3.9.12