From 199a1e2a61662d3959975de3aae011253ca4fc04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Cort=C3=A9s?= Date: Sun, 22 Nov 2020 21:14:46 -0300 Subject: [PATCH] Eliminado venv y www del repositorio, agrege un requirements igual --- .gitignore | 3 + requirements.txt | 3 + template.html | 2 +- venv/bin/Activate.ps1 | 19 +- venv/bin/activate | 4 +- venv/bin/activate.csh | 4 +- venv/bin/activate.fish | 4 +- venv/bin/easy_install | 6 +- venv/bin/easy_install-3.8 | 6 +- venv/bin/markdown_py | 6 +- venv/bin/pip | 8 +- venv/bin/pip3 | 8 +- venv/bin/pip3.8 | 8 +- .../Jinja2-2.11.2.dist-info/RECORD | 1 + .../Markdown-3.2.1.dist-info/INSTALLER | 1 - .../Markdown-3.2.1.dist-info/LICENSE.md | 29 - .../Markdown-3.2.1.dist-info/METADATA | 57 - .../Markdown-3.2.1.dist-info/RECORD | 74 - .../Markdown-3.2.1.dist-info/WHEEL | 6 - .../Markdown-3.2.1.dist-info/entry_points.txt | 23 - .../Markdown-3.2.1.dist-info/top_level.txt | 1 - .../__pycache__/easy_install.cpython-38.pyc | Bin 285 -> 315 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 1779 -> 1813 bytes .../jinja2/__pycache__/_compat.cpython-38.pyc | Bin 3874 -> 3908 bytes .../__pycache__/_identifier.cpython-38.pyc | Bin 1862 -> 1896 bytes .../__pycache__/asyncfilters.cpython-38.pyc | Bin 4825 -> 4859 bytes .../__pycache__/asyncsupport.cpython-38.pyc | Bin 8191 -> 8225 bytes .../jinja2/__pycache__/bccache.cpython-38.pyc | Bin 12209 -> 12243 bytes .../__pycache__/compiler.cpython-38.pyc | Bin 48319 -> 48353 bytes .../__pycache__/constants.cpython-38.pyc | Bin 1506 -> 1540 bytes .../jinja2/__pycache__/debug.cpython-38.pyc | Bin 5146 -> 5180 bytes .../__pycache__/defaults.cpython-38.pyc | Bin 1082 -> 1116 bytes .../__pycache__/environment.cpython-38.pyc | Bin 43979 -> 44013 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 5610 -> 5644 bytes .../jinja2/__pycache__/ext.cpython-38.pyc | Bin 21474 -> 21508 bytes .../jinja2/__pycache__/filters.cpython-38.pyc | Bin 39780 -> 39814 bytes .../__pycache__/idtracking.cpython-38.pyc | Bin 9840 -> 9874 bytes .../jinja2/__pycache__/lexer.cpython-38.pyc | Bin 19354 -> 19388 bytes .../jinja2/__pycache__/loaders.cpython-38.pyc | Bin 16967 -> 17001 bytes .../jinja2/__pycache__/meta.cpython-38.pyc | Bin 3458 -> 3492 bytes .../__pycache__/nativetypes.cpython-38.pyc | Bin 3892 -> 3926 bytes .../jinja2/__pycache__/nodes.cpython-38.pyc | Bin 35385 -> 35419 bytes .../__pycache__/optimizer.cpython-38.pyc | Bin 1624 -> 1658 bytes .../jinja2/__pycache__/parser.cpython-38.pyc | Bin 24941 -> 24975 bytes .../jinja2/__pycache__/runtime.cpython-38.pyc | Bin 27617 -> 27651 bytes .../jinja2/__pycache__/sandbox.cpython-38.pyc | Bin 14101 -> 14135 bytes .../jinja2/__pycache__/tests.cpython-38.pyc | Bin 5339 -> 5373 bytes .../jinja2/__pycache__/utils.cpython-38.pyc | Bin 22816 -> 22850 bytes .../jinja2/__pycache__/visitor.cpython-38.pyc | Bin 3267 -> 3301 bytes .../site-packages/markdown/__meta__.py | 30 +- .../__pycache__/__init__.cpython-38.pyc | Bin 1850 -> 1882 bytes .../__pycache__/__main__.cpython-38.pyc | Bin 4290 -> 4322 bytes .../__pycache__/__meta__.cpython-38.pyc | Bin 1639 -> 1516 bytes .../__pycache__/blockparser.cpython-38.pyc | Bin 4968 -> 5000 bytes .../blockprocessors.cpython-38.pyc | Bin 16757 -> 17773 bytes .../markdown/__pycache__/core.cpython-38.pyc | Bin 12245 -> 12330 bytes .../__pycache__/inlinepatterns.cpython-38.pyc | Bin 25294 -> 25725 bytes .../__pycache__/pep562.cpython-38.pyc | Bin 8166 -> 8198 bytes .../__pycache__/postprocessors.cpython-38.pyc | Bin 4628 -> 4860 bytes .../__pycache__/preprocessors.cpython-38.pyc | Bin 9808 -> 3357 bytes .../__pycache__/serializers.cpython-38.pyc | Bin 3217 -> 3249 bytes .../__pycache__/test_tools.cpython-38.pyc | Bin 6711 -> 8008 bytes .../__pycache__/treeprocessors.cpython-38.pyc | Bin 11876 -> 11911 bytes .../markdown/__pycache__/util.cpython-38.pyc | Bin 13644 -> 14610 bytes .../site-packages/markdown/blockprocessors.py | 41 +- .../python3.8/site-packages/markdown/core.py | 21 +- .../markdown/extensions/__init__.py | 21 +- .../__pycache__/__init__.cpython-38.pyc | Bin 3959 -> 4073 bytes .../__pycache__/abbr.cpython-38.pyc | Bin 3546 -> 3888 bytes .../__pycache__/admonition.cpython-38.pyc | Bin 3005 -> 4033 bytes .../__pycache__/attr_list.cpython-38.pyc | Bin 4697 -> 4745 bytes .../__pycache__/codehilite.cpython-38.pyc | Bin 8081 -> 9520 bytes .../__pycache__/def_list.cpython-38.pyc | Bin 3544 -> 3624 bytes .../__pycache__/extra.cpython-38.pyc | Bin 2300 -> 2332 bytes .../__pycache__/fenced_code.cpython-38.pyc | Bin 3528 -> 5508 bytes .../__pycache__/footnotes.cpython-38.pyc | Bin 12159 -> 12310 bytes .../__pycache__/legacy_attrs.cpython-38.pyc | Bin 3183 -> 3215 bytes .../__pycache__/legacy_em.cpython-38.pyc | Bin 1886 -> 1921 bytes .../__pycache__/md_in_html.cpython-38.pyc | Bin 3391 -> 10000 bytes .../__pycache__/meta.cpython-38.pyc | Bin 2478 -> 2510 bytes .../__pycache__/nl2br.cpython-38.pyc | Bin 1213 -> 1245 bytes .../__pycache__/sane_lists.cpython-38.pyc | Bin 2196 -> 2228 bytes .../__pycache__/smarty.cpython-38.pyc | Bin 8985 -> 9017 bytes .../__pycache__/tables.cpython-38.pyc | Bin 5570 -> 5602 bytes .../extensions/__pycache__/toc.cpython-38.pyc | Bin 9844 -> 10383 bytes .../__pycache__/wikilinks.cpython-38.pyc | Bin 3214 -> 3246 bytes .../site-packages/markdown/extensions/abbr.py | 49 +- .../markdown/extensions/admonition.py | 80 +- .../markdown/extensions/attr_list.py | 15 +- .../markdown/extensions/codehilite.py | 179 +- .../markdown/extensions/def_list.py | 12 +- .../markdown/extensions/fenced_code.py | 136 +- .../markdown/extensions/footnotes.py | 168 +- .../markdown/extensions/legacy_em.py | 2 +- .../markdown/extensions/md_in_html.py | 355 ++- .../site-packages/markdown/extensions/toc.py | 30 +- .../site-packages/markdown/inlinepatterns.py | 15 +- .../site-packages/markdown/postprocessors.py | 11 +- .../site-packages/markdown/preprocessors.py | 300 +- .../site-packages/markdown/test_tools.py | 38 +- .../site-packages/markdown/treeprocessors.py | 4 +- .../python3.8/site-packages/markdown/util.py | 36 +- .../__pycache__/__init__.cpython-38.pyc | Bin 10934 -> 10964 bytes .../__pycache__/_compat.cpython-38.pyc | Bin 743 -> 773 bytes .../__pycache__/_constants.cpython-38.pyc | Bin 4239 -> 4269 bytes .../__pycache__/_native.cpython-38.pyc | Bin 2117 -> 2147 bytes .../pip-19.2.3.dist-info/INSTALLER | 1 - .../pip-19.2.3.dist-info/LICENSE.txt | 20 - .../pip-19.2.3.dist-info/METADATA | 81 - .../site-packages/pip-19.2.3.dist-info/RECORD | 668 ---- .../site-packages/pip-19.2.3.dist-info/WHEEL | 6 - .../pip-19.2.3.dist-info/entry_points.txt | 5 - .../pip-19.2.3.dist-info/top_level.txt | 1 - .../python3.8/site-packages/pip/__init__.py | 19 +- .../python3.8/site-packages/pip/__main__.py | 9 +- .../pip/__pycache__/__init__.cpython-38.pyc | Bin 158 -> 663 bytes .../pip/__pycache__/__main__.cpython-38.pyc | Bin 410 -> 507 bytes .../site-packages/pip/_internal/__init__.py | 82 +- .../__pycache__/__init__.cpython-38.pyc | Bin 1703 -> 712 bytes .../__pycache__/build_env.cpython-38.pyc | Bin 7479 -> 7537 bytes .../__pycache__/cache.cpython-38.pyc | Bin 7091 -> 9144 bytes .../__pycache__/configuration.cpython-38.pyc | Bin 10642 -> 10938 bytes .../__pycache__/download.cpython-38.pyc | Bin 25929 -> 0 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 12490 -> 14568 bytes .../__pycache__/index.cpython-38.pyc | Bin 37730 -> 0 bytes .../__pycache__/legacy_resolve.cpython-38.pyc | Bin 10549 -> 0 bytes .../__pycache__/locations.cpython-38.pyc | Bin 2938 -> 4521 bytes .../__pycache__/pep425tags.cpython-38.pyc | Bin 8337 -> 0 bytes .../__pycache__/pyproject.cpython-38.pyc | Bin 3164 -> 3766 bytes .../__pycache__/wheel.cpython-38.pyc | Bin 27490 -> 0 bytes .../site-packages/pip/_internal/build_env.py | 57 +- .../site-packages/pip/_internal/cache.py | 234 +- .../cli/__pycache__/__init__.cpython-38.pyc | Bin 233 -> 270 bytes .../__pycache__/autocompletion.cpython-38.pyc | Bin 5091 -> 4987 bytes .../__pycache__/base_command.cpython-38.pyc | Bin 8266 -> 6700 bytes .../cli/__pycache__/cmdoptions.cpython-38.pyc | Bin 20008 -> 20877 bytes .../__pycache__/main_parser.cpython-38.pyc | Bin 2171 -> 2233 bytes .../cli/__pycache__/parser.cpython-38.pyc | Bin 8974 -> 9000 bytes .../__pycache__/status_codes.cpython-38.pyc | Bin 362 -> 399 bytes .../pip/_internal/cli/autocompletion.py | 48 +- .../pip/_internal/cli/base_command.py | 339 +- .../pip/_internal/cli/cmdoptions.py | 218 +- .../pip/_internal/cli/main_parser.py | 17 +- .../site-packages/pip/_internal/cli/parser.py | 21 +- .../pip/_internal/commands/__init__.py | 145 +- .../__pycache__/__init__.cpython-38.pyc | Bin 2552 -> 3000 bytes .../commands/__pycache__/check.cpython-38.pyc | Bin 1294 -> 1598 bytes .../__pycache__/completion.cpython-38.pyc | Bin 3073 -> 3202 bytes .../__pycache__/configuration.cpython-38.pyc | Bin 7137 -> 8098 bytes .../commands/__pycache__/debug.cpython-38.pyc | Bin 3345 -> 6439 bytes .../__pycache__/download.cpython-38.pyc | Bin 4699 -> 4093 bytes .../__pycache__/freeze.cpython-38.pyc | Bin 2992 -> 3032 bytes .../commands/__pycache__/hash.cpython-38.pyc | Bin 2042 -> 2138 bytes .../commands/__pycache__/help.cpython-38.pyc | Bin 1213 -> 1381 bytes .../__pycache__/install.cpython-38.pyc | Bin 13040 -> 17324 bytes .../commands/__pycache__/list.cpython-38.pyc | Bin 8981 -> 8833 bytes .../__pycache__/search.cpython-38.pyc | Bin 4428 -> 4895 bytes .../commands/__pycache__/show.cpython-38.pyc | Bin 5825 -> 6478 bytes .../__pycache__/uninstall.cpython-38.pyc | Bin 2675 -> 2968 bytes .../commands/__pycache__/wheel.cpython-38.pyc | Bin 4881 -> 5118 bytes .../pip/_internal/commands/check.py | 24 +- .../pip/_internal/commands/completion.py | 58 +- .../pip/_internal/commands/configuration.py | 140 +- .../pip/_internal/commands/debug.py | 143 +- .../pip/_internal/commands/download.py | 177 +- .../pip/_internal/commands/freeze.py | 26 +- .../pip/_internal/commands/hash.py | 28 +- .../pip/_internal/commands/help.py | 19 +- .../pip/_internal/commands/install.py | 819 +++-- .../pip/_internal/commands/list.py | 123 +- .../pip/_internal/commands/search.py | 67 +- .../pip/_internal/commands/show.py | 86 +- .../pip/_internal/commands/uninstall.py | 81 +- .../pip/_internal/commands/wheel.py | 207 +- .../pip/_internal/configuration.py | 61 +- .../pip/_internal/distributions/__init__.py | 9 +- .../__pycache__/__init__.cpython-38.pyc | Bin 822 -> 846 bytes .../__pycache__/base.cpython-38.pyc | Bin 1617 -> 1962 bytes .../__pycache__/installed.cpython-38.pyc | Bin 957 -> 1242 bytes .../__pycache__/source.cpython-38.pyc | Bin 3054 -> 0 bytes .../__pycache__/wheel.cpython-38.pyc | Bin 1021 -> 1594 bytes .../pip/_internal/distributions/base.py | 12 + .../pip/_internal/distributions/installed.py | 9 + .../pip/_internal/distributions/source.py | 80 - .../pip/_internal/distributions/wheel.py | 25 +- .../site-packages/pip/_internal/download.py | 1177 ------- .../site-packages/pip/_internal/exceptions.py | 108 +- .../site-packages/pip/_internal/index.py | 1508 --------- .../pip/_internal/legacy_resolve.py | 457 --- .../site-packages/pip/_internal/locations.py | 94 +- .../__pycache__/__init__.cpython-38.pyc | Bin 221 -> 258 bytes .../__pycache__/candidate.cpython-38.pyc | Bin 1455 -> 1493 bytes .../__pycache__/format_control.cpython-38.pyc | Bin 2249 -> 2747 bytes .../models/__pycache__/index.cpython-38.pyc | Bin 1143 -> 1236 bytes .../models/__pycache__/link.cpython-38.pyc | Bin 6282 -> 7193 bytes .../__pycache__/search_scope.cpython-38.pyc | Bin 3252 -> 3445 bytes .../selection_prefs.cpython-38.pyc | Bin 1593 -> 1688 bytes .../__pycache__/target_python.cpython-38.pyc | Bin 3197 -> 3363 bytes .../pip/_internal/models/candidate.py | 16 +- .../pip/_internal/models/format_control.py | 27 +- .../pip/_internal/models/index.py | 3 + .../pip/_internal/models/link.py | 70 +- .../pip/_internal/models/search_scope.py | 38 +- .../pip/_internal/models/selection_prefs.py | 4 +- .../pip/_internal/models/target_python.py | 32 +- .../__pycache__/__init__.cpython-38.pyc | Bin 157 -> 194 bytes .../__pycache__/check.cpython-38.pyc | Bin 3663 -> 3628 bytes .../__pycache__/freeze.cpython-38.pyc | Bin 5727 -> 5926 bytes .../__pycache__/prepare.cpython-38.pyc | Bin 5744 -> 11508 bytes .../pip/_internal/operations/check.py | 19 +- .../pip/_internal/operations/freeze.py | 95 +- .../pip/_internal/operations/prepare.py | 597 +++- .../site-packages/pip/_internal/pep425tags.py | 384 --- .../site-packages/pip/_internal/pyproject.py | 39 +- .../pip/_internal/req/__init__.py | 89 +- .../req/__pycache__/__init__.cpython-38.pyc | Bin 1697 -> 2476 bytes .../__pycache__/constructors.cpython-38.pyc | Bin 7969 -> 11262 bytes .../req/__pycache__/req_file.cpython-38.pyc | Bin 9374 -> 13228 bytes .../__pycache__/req_install.cpython-38.pyc | Bin 25727 -> 21487 bytes .../req/__pycache__/req_set.cpython-38.pyc | Bin 5690 -> 5860 bytes .../__pycache__/req_tracker.cpython-38.pyc | Bin 3222 -> 4118 bytes .../__pycache__/req_uninstall.cpython-38.pyc | Bin 17349 -> 17483 bytes .../pip/_internal/req/constructors.py | 333 +- .../pip/_internal/req/req_file.py | 513 ++- .../pip/_internal/req/req_install.py | 954 +++--- .../pip/_internal/req/req_set.py | 136 +- .../pip/_internal/req/req_tracker.py | 116 +- .../pip/_internal/req/req_uninstall.py | 47 +- .../utils/__pycache__/__init__.cpython-38.pyc | Bin 152 -> 189 bytes .../utils/__pycache__/appdirs.cpython-38.pyc | Bin 8031 -> 1379 bytes .../utils/__pycache__/compat.cpython-38.pyc | Bin 6927 -> 6733 bytes .../__pycache__/deprecation.cpython-38.pyc | Bin 2823 -> 2860 bytes .../utils/__pycache__/encoding.cpython-38.pyc | Bin 1244 -> 1325 bytes .../__pycache__/filesystem.cpython-38.pyc | Bin 623 -> 5638 bytes .../utils/__pycache__/glibc.cpython-38.pyc | Bin 2254 -> 1742 bytes .../utils/__pycache__/hashes.cpython-38.pyc | Bin 4141 -> 4645 bytes .../utils/__pycache__/logging.cpython-38.pyc | Bin 9117 -> 9213 bytes .../__pycache__/marker_files.cpython-38.pyc | Bin 763 -> 0 bytes .../utils/__pycache__/misc.cpython-38.pyc | Bin 29848 -> 25054 bytes .../utils/__pycache__/models.cpython-38.pyc | Bin 1921 -> 1989 bytes .../utils/__pycache__/outdated.cpython-38.pyc | Bin 4208 -> 0 bytes .../__pycache__/packaging.cpython-38.pyc | Bin 2605 -> 2642 bytes .../setuptools_build.cpython-38.pyc | Bin 1014 -> 2955 bytes .../utils/__pycache__/temp_dir.cpython-38.pyc | Bin 4872 -> 7123 bytes .../utils/__pycache__/typing.cpython-38.pyc | Bin 1282 -> 1471 bytes .../utils/__pycache__/ui.cpython-38.pyc | Bin 11807 -> 0 bytes .../__pycache__/virtualenv.cpython-38.pyc | Bin 875 -> 3358 bytes .../pip/_internal/utils/appdirs.py | 260 +- .../pip/_internal/utils/compat.py | 132 +- .../pip/_internal/utils/deprecation.py | 4 + .../pip/_internal/utils/encoding.py | 4 +- .../pip/_internal/utils/filesystem.py | 196 +- .../pip/_internal/utils/glibc.py | 34 +- .../pip/_internal/utils/hashes.py | 29 +- .../pip/_internal/utils/logging.py | 13 +- .../pip/_internal/utils/marker_files.py | 20 - .../site-packages/pip/_internal/utils/misc.py | 800 ++--- .../pip/_internal/utils/models.py | 4 + .../pip/_internal/utils/outdated.py | 178 -- .../pip/_internal/utils/setuptools_build.py | 155 +- .../pip/_internal/utils/temp_dir.py | 193 +- .../pip/_internal/utils/typing.py | 9 + .../site-packages/pip/_internal/utils/ui.py | 424 --- .../pip/_internal/utils/virtualenv.py | 119 +- .../pip/_internal/vcs/__init__.py | 9 +- .../vcs/__pycache__/__init__.cpython-38.pyc | Bin 428 -> 482 bytes .../vcs/__pycache__/bazaar.cpython-38.pyc | Bin 3404 -> 3744 bytes .../vcs/__pycache__/git.cpython-38.pyc | Bin 8960 -> 9592 bytes .../vcs/__pycache__/mercurial.cpython-38.pyc | Bin 3691 -> 5026 bytes .../vcs/__pycache__/subversion.cpython-38.pyc | Bin 8344 -> 8529 bytes .../__pycache__/versioncontrol.cpython-38.pyc | Bin 17074 -> 21033 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 34 +- .../site-packages/pip/_internal/vcs/git.py | 141 +- .../pip/_internal/vcs/mercurial.py | 83 +- .../pip/_internal/vcs/subversion.py | 76 +- .../pip/_internal/vcs/versioncontrol.py | 295 +- .../site-packages/pip/_internal/wheel.py | 1125 ------- .../site-packages/pip/_vendor/__init__.py | 23 +- .../__pycache__/__init__.cpython-38.pyc | Bin 2823 -> 2971 bytes .../__pycache__/appdirs.cpython-38.pyc | Bin 20434 -> 21439 bytes .../_vendor/__pycache__/distro.cpython-38.pyc | Bin 36538 -> 36894 bytes .../__pycache__/ipaddress.cpython-38.pyc | Bin 64779 -> 64822 bytes .../__pycache__/pyparsing.cpython-38.pyc | Bin 220202 -> 240882 bytes .../__pycache__/retrying.cpython-38.pyc | Bin 8003 -> 8040 bytes .../_vendor/__pycache__/six.cpython-38.pyc | Bin 26393 -> 26921 bytes .../site-packages/pip/_vendor/appdirs.py | 45 +- .../pip/_vendor/cachecontrol/__init__.py | 2 +- .../__pycache__/__init__.cpython-38.pyc | Bin 510 -> 547 bytes .../__pycache__/_cmd.cpython-38.pyc | Bin 1537 -> 1574 bytes .../__pycache__/adapter.cpython-38.pyc | Bin 3036 -> 3081 bytes .../__pycache__/cache.cpython-38.pyc | Bin 1743 -> 1780 bytes .../__pycache__/compat.cpython-38.pyc | Bin 717 -> 754 bytes .../__pycache__/controller.cpython-38.pyc | Bin 7657 -> 7785 bytes .../__pycache__/filewrapper.cpython-38.pyc | Bin 2136 -> 2173 bytes .../__pycache__/heuristics.cpython-38.pyc | Bin 4695 -> 4732 bytes .../__pycache__/serialize.cpython-38.pyc | Bin 4208 -> 4234 bytes .../__pycache__/wrapper.cpython-38.pyc | Bin 626 -> 671 bytes .../pip/_vendor/cachecontrol/adapter.py | 2 +- .../__pycache__/__init__.cpython-38.pyc | Bin 254 -> 291 bytes .../__pycache__/file_cache.cpython-38.pyc | Bin 3252 -> 3265 bytes .../__pycache__/redis_cache.cpython-38.pyc | Bin 1526 -> 1563 bytes .../_vendor/cachecontrol/caches/file_cache.py | 4 +- .../pip/_vendor/cachecontrol/controller.py | 11 +- .../pip/_vendor/cachecontrol/serialize.py | 4 +- .../pip/_vendor/cachecontrol/wrapper.py | 2 +- .../pip/_vendor/certifi/__init__.py | 4 +- .../pip/_vendor/certifi/__main__.py | 14 +- .../__pycache__/__init__.cpython-38.pyc | Bin 217 -> 273 bytes .../__pycache__/__main__.cpython-38.pyc | Bin 220 -> 450 bytes .../certifi/__pycache__/core.cpython-38.pyc | Bin 433 -> 1170 bytes .../pip/_vendor/certifi/cacert.pem | 416 +-- .../site-packages/pip/_vendor/certifi/core.py | 53 +- .../__pycache__/__init__.cpython-38.pyc | Bin 810 -> 847 bytes .../__pycache__/big5freq.cpython-38.pyc | Bin 27139 -> 27176 bytes .../__pycache__/big5prober.cpython-38.pyc | Bin 1094 -> 1131 bytes .../chardistribution.cpython-38.pyc | Bin 6180 -> 6217 bytes .../charsetgroupprober.cpython-38.pyc | Bin 2211 -> 2248 bytes .../__pycache__/charsetprober.cpython-38.pyc | Bin 3443 -> 3480 bytes .../codingstatemachine.cpython-38.pyc | Bin 2870 -> 2907 bytes .../chardet/__pycache__/compat.cpython-38.pyc | Bin 315 -> 352 bytes .../__pycache__/cp949prober.cpython-38.pyc | Bin 1101 -> 1138 bytes .../chardet/__pycache__/enums.cpython-38.pyc | Bin 2608 -> 2645 bytes .../__pycache__/escprober.cpython-38.pyc | Bin 2593 -> 2630 bytes .../chardet/__pycache__/escsm.cpython-38.pyc | Bin 7434 -> 7471 bytes .../__pycache__/eucjpprober.cpython-38.pyc | Bin 2411 -> 2448 bytes .../__pycache__/euckrfreq.cpython-38.pyc | Bin 12023 -> 12060 bytes .../__pycache__/euckrprober.cpython-38.pyc | Bin 1102 -> 1139 bytes .../__pycache__/euctwfreq.cpython-38.pyc | Bin 27143 -> 27180 bytes .../__pycache__/euctwprober.cpython-38.pyc | Bin 1102 -> 1139 bytes .../__pycache__/gb2312freq.cpython-38.pyc | Bin 19067 -> 19104 bytes .../__pycache__/gb2312prober.cpython-38.pyc | Bin 1110 -> 1147 bytes .../__pycache__/hebrewprober.cpython-38.pyc | Bin 2983 -> 3020 bytes .../__pycache__/jisfreq.cpython-38.pyc | Bin 22095 -> 22132 bytes .../chardet/__pycache__/jpcntx.cpython-38.pyc | Bin 37568 -> 37605 bytes .../langbulgarianmodel.cpython-38.pyc | Bin 23592 -> 23629 bytes .../langcyrillicmodel.cpython-38.pyc | Bin 29056 -> 29093 bytes .../__pycache__/langgreekmodel.cpython-38.pyc | Bin 23550 -> 23587 bytes .../langhebrewmodel.cpython-38.pyc | Bin 22177 -> 22214 bytes .../langhungarianmodel.cpython-38.pyc | Bin 23581 -> 23618 bytes .../__pycache__/langthaimodel.cpython-38.pyc | Bin 22156 -> 22193 bytes .../langturkishmodel.cpython-38.pyc | Bin 22179 -> 22216 bytes .../__pycache__/latin1prober.cpython-38.pyc | Bin 3363 -> 3400 bytes .../mbcharsetprober.cpython-38.pyc | Bin 2226 -> 2263 bytes .../mbcsgroupprober.cpython-38.pyc | Bin 1091 -> 1128 bytes .../chardet/__pycache__/mbcssm.cpython-38.pyc | Bin 16714 -> 16751 bytes .../sbcharsetprober.cpython-38.pyc | Bin 2979 -> 3016 bytes .../sbcsgroupprober.cpython-38.pyc | Bin 1589 -> 1626 bytes .../__pycache__/sjisprober.cpython-38.pyc | Bin 2447 -> 2484 bytes .../universaldetector.cpython-38.pyc | Bin 5791 -> 5828 bytes .../__pycache__/utf8prober.cpython-38.pyc | Bin 1952 -> 1989 bytes .../__pycache__/version.cpython-38.pyc | Bin 399 -> 436 bytes .../cli/__pycache__/__init__.cpython-38.pyc | Bin 156 -> 193 bytes .../cli/__pycache__/chardetect.cpython-38.pyc | Bin 2657 -> 2694 bytes .../pip/_vendor/colorama/__init__.py | 2 +- .../__pycache__/__init__.cpython-38.pyc | Bin 404 -> 441 bytes .../colorama/__pycache__/ansi.cpython-38.pyc | Bin 3189 -> 3226 bytes .../__pycache__/ansitowin32.cpython-38.pyc | Bin 7698 -> 7735 bytes .../__pycache__/initialise.cpython-38.pyc | Bin 1665 -> 1702 bytes .../colorama/__pycache__/win32.cpython-38.pyc | Bin 3941 -> 3978 bytes .../__pycache__/winterm.cpython-38.pyc | Bin 4625 -> 4662 bytes .../pip/_vendor/distlib/__init__.py | 2 +- .../__pycache__/__init__.cpython-38.pyc | Bin 1025 -> 1056 bytes .../distlib/__pycache__/compat.cpython-38.pyc | Bin 32168 -> 32222 bytes .../__pycache__/database.cpython-38.pyc | Bin 42065 -> 42113 bytes .../distlib/__pycache__/index.cpython-38.pyc | Bin 17372 -> 17409 bytes .../__pycache__/locators.cpython-38.pyc | Bin 38270 -> 38411 bytes .../__pycache__/manifest.cpython-38.pyc | Bin 10194 -> 10231 bytes .../__pycache__/markers.cpython-38.pyc | Bin 4458 -> 4495 bytes .../__pycache__/metadata.cpython-38.pyc | Bin 26605 -> 26403 bytes .../__pycache__/resources.cpython-38.pyc | Bin 10969 -> 11006 bytes .../__pycache__/scripts.cpython-38.pyc | Bin 10751 -> 10912 bytes .../distlib/__pycache__/util.cpython-38.pyc | Bin 48102 -> 48159 bytes .../__pycache__/version.cpython-38.pyc | Bin 20328 -> 20365 bytes .../distlib/__pycache__/wheel.cpython-38.pyc | Bin 25515 -> 25783 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 444 -> 481 bytes .../_backport/__pycache__/misc.cpython-38.pyc | Bin 1055 -> 1092 bytes .../__pycache__/shutil.cpython-38.pyc | Bin 21448 -> 21548 bytes .../__pycache__/sysconfig.cpython-38.pyc | Bin 15847 -> 15912 bytes .../__pycache__/tarfile.cpython-38.pyc | Bin 62704 -> 62741 bytes .../pip/_vendor/distlib/_backport/shutil.py | 9 +- .../_vendor/distlib/_backport/sysconfig.py | 8 +- .../pip/_vendor/distlib/compat.py | 2 +- .../pip/_vendor/distlib/database.py | 4 +- .../pip/_vendor/distlib/locators.py | 21 +- .../pip/_vendor/distlib/metadata.py | 122 +- .../pip/_vendor/distlib/scripts.py | 32 +- .../site-packages/pip/_vendor/distlib/t32.exe | Bin 92672 -> 96768 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 102912 -> 105984 bytes .../site-packages/pip/_vendor/distlib/util.py | 5 +- .../site-packages/pip/_vendor/distlib/w32.exe | Bin 89088 -> 90112 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 99840 -> 99840 bytes .../pip/_vendor/distlib/wheel.py | 40 +- .../site-packages/pip/_vendor/distro.py | 36 +- .../pip/_vendor/html5lib/__init__.py | 2 +- .../__pycache__/__init__.cpython-38.pyc | Bin 1277 -> 1312 bytes .../__pycache__/_ihatexml.cpython-38.pyc | Bin 13749 -> 13798 bytes .../__pycache__/_inputstream.cpython-38.pyc | Bin 21901 -> 21871 bytes .../__pycache__/_tokenizer.cpython-38.pyc | Bin 39619 -> 39900 bytes .../__pycache__/_utils.cpython-38.pyc | Bin 3307 -> 4815 bytes .../__pycache__/constants.cpython-38.pyc | Bin 66314 -> 66329 bytes .../__pycache__/html5parser.cpython-38.pyc | Bin 95136 -> 91273 bytes .../__pycache__/serializer.cpython-38.pyc | Bin 10785 -> 10823 bytes .../pip/_vendor/html5lib/_ihatexml.py | 5 +- .../pip/_vendor/html5lib/_inputstream.py | 55 +- .../pip/_vendor/html5lib/_tokenizer.py | 16 +- .../pip/_vendor/html5lib/_trie/__init__.py | 13 +- .../_trie/__pycache__/__init__.cpython-38.pyc | Bin 386 -> 350 bytes .../_trie/__pycache__/_base.cpython-38.pyc | Bin 1565 -> 1602 bytes .../_trie/__pycache__/datrie.cpython-38.pyc | Bin 1998 -> 0 bytes .../_trie/__pycache__/py.cpython-38.pyc | Bin 2222 -> 2259 bytes .../pip/_vendor/html5lib/_trie/datrie.py | 44 - .../pip/_vendor/html5lib/_utils.py | 49 +- .../pip/_vendor/html5lib/constants.py | 9 +- .../__pycache__/__init__.cpython-38.pyc | Bin 161 -> 198 bytes .../alphabeticalattributes.cpython-38.pyc | Bin 1283 -> 1320 bytes .../filters/__pycache__/base.cpython-38.pyc | Bin 831 -> 868 bytes .../inject_meta_charset.cpython-38.pyc | Bin 1837 -> 1874 bytes .../filters/__pycache__/lint.cpython-38.pyc | Bin 2595 -> 2632 bytes .../__pycache__/optionaltags.cpython-38.pyc | Bin 2724 -> 2761 bytes .../__pycache__/sanitizer.cpython-38.pyc | Bin 16266 -> 16907 bytes .../__pycache__/whitespace.cpython-38.pyc | Bin 1329 -> 1366 bytes .../pip/_vendor/html5lib/filters/sanitizer.py | 20 + .../pip/_vendor/html5lib/html5parser.py | 734 ++--- .../pip/_vendor/html5lib/serializer.py | 2 +- .../__pycache__/__init__.cpython-38.pyc | Bin 900 -> 937 bytes .../__pycache__/genshi.cpython-38.pyc | Bin 1506 -> 1543 bytes .../__pycache__/sax.cpython-38.pyc | Bin 1441 -> 1478 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 3285 -> 3322 bytes .../__pycache__/base.cpython-38.pyc | Bin 11311 -> 11335 bytes .../__pycache__/dom.cpython-38.pyc | Bin 9418 -> 9455 bytes .../__pycache__/etree.cpython-38.pyc | Bin 11805 -> 11837 bytes .../__pycache__/etree_lxml.cpython-38.pyc | Bin 11773 -> 13032 bytes .../pip/_vendor/html5lib/treebuilders/base.py | 8 +- .../_vendor/html5lib/treebuilders/etree.py | 27 +- .../html5lib/treebuilders/etree_lxml.py | 64 +- .../_vendor/html5lib/treewalkers/__init__.py | 6 +- .../__pycache__/__init__.cpython-38.pyc | Bin 3966 -> 4008 bytes .../__pycache__/base.cpython-38.pyc | Bin 6966 -> 7003 bytes .../__pycache__/dom.cpython-38.pyc | Bin 1695 -> 1732 bytes .../__pycache__/etree.cpython-38.pyc | Bin 3480 -> 3517 bytes .../__pycache__/etree_lxml.cpython-38.pyc | Bin 6579 -> 6670 bytes .../__pycache__/genshi.cpython-38.pyc | Bin 1853 -> 1890 bytes .../pip/_vendor/html5lib/treewalkers/etree.py | 1 + .../html5lib/treewalkers/etree_lxml.py | 4 +- .../idna/__pycache__/__init__.cpython-38.pyc | Bin 218 -> 255 bytes .../idna/__pycache__/codec.cpython-38.pyc | Bin 2872 -> 2909 bytes .../idna/__pycache__/compat.cpython-38.pyc | Bin 590 -> 627 bytes .../idna/__pycache__/core.cpython-38.pyc | Bin 9006 -> 9195 bytes .../idna/__pycache__/idnadata.cpython-38.pyc | Bin 21342 -> 22136 bytes .../idna/__pycache__/intranges.cpython-38.pyc | Bin 1770 -> 1807 bytes .../__pycache__/package_data.cpython-38.pyc | Bin 172 -> 210 bytes .../idna/__pycache__/uts46data.cpython-38.pyc | Bin 174145 -> 177456 bytes .../site-packages/pip/_vendor/idna/core.py | 6 +- .../pip/_vendor/idna/idnadata.py | 155 +- .../pip/_vendor/idna/package_data.py | 2 +- .../pip/_vendor/idna/uts46data.py | 846 +++-- .../site-packages/pip/_vendor/ipaddress.py | 5 +- .../pip/_vendor/lockfile/__init__.py | 347 -- .../__pycache__/__init__.cpython-38.pyc | Bin 9765 -> 0 bytes .../__pycache__/linklockfile.cpython-38.pyc | Bin 2273 -> 0 bytes .../__pycache__/mkdirlockfile.cpython-38.pyc | Bin 2641 -> 0 bytes .../__pycache__/pidlockfile.cpython-38.pyc | Bin 4845 -> 0 bytes .../__pycache__/sqlitelockfile.cpython-38.pyc | Bin 3700 -> 0 bytes .../symlinklockfile.cpython-38.pyc | Bin 2162 -> 0 bytes .../pip/_vendor/lockfile/linklockfile.py | 73 - .../pip/_vendor/lockfile/mkdirlockfile.py | 84 - .../pip/_vendor/lockfile/pidlockfile.py | 190 -- .../pip/_vendor/lockfile/sqlitelockfile.py | 156 - .../pip/_vendor/lockfile/symlinklockfile.py | 70 - .../pip/_vendor/msgpack/__init__.py | 31 +- .../__pycache__/__init__.cpython-38.pyc | Bin 1990 -> 1402 bytes .../__pycache__/_version.cpython-38.pyc | Bin 179 -> 216 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 1813 -> 1850 bytes .../__pycache__/fallback.cpython-38.pyc | Bin 26309 -> 25953 bytes .../pip/_vendor/msgpack/_version.py | 2 +- .../pip/_vendor/msgpack/fallback.py | 560 ++-- .../pip/_vendor/packaging/__about__.py | 4 +- .../__pycache__/__about__.cpython-38.pyc | Bin 694 -> 723 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 532 -> 569 bytes .../__pycache__/_compat.cpython-38.pyc | Bin 968 -> 1141 bytes .../__pycache__/_structures.cpython-38.pyc | Bin 2750 -> 2895 bytes .../__pycache__/markers.cpython-38.pyc | Bin 8875 -> 9321 bytes .../__pycache__/requirements.cpython-38.pyc | Bin 3973 -> 4096 bytes .../__pycache__/specifiers.cpython-38.pyc | Bin 19724 -> 20604 bytes .../__pycache__/utils.cpython-38.pyc | Bin 1425 -> 1658 bytes .../__pycache__/version.cpython-38.pyc | Bin 12055 -> 13333 bytes .../pip/_vendor/packaging/_compat.py | 9 +- .../pip/_vendor/packaging/_structures.py | 26 +- .../pip/_vendor/packaging/markers.py | 56 +- .../pip/_vendor/packaging/requirements.py | 9 +- .../pip/_vendor/packaging/specifiers.py | 190 +- .../pip/_vendor/packaging/utils.py | 18 +- .../pip/_vendor/packaging/version.py | 149 +- .../pip/_vendor/pep517/__init__.py | 2 +- .../__pycache__/__init__.cpython-38.pyc | Bin 243 -> 280 bytes .../__pycache__/_in_process.cpython-38.pyc | Bin 5501 -> 8143 bytes .../pep517/__pycache__/build.cpython-38.pyc | Bin 2757 -> 3394 bytes .../pep517/__pycache__/check.cpython-38.pyc | Bin 4726 -> 4814 bytes .../__pycache__/colorlog.cpython-38.pyc | Bin 2913 -> 2950 bytes .../pep517/__pycache__/compat.cpython-38.pyc | Bin 965 -> 1047 bytes .../__pycache__/envbuild.cpython-38.pyc | Bin 4245 -> 4444 bytes .../__pycache__/wrappers.cpython-38.pyc | Bin 5505 -> 10546 bytes .../pip/_vendor/pep517/_in_process.py | 95 +- .../site-packages/pip/_vendor/pep517/build.py | 80 +- .../site-packages/pip/_vendor/pep517/check.py | 7 +- .../pip/_vendor/pep517/compat.py | 13 +- .../pip/_vendor/pep517/envbuild.py | 29 +- .../pip/_vendor/pep517/wrappers.py | 183 +- .../pip/_vendor/pkg_resources/__init__.py | 20 +- .../__pycache__/__init__.cpython-38.pyc | Bin 100145 -> 100348 bytes .../__pycache__/py31compat.cpython-38.pyc | Bin 609 -> 646 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 5578 -> 5615 bytes .../progress/__pycache__/bar.cpython-38.pyc | Bin 2602 -> 2639 bytes .../__pycache__/counter.cpython-38.pyc | Bin 1434 -> 1471 bytes .../__pycache__/spinner.cpython-38.pyc | Bin 1361 -> 1398 bytes .../site-packages/pip/_vendor/pyparsing.py | 2790 ++++++++++------- .../pip/_vendor/pytoml/__init__.py | 4 - .../__pycache__/__init__.cpython-38.pyc | Bin 337 -> 0 bytes .../pytoml/__pycache__/core.cpython-38.pyc | Bin 914 -> 0 bytes .../pytoml/__pycache__/parser.cpython-38.pyc | Bin 10111 -> 0 bytes .../pytoml/__pycache__/test.cpython-38.pyc | Bin 1216 -> 0 bytes .../pytoml/__pycache__/utils.cpython-38.pyc | Bin 2126 -> 0 bytes .../pytoml/__pycache__/writer.cpython-38.pyc | Bin 3557 -> 0 bytes .../site-packages/pip/_vendor/pytoml/core.py | 13 - .../pip/_vendor/pytoml/parser.py | 341 -- .../site-packages/pip/_vendor/pytoml/test.py | 30 - .../site-packages/pip/_vendor/pytoml/utils.py | 67 - .../pip/_vendor/pytoml/writer.py | 106 - .../pip/_vendor/requests/__init__.py | 33 +- .../__pycache__/__init__.cpython-38.pyc | Bin 3464 -> 3656 bytes .../__pycache__/__version__.cpython-38.pyc | Bin 511 -> 553 bytes .../_internal_utils.cpython-38.pyc | Bin 1281 -> 1318 bytes .../__pycache__/adapters.cpython-38.pyc | Bin 16944 -> 16981 bytes .../requests/__pycache__/api.cpython-38.pyc | Bin 6468 -> 6733 bytes .../requests/__pycache__/auth.cpython-38.pyc | Bin 8290 -> 8337 bytes .../requests/__pycache__/certs.cpython-38.pyc | Bin 594 -> 631 bytes .../__pycache__/compat.cpython-38.pyc | Bin 1573 -> 1610 bytes .../__pycache__/cookies.cpython-38.pyc | Bin 18795 -> 18832 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 5205 -> 5239 bytes .../requests/__pycache__/help.cpython-38.pyc | Bin 2691 -> 2728 bytes .../requests/__pycache__/hooks.cpython-38.pyc | Bin 953 -> 990 bytes .../__pycache__/models.cpython-38.pyc | Bin 23889 -> 23931 bytes .../__pycache__/packages.cpython-38.pyc | Bin 463 -> 500 bytes .../__pycache__/sessions.cpython-38.pyc | Bin 19503 -> 19543 bytes .../__pycache__/status_codes.cpython-38.pyc | Bin 4149 -> 4245 bytes .../__pycache__/structures.cpython-38.pyc | Bin 4391 -> 4458 bytes .../requests/__pycache__/utils.cpython-38.pyc | Bin 22160 -> 22331 bytes .../pip/_vendor/requests/__version__.py | 8 +- .../site-packages/pip/_vendor/requests/api.py | 7 +- .../pip/_vendor/requests/auth.py | 4 +- .../pip/_vendor/requests/compat.py | 2 + .../pip/_vendor/requests/exceptions.py | 9 +- .../pip/_vendor/requests/models.py | 19 +- .../pip/_vendor/requests/sessions.py | 33 +- .../pip/_vendor/requests/status_codes.py | 15 +- .../pip/_vendor/requests/structures.py | 4 +- .../pip/_vendor/requests/utils.py | 11 +- .../site-packages/pip/_vendor/six.py | 88 +- .../pip/_vendor/urllib3/__init__.py | 55 +- .../__pycache__/__init__.cpython-38.pyc | Bin 2086 -> 2119 bytes .../__pycache__/_collections.cpython-38.pyc | Bin 10736 -> 10673 bytes .../__pycache__/connection.cpython-38.pyc | Bin 10529 -> 10350 bytes .../__pycache__/connectionpool.cpython-38.pyc | Bin 23841 -> 24041 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 10029 -> 10767 bytes .../urllib3/__pycache__/fields.cpython-38.pyc | Bin 8094 -> 8133 bytes .../__pycache__/filepost.cpython-38.pyc | Bin 2731 -> 2768 bytes .../__pycache__/poolmanager.cpython-38.pyc | Bin 12907 -> 13600 bytes .../__pycache__/request.cpython-38.pyc | Bin 5585 -> 5656 bytes .../__pycache__/response.cpython-38.pyc | Bin 20096 -> 20791 bytes .../pip/_vendor/urllib3/_collections.py | 37 +- .../pip/_vendor/urllib3/connection.py | 248 +- .../pip/_vendor/urllib3/connectionpool.py | 432 ++- .../__pycache__/__init__.cpython-38.pyc | Bin 160 -> 197 bytes .../_appengine_environ.cpython-38.pyc | Bin 1088 -> 1421 bytes .../__pycache__/appengine.cpython-38.pyc | Bin 8401 -> 8270 bytes .../__pycache__/ntlmpool.cpython-38.pyc | Bin 3227 -> 3278 bytes .../__pycache__/pyopenssl.cpython-38.pyc | Bin 14932 -> 15105 bytes .../securetransport.cpython-38.pyc | Bin 19860 -> 19868 bytes .../contrib/__pycache__/socks.cpython-38.pyc | Bin 5546 -> 5581 bytes .../urllib3/contrib/_appengine_environ.py | 26 +- .../__pycache__/__init__.cpython-38.pyc | Bin 177 -> 214 bytes .../__pycache__/bindings.cpython-38.pyc | Bin 10332 -> 10233 bytes .../__pycache__/low_level.cpython-38.pyc | Bin 7529 -> 7554 bytes .../contrib/_securetransport/bindings.py | 262 +- .../contrib/_securetransport/low_level.py | 52 +- .../pip/_vendor/urllib3/contrib/appengine.py | 121 +- .../pip/_vendor/urllib3/contrib/ntlmpool.py | 96 +- .../pip/_vendor/urllib3/contrib/pyopenssl.py | 138 +- .../urllib3/contrib/securetransport.py | 165 +- .../pip/_vendor/urllib3/contrib/socks.py | 101 +- .../pip/_vendor/urllib3/exceptions.py | 48 +- .../pip/_vendor/urllib3/fields.py | 93 +- .../pip/_vendor/urllib3/filepost.py | 14 +- .../pip/_vendor/urllib3/packages/__init__.py | 2 +- .../__pycache__/__init__.cpython-38.pyc | Bin 274 -> 311 bytes .../packages/__pycache__/six.cpython-38.pyc | Bin 24434 -> 26523 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 171 -> 208 bytes .../__pycache__/makefile.cpython-38.pyc | Bin 1275 -> 1312 bytes .../urllib3/packages/backports/makefile.py | 9 +- .../urllib3/packages/rfc3986/__init__.py | 56 - .../__pycache__/__init__.cpython-38.pyc | Bin 1008 -> 0 bytes .../rfc3986/__pycache__/_mixin.cpython-38.pyc | Bin 10609 -> 0 bytes .../__pycache__/abnf_regexp.cpython-38.pyc | Bin 4112 -> 0 bytes .../rfc3986/__pycache__/api.cpython-38.pyc | Bin 3673 -> 0 bytes .../__pycache__/builder.cpython-38.pyc | Bin 8115 -> 0 bytes .../rfc3986/__pycache__/compat.cpython-38.pyc | Bin 1110 -> 0 bytes .../__pycache__/exceptions.cpython-38.pyc | Bin 4749 -> 0 bytes .../rfc3986/__pycache__/iri.cpython-38.pyc | Bin 4464 -> 0 bytes .../rfc3986/__pycache__/misc.cpython-38.pyc | Bin 2229 -> 0 bytes .../__pycache__/normalizers.cpython-38.pyc | Bin 3542 -> 0 bytes .../__pycache__/parseresult.cpython-38.pyc | Bin 9856 -> 0 bytes .../rfc3986/__pycache__/uri.cpython-38.pyc | Bin 4237 -> 0 bytes .../__pycache__/validators.cpython-38.pyc | Bin 12997 -> 0 bytes .../urllib3/packages/rfc3986/_mixin.py | 353 --- .../urllib3/packages/rfc3986/abnf_regexp.py | 267 -- .../_vendor/urllib3/packages/rfc3986/api.py | 106 - .../urllib3/packages/rfc3986/builder.py | 298 -- .../urllib3/packages/rfc3986/compat.py | 54 - .../urllib3/packages/rfc3986/exceptions.py | 118 - .../_vendor/urllib3/packages/rfc3986/iri.py | 147 - .../_vendor/urllib3/packages/rfc3986/misc.py | 124 - .../urllib3/packages/rfc3986/normalizers.py | 167 - .../urllib3/packages/rfc3986/parseresult.py | 385 --- .../_vendor/urllib3/packages/rfc3986/uri.py | 153 - .../urllib3/packages/rfc3986/validators.py | 450 --- .../pip/_vendor/urllib3/packages/six.py | 323 +- .../packages/ssl_match_hostname/__init__.py | 2 +- .../__pycache__/__init__.cpython-38.pyc | Bin 515 -> 552 bytes .../_implementation.cpython-38.pyc | Bin 3288 -> 3333 bytes .../ssl_match_hostname/_implementation.py | 56 +- .../pip/_vendor/urllib3/poolmanager.py | 207 +- .../pip/_vendor/urllib3/request.py | 79 +- .../pip/_vendor/urllib3/response.py | 209 +- .../pip/_vendor/urllib3/util/__init__.py | 60 +- .../util/__pycache__/__init__.cpython-38.pyc | Bin 980 -> 1017 bytes .../__pycache__/connection.cpython-38.pyc | Bin 3153 -> 3190 bytes .../util/__pycache__/queue.cpython-38.pyc | Bin 1025 -> 1062 bytes .../util/__pycache__/request.cpython-38.pyc | Bin 3307 -> 3356 bytes .../util/__pycache__/response.cpython-38.pyc | Bin 1950 -> 1983 bytes .../util/__pycache__/retry.cpython-38.pyc | Bin 12901 -> 13041 bytes .../util/__pycache__/ssl_.cpython-38.pyc | Bin 9779 -> 10132 bytes .../util/__pycache__/timeout.cpython-38.pyc | Bin 8781 -> 8894 bytes .../util/__pycache__/url.cpython-38.pyc | Bin 7846 -> 10727 bytes .../util/__pycache__/wait.cpython-38.pyc | Bin 3074 -> 3111 bytes .../pip/_vendor/urllib3/util/connection.py | 18 +- .../pip/_vendor/urllib3/util/request.py | 52 +- .../pip/_vendor/urllib3/util/response.py | 9 +- .../pip/_vendor/urllib3/util/retry.py | 103 +- .../pip/_vendor/urllib3/util/ssl_.py | 190 +- .../pip/_vendor/urllib3/util/timeout.py | 84 +- .../pip/_vendor/urllib3/util/url.py | 353 ++- .../pip/_vendor/urllib3/util/wait.py | 3 + .../__pycache__/__init__.cpython-38.pyc | Bin 9700 -> 9737 bytes .../__pycache__/labels.cpython-38.pyc | Bin 3798 -> 3835 bytes .../__pycache__/mklabels.cpython-38.pyc | Bin 1894 -> 1931 bytes .../__pycache__/tests.cpython-38.pyc | Bin 5060 -> 5097 bytes .../__pycache__/x_user_defined.cpython-38.pyc | Bin 2628 -> 2665 bytes .../site-packages/pkg_resources/__init__.py | 153 +- .../__pycache__/__init__.cpython-38.pyc | Bin 100342 -> 100474 bytes .../__pycache__/py31compat.cpython-38.pyc | Bin 604 -> 0 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 161 -> 191 bytes .../__pycache__/appdirs.cpython-38.pyc | Bin 20514 -> 20544 bytes .../__pycache__/pyparsing.cpython-38.pyc | Bin 201638 -> 201668 bytes .../_vendor/__pycache__/six.cpython-38.pyc | Bin 24434 -> 24464 bytes .../_vendor/packaging/__about__.py | 14 +- .../_vendor/packaging/__init__.py | 20 +- .../__pycache__/__about__.cpython-38.pyc | Bin 711 -> 741 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 549 -> 579 bytes .../__pycache__/_compat.cpython-38.pyc | Bin 985 -> 1015 bytes .../__pycache__/_structures.cpython-38.pyc | Bin 2767 -> 2797 bytes .../__pycache__/markers.cpython-38.pyc | Bin 8923 -> 8967 bytes .../__pycache__/requirements.cpython-38.pyc | Bin 3882 -> 4038 bytes .../__pycache__/specifiers.cpython-38.pyc | Bin 19791 -> 19771 bytes .../__pycache__/utils.cpython-38.pyc | Bin 470 -> 1472 bytes .../__pycache__/version.cpython-38.pyc | Bin 10638 -> 12102 bytes .../_vendor/packaging/_compat.py | 7 +- .../_vendor/packaging/_structures.py | 4 +- .../_vendor/packaging/markers.py | 91 +- .../_vendor/packaging/requirements.py | 41 +- .../_vendor/packaging/specifiers.py | 71 +- .../pkg_resources/_vendor/packaging/utils.py | 43 + .../_vendor/packaging/version.py | 149 +- .../pkg_resources/extern/__init__.py | 7 - .../__pycache__/__init__.cpython-38.pyc | Bin 2410 -> 2388 bytes .../site-packages/pkg_resources/py31compat.py | 23 - .../setuptools-41.2.0.dist-info/INSTALLER | 1 - .../setuptools-41.2.0.dist-info/LICENSE | 19 - .../setuptools-41.2.0.dist-info/METADATA | 77 - .../setuptools-41.2.0.dist-info/RECORD | 186 -- .../setuptools-41.2.0.dist-info/WHEEL | 6 - .../dependency_links.txt | 2 - .../entry_points.txt | 65 - .../setuptools-41.2.0.dist-info/top_level.txt | 3 - .../setuptools-41.2.0.dist-info/zip-safe | 1 - .../site-packages/setuptools/__init__.py | 47 +- .../__pycache__/__init__.cpython-38.pyc | Bin 7772 -> 8864 bytes .../_deprecation_warning.cpython-38.pyc | Bin 520 -> 550 bytes .../__pycache__/archive_util.cpython-38.pyc | Bin 5132 -> 5193 bytes .../__pycache__/build_meta.cpython-38.pyc | Bin 8499 -> 8558 bytes .../__pycache__/config.cpython-38.pyc | Bin 17780 -> 19367 bytes .../__pycache__/dep_util.cpython-38.pyc | Bin 823 -> 857 bytes .../__pycache__/depends.cpython-38.pyc | Bin 5292 -> 5250 bytes .../__pycache__/dist.cpython-38.pyc | Bin 42151 -> 33066 bytes .../__pycache__/extension.cpython-38.pyc | Bin 1965 -> 1995 bytes .../__pycache__/glibc.cpython-38.pyc | Bin 1534 -> 0 bytes .../__pycache__/glob.cpython-38.pyc | Bin 3737 -> 3767 bytes .../__pycache__/launch.cpython-38.pyc | Bin 828 -> 881 bytes .../__pycache__/lib2to3_ex.cpython-38.pyc | Bin 2415 -> 2746 bytes .../__pycache__/monkey.cpython-38.pyc | Bin 4648 -> 4678 bytes .../__pycache__/msvc.cpython-38.pyc | Bin 34444 -> 43204 bytes .../__pycache__/namespaces.cpython-38.pyc | Bin 3620 -> 3650 bytes .../__pycache__/package_index.cpython-38.pyc | Bin 32965 -> 33142 bytes .../__pycache__/pep425tags.cpython-38.pyc | Bin 7207 -> 0 bytes .../__pycache__/py27compat.cpython-38.pyc | Bin 788 -> 1783 bytes .../__pycache__/py31compat.cpython-38.pyc | Bin 1195 -> 1225 bytes .../__pycache__/py33compat.cpython-38.pyc | Bin 1412 -> 1442 bytes .../__pycache__/sandbox.cpython-38.pyc | Bin 15540 -> 15530 bytes .../__pycache__/site-patch.cpython-38.pyc | Bin 1478 -> 0 bytes .../__pycache__/ssl_support.cpython-38.pyc | Bin 6859 -> 6907 bytes .../__pycache__/unicode_utils.cpython-38.pyc | Bin 1155 -> 1185 bytes .../__pycache__/version.cpython-38.pyc | Bin 296 -> 326 bytes .../__pycache__/wheel.cpython-38.pyc | Bin 7058 -> 7325 bytes .../windows_support.cpython-38.pyc | Bin 993 -> 1023 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 158 -> 188 bytes .../__pycache__/pyparsing.cpython-38.pyc | Bin 201635 -> 201665 bytes .../_vendor/__pycache__/six.cpython-38.pyc | Bin 24431 -> 24461 bytes .../setuptools/_vendor/packaging/__about__.py | 14 +- .../setuptools/_vendor/packaging/__init__.py | 20 +- .../__pycache__/__about__.cpython-38.pyc | Bin 708 -> 738 bytes .../__pycache__/__init__.cpython-38.pyc | Bin 546 -> 576 bytes .../__pycache__/_compat.cpython-38.pyc | Bin 982 -> 1012 bytes .../__pycache__/_structures.cpython-38.pyc | Bin 2764 -> 2794 bytes .../__pycache__/markers.cpython-38.pyc | Bin 8917 -> 8961 bytes .../__pycache__/requirements.cpython-38.pyc | Bin 3873 -> 4029 bytes .../__pycache__/specifiers.cpython-38.pyc | Bin 19788 -> 19768 bytes .../__pycache__/utils.cpython-38.pyc | Bin 467 -> 1469 bytes .../__pycache__/version.cpython-38.pyc | Bin 10635 -> 12099 bytes .../setuptools/_vendor/packaging/_compat.py | 7 +- .../_vendor/packaging/_structures.py | 4 +- .../setuptools/_vendor/packaging/markers.py | 91 +- .../_vendor/packaging/requirements.py | 41 +- .../_vendor/packaging/specifiers.py | 71 +- .../setuptools/_vendor/packaging/utils.py | 43 + .../setuptools/_vendor/packaging/version.py | 149 +- .../site-packages/setuptools/archive_util.py | 10 +- .../site-packages/setuptools/build_meta.py | 34 +- .../setuptools/command/__init__.py | 3 +- .../__pycache__/__init__.cpython-38.pyc | Bin 742 -> 746 bytes .../command/__pycache__/alias.cpython-38.pyc | Bin 2396 -> 2426 bytes .../__pycache__/bdist_egg.cpython-38.pyc | Bin 14182 -> 14457 bytes .../__pycache__/bdist_rpm.cpython-38.pyc | Bin 1788 -> 1818 bytes .../__pycache__/bdist_wininst.cpython-38.pyc | Bin 958 -> 1219 bytes .../__pycache__/build_clib.cpython-38.pyc | Bin 2441 -> 2468 bytes .../__pycache__/build_ext.cpython-38.pyc | Bin 9899 -> 10035 bytes .../__pycache__/build_py.cpython-38.pyc | Bin 8645 -> 8877 bytes .../__pycache__/develop.cpython-38.pyc | Bin 6505 -> 6508 bytes .../__pycache__/dist_info.cpython-38.pyc | Bin 1365 -> 1395 bytes .../__pycache__/easy_install.cpython-38.pyc | Bin 65266 -> 65222 bytes .../__pycache__/egg_info.cpython-38.pyc | Bin 21768 -> 21779 bytes .../__pycache__/install.cpython-38.pyc | Bin 3995 -> 4050 bytes .../install_egg_info.cpython-38.pyc | Bin 2407 -> 2437 bytes .../__pycache__/install_lib.cpython-38.pyc | Bin 4128 -> 4164 bytes .../install_scripts.cpython-38.pyc | Bin 2277 -> 2358 bytes .../__pycache__/py36compat.cpython-38.pyc | Bin 4614 -> 4644 bytes .../__pycache__/register.cpython-38.pyc | Bin 759 -> 845 bytes .../command/__pycache__/rotate.cpython-38.pyc | Bin 2524 -> 2575 bytes .../__pycache__/saveopts.cpython-38.pyc | Bin 893 -> 923 bytes .../command/__pycache__/sdist.cpython-38.pyc | Bin 6811 -> 7893 bytes .../command/__pycache__/setopt.cpython-38.pyc | Bin 4541 -> 4571 bytes .../command/__pycache__/test.cpython-38.pyc | Bin 8244 -> 8519 bytes .../command/__pycache__/upload.cpython-38.pyc | Bin 5207 -> 818 bytes .../__pycache__/upload_docs.cpython-38.pyc | Bin 6144 -> 6171 bytes .../setuptools/command/bdist_egg.py | 16 +- .../setuptools/command/bdist_wininst.py | 9 + .../setuptools/command/build_clib.py | 61 +- .../setuptools/command/build_ext.py | 17 +- .../setuptools/command/build_py.py | 6 + .../setuptools/command/develop.py | 3 +- .../setuptools/command/easy_install.py | 171 +- .../setuptools/command/egg_info.py | 18 +- .../setuptools/command/install.py | 2 +- .../setuptools/command/install_lib.py | 3 +- .../setuptools/command/install_scripts.py | 7 +- .../setuptools/command/py36compat.py | 2 +- .../setuptools/command/register.py | 22 +- .../setuptools/command/rotate.py | 4 +- .../site-packages/setuptools/command/sdist.py | 67 +- .../site-packages/setuptools/command/test.py | 15 +- .../setuptools/command/upload.py | 195 +- .../setuptools/command/upload_docs.py | 10 +- .../site-packages/setuptools/config.py | 61 +- .../site-packages/setuptools/dep_util.py | 4 +- .../site-packages/setuptools/depends.py | 48 +- .../site-packages/setuptools/dist.py | 397 +-- .../setuptools/extern/__init__.py | 9 +- .../__pycache__/__init__.cpython-38.pyc | Bin 2411 -> 2411 bytes .../site-packages/setuptools/glibc.py | 86 - .../site-packages/setuptools/launch.py | 3 +- .../site-packages/setuptools/lib2to3_ex.py | 9 + .../site-packages/setuptools/msvc.py | 1208 +++++-- .../site-packages/setuptools/namespaces.py | 16 +- .../site-packages/setuptools/package_index.py | 22 +- .../site-packages/setuptools/pep425tags.py | 319 -- .../site-packages/setuptools/py27compat.py | 34 +- .../site-packages/setuptools/sandbox.py | 13 +- .../site-packages/setuptools/site-patch.py | 74 - .../site-packages/setuptools/ssl_support.py | 23 +- .../site-packages/setuptools/wheel.py | 34 +- venv/pyvenv.cfg | 2 +- www/about.html | 2 +- www/assets/style.css | 272 +- www/blog/contar_con_hashmaps_java.html | 72 +- www/blog/index.html | 2 +- www/blog/olvido_sobre_git.html | 30 +- www/blog/olvido_sobre_sql.html | 57 +- www/index.html | 2 +- www/now.html | 2 +- www/projects.html | 2 +- www/random.html | 2 +- www/setup.html | 140 +- 820 files changed, 15495 insertions(+), 22017 deletions(-) create mode 100644 .gitignore create mode 100644 requirements.txt delete mode 100644 venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/INSTALLER delete mode 100644 venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/LICENSE.md delete mode 100644 venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/METADATA delete mode 100644 venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/RECORD delete mode 100644 venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/WHEEL delete mode 100644 venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/entry_points.txt delete mode 100644 venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/top_level.txt delete mode 100644 venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/INSTALLER delete mode 100644 venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/LICENSE.txt delete mode 100644 venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/METADATA delete mode 100644 venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/RECORD delete mode 100644 venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/WHEEL delete mode 100644 venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/entry_points.txt delete mode 100644 venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/top_level.txt delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/download.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/index.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/legacy_resolve.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/pep425tags.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/__pycache__/wheel.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/source.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/distributions/source.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/download.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/index.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/legacy_resolve.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/pep425tags.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/marker_files.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/outdated.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/ui.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/marker_files.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/outdated.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/utils/ui.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_internal/wheel.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/datrie.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/lockfile/linklockfile.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/lockfile/mkdirlockfile.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/lockfile/pidlockfile.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/lockfile/sqlitelockfile.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/lockfile/symlinklockfile.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/core.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/parser.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/test.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/utils.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/writer.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/pytoml/core.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/pytoml/parser.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/pytoml/test.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/pytoml/utils.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/pytoml/writer.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__init__.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/__init__.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/_mixin.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/abnf_regexp.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/api.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/builder.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/compat.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/exceptions.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/iri.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/misc.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/normalizers.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/parseresult.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/uri.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/validators.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/_mixin.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/abnf_regexp.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/api.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/builder.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/compat.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/exceptions.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/iri.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/misc.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/normalizers.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/parseresult.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/uri.py delete mode 100644 venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/validators.py delete mode 100644 venv/lib/python3.8/site-packages/pkg_resources/__pycache__/py31compat.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/pkg_resources/py31compat.py delete mode 100644 venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/INSTALLER delete mode 100644 venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/LICENSE delete mode 100644 venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/METADATA delete mode 100644 venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/RECORD delete mode 100644 venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/WHEEL delete mode 100644 venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/dependency_links.txt delete mode 100644 venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/entry_points.txt delete mode 100644 venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/top_level.txt delete mode 100644 venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/zip-safe delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/glibc.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/pep425tags.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/__pycache__/site-patch.cpython-38.pyc delete mode 100644 venv/lib/python3.8/site-packages/setuptools/glibc.py delete mode 100644 venv/lib/python3.8/site-packages/setuptools/pep425tags.py delete mode 100644 venv/lib/python3.8/site-packages/setuptools/site-patch.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3459116 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +venv/ +www/ + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..b18e420 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +jinja2 +markdown +pygments diff --git a/template.html b/template.html index 10498ea..17a70a9 100755 --- a/template.html +++ b/template.html @@ -19,7 +19,7 @@ }); } - window.addEventListener('DOMContentLoaded', (event) => { + window.addEventListener('load', (event) => { makeImagesClickeable(); }); diff --git a/venv/bin/Activate.ps1 b/venv/bin/Activate.ps1 index 900f50e..2fb3852 100644 --- a/venv/bin/Activate.ps1 +++ b/venv/bin/Activate.ps1 @@ -1,6 +1,6 @@ <# .Synopsis -Activate a Python virtual environment for the current Powershell session. +Activate a Python virtual environment for the current PowerShell session. .Description Pushes the python executable for a virtual environment to the front of the @@ -37,6 +37,15 @@ 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( @@ -137,7 +146,7 @@ function Get-PyVenvConfig( $val = $keyval[1] # Remove extraneous quotations around a string value. - if ("'""".Contains($val.Substring(0,1))) { + if ("'""".Contains($val.Substring(0, 1))) { $val = $val.Substring(1, $val.Length - 2) } @@ -165,7 +174,8 @@ Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" # VenvExecDir if specified on the command line. if ($VenvDir) { Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" -} else { +} +else { Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") Write-Verbose "VenvDir=$VenvDir" @@ -179,7 +189,8 @@ $pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir # just use the name of the virtual environment folder. if ($Prompt) { Write-Verbose "Prompt specified as argument, using '$Prompt'" -} else { +} +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'])'" diff --git a/venv/bin/activate b/venv/bin/activate index 65245be..7420877 100644 --- a/venv/bin/activate +++ b/venv/bin/activate @@ -37,7 +37,7 @@ deactivate () { # unset irrelevant variables deactivate nondestructive -VIRTUAL_ENV="/home/ryuuji/src/generator/venv" +VIRTUAL_ENV="/home/ryuuji/src/danielcortes.xyz/venv" export VIRTUAL_ENV _OLD_VIRTUAL_PATH="$PATH" @@ -59,7 +59,7 @@ if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then else if [ "`basename \"$VIRTUAL_ENV\"`" = "__" ] ; then # special case for Aspen magic directories - # see http://www.zetadev.com/software/aspen/ + # see https://aspen.io/ PS1="[`basename \`dirname \"$VIRTUAL_ENV\"\``] $PS1" else PS1="(`basename \"$VIRTUAL_ENV\"`)$PS1" diff --git a/venv/bin/activate.csh b/venv/bin/activate.csh index 2b65f2f..2b5b120 100644 --- a/venv/bin/activate.csh +++ b/venv/bin/activate.csh @@ -8,7 +8,7 @@ alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PA # Unset irrelevant variables. deactivate nondestructive -setenv VIRTUAL_ENV "/home/ryuuji/src/generator/venv" +setenv VIRTUAL_ENV "/home/ryuuji/src/danielcortes.xyz/venv" set _OLD_VIRTUAL_PATH="$PATH" setenv PATH "$VIRTUAL_ENV/bin:$PATH" @@ -22,7 +22,7 @@ if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then else if (`basename "VIRTUAL_ENV"` == "__") then # special case for Aspen magic directories - # see http://www.zetadev.com/software/aspen/ + # see https://aspen.io/ set env_name = `basename \`dirname "$VIRTUAL_ENV"\`` else set env_name = `basename "$VIRTUAL_ENV"` diff --git a/venv/bin/activate.fish b/venv/bin/activate.fish index edcb526..a60de0f 100644 --- a/venv/bin/activate.fish +++ b/venv/bin/activate.fish @@ -29,7 +29,7 @@ end # unset irrelevant variables deactivate nondestructive -set -gx VIRTUAL_ENV "/home/ryuuji/src/generator/venv" +set -gx VIRTUAL_ENV "/home/ryuuji/src/danielcortes.xyz/venv" set -gx _OLD_VIRTUAL_PATH $PATH set -gx PATH "$VIRTUAL_ENV/bin" $PATH @@ -59,7 +59,7 @@ if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" set -l _checkbase (basename "$VIRTUAL_ENV") if test $_checkbase = "__" # special case for Aspen magic directories - # see http://www.zetadev.com/software/aspen/ + # see https://aspen.io/ printf "%s[%s]%s " (set_color -b blue white) (basename (dirname "$VIRTUAL_ENV")) (set_color normal) else printf "%s(%s)%s" (set_color -b blue white) (basename "$VIRTUAL_ENV") (set_color normal) diff --git a/venv/bin/easy_install b/venv/bin/easy_install index 5c40f51..b7a0820 100755 --- a/venv/bin/easy_install +++ b/venv/bin/easy_install @@ -1,10 +1,8 @@ -#!/home/ryuuji/src/generator/venv/bin/python +#!/home/ryuuji/src/danielcortes.xyz/venv/bin/python # -*- coding: utf-8 -*- import re import sys - from setuptools.command.easy_install import main - if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(main()) diff --git a/venv/bin/easy_install-3.8 b/venv/bin/easy_install-3.8 index 5c40f51..b7a0820 100755 --- a/venv/bin/easy_install-3.8 +++ b/venv/bin/easy_install-3.8 @@ -1,10 +1,8 @@ -#!/home/ryuuji/src/generator/venv/bin/python +#!/home/ryuuji/src/danielcortes.xyz/venv/bin/python # -*- coding: utf-8 -*- import re import sys - from setuptools.command.easy_install import main - if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(main()) diff --git a/venv/bin/markdown_py b/venv/bin/markdown_py index a851441..95e2f9e 100755 --- a/venv/bin/markdown_py +++ b/venv/bin/markdown_py @@ -1,10 +1,8 @@ -#!/home/ryuuji/src/generator/venv/bin/python +#!/home/ryuuji/src/danielcortes.xyz/venv/bin/python # -*- coding: utf-8 -*- import re import sys - from markdown.__main__ import run - if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(run()) diff --git a/venv/bin/pip b/venv/bin/pip index 9e49170..2674b75 100755 --- a/venv/bin/pip +++ b/venv/bin/pip @@ -1,10 +1,8 @@ -#!/home/ryuuji/src/generator/venv/bin/python +#!/home/ryuuji/src/danielcortes.xyz/venv/bin/python # -*- coding: utf-8 -*- import re import sys - -from pip._internal import main - +from pip._internal.cli.main import main if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(main()) diff --git a/venv/bin/pip3 b/venv/bin/pip3 index 9e49170..2674b75 100755 --- a/venv/bin/pip3 +++ b/venv/bin/pip3 @@ -1,10 +1,8 @@ -#!/home/ryuuji/src/generator/venv/bin/python +#!/home/ryuuji/src/danielcortes.xyz/venv/bin/python # -*- coding: utf-8 -*- import re import sys - -from pip._internal import main - +from pip._internal.cli.main import main if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(main()) diff --git a/venv/bin/pip3.8 b/venv/bin/pip3.8 index 9e49170..2674b75 100755 --- a/venv/bin/pip3.8 +++ b/venv/bin/pip3.8 @@ -1,10 +1,8 @@ -#!/home/ryuuji/src/generator/venv/bin/python +#!/home/ryuuji/src/danielcortes.xyz/venv/bin/python # -*- coding: utf-8 -*- import re import sys - -from pip._internal import main - +from pip._internal.cli.main import main if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(main()) diff --git a/venv/lib/python3.8/site-packages/Jinja2-2.11.2.dist-info/RECORD b/venv/lib/python3.8/site-packages/Jinja2-2.11.2.dist-info/RECORD index 413fef4..3a6cdaa 100644 --- a/venv/lib/python3.8/site-packages/Jinja2-2.11.2.dist-info/RECORD +++ b/venv/lib/python3.8/site-packages/Jinja2-2.11.2.dist-info/RECORD @@ -2,6 +2,7 @@ Jinja2-2.11.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuw Jinja2-2.11.2.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 Jinja2-2.11.2.dist-info/METADATA,sha256=5ZHRZoIRAMHsJPnqhlJ622_dRPsYePYJ-9EH4-Ry7yI,3535 Jinja2-2.11.2.dist-info/RECORD,, +Jinja2-2.11.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 Jinja2-2.11.2.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110 Jinja2-2.11.2.dist-info/entry_points.txt,sha256=Qy_DkVo6Xj_zzOtmErrATe8lHZhOqdjpt3e4JJAGyi8,61 Jinja2-2.11.2.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7 diff --git a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/INSTALLER b/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/INSTALLER deleted file mode 100644 index a1b589e..0000000 --- a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/LICENSE.md b/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/LICENSE.md deleted file mode 100644 index 2652d97..0000000 --- a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/LICENSE.md +++ /dev/null @@ -1,29 +0,0 @@ -Copyright 2007, 2008 The Python Markdown Project (v. 1.7 and later) -Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) -Copyright 2004 Manfred Stienstra (the original version) - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -* 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. -* Neither the name of the Python Markdown Project 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 PYTHON MARKDOWN PROJECT ''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 ANY CONTRIBUTORS TO THE PYTHON MARKDOWN PROJECT -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/METADATA b/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/METADATA deleted file mode 100644 index b80bb75..0000000 --- a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/METADATA +++ /dev/null @@ -1,57 +0,0 @@ -Metadata-Version: 2.1 -Name: Markdown -Version: 3.2.1 -Summary: Python implementation of Markdown. -Home-page: https://Python-Markdown.github.io/ -Author: Manfred Stienstra, Yuri takhteyev and Waylan limberg -Author-email: waylan.limberg@icloud.com -Maintainer: Waylan Limberg -Maintainer-email: waylan.limberg@icloud.com -License: BSD License -Download-URL: http://pypi.python.org/packages/source/M/Markdown/Markdown-3.2.1-py2.py3-none-any.whl -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: License :: OSI Approved :: BSD License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -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 :: Only -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Classifier: Topic :: Communications :: Email :: Filters -Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries -Classifier: Topic :: Internet :: WWW/HTTP :: Site Management -Classifier: Topic :: Software Development :: Documentation -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: Text Processing :: Filters -Classifier: Topic :: Text Processing :: Markup :: HTML -Requires-Python: >=3.5 -Requires-Dist: setuptools (>=36) -Provides-Extra: testing -Requires-Dist: coverage ; extra == 'testing' -Requires-Dist: pyyaml ; extra == 'testing' - - -This is a Python implementation of John Gruber's Markdown_. -It is almost completely compliant with the reference implementation, -though there are a few known issues. See Features_ for information -on what exactly is supported and what is not. Additional features are -supported by the `Available Extensions`_. - -.. _Markdown: https://daringfireball.net/projects/markdown/ -.. _Features: https://Python-Markdown.github.io#features -.. _`Available Extensions`: https://Python-Markdown.github.io/extensions/ - -Support -======= - -You may report bugs, ask for help, and discuss various other issues on -the `bug tracker`_. - -.. _`bug tracker`: https://github.com/Python-Markdown/markdown/issues - - diff --git a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/RECORD b/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/RECORD deleted file mode 100644 index be08e6f..0000000 --- a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/RECORD +++ /dev/null @@ -1,74 +0,0 @@ -../../../bin/markdown_py,sha256=CN-Ji-5IbiekxHQIaCGuLnffDcAJe1KbGNP2M75sqGM,243 -Markdown-3.2.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -Markdown-3.2.1.dist-info/LICENSE.md,sha256=bxGTy2NHGOZcOlN9biXr1hSCDsDvaTz8EiSBEmONZNo,1645 -Markdown-3.2.1.dist-info/METADATA,sha256=PK6UzXb9yL09qZJH7SCqZd6-mj8keovCmxQLt89NlEQ,2383 -Markdown-3.2.1.dist-info/RECORD,, -Markdown-3.2.1.dist-info/WHEEL,sha256=h_aVn5OB2IERUjMbi2pucmR_zzWJtk303YXvhh60NJ8,110 -Markdown-3.2.1.dist-info/entry_points.txt,sha256=j4jiKg-iwZGImvi8OzotZePWoFbJJ4GrfzDqH03u3SQ,1103 -Markdown-3.2.1.dist-info/top_level.txt,sha256=IAxs8x618RXoH1uCqeLLxXsDefJvE_mIibr_M4sOlyk,9 -markdown/__init__.py,sha256=002-LuHviYzROW2rg_gBGai81nMouUNO9UFj5nSsTSk,2065 -markdown/__main__.py,sha256=MpVK3zlwQ-4AzDzZmIScPB90PpunMGVgS5KBmJuHYTw,5802 -markdown/__meta__.py,sha256=xhmwLb0Eb6kfiapdM21pCb80lyVEl8hxv8Re_X6wsI0,1837 -markdown/__pycache__/__init__.cpython-38.pyc,, -markdown/__pycache__/__main__.cpython-38.pyc,, -markdown/__pycache__/__meta__.cpython-38.pyc,, -markdown/__pycache__/blockparser.cpython-38.pyc,, -markdown/__pycache__/blockprocessors.cpython-38.pyc,, -markdown/__pycache__/core.cpython-38.pyc,, -markdown/__pycache__/inlinepatterns.cpython-38.pyc,, -markdown/__pycache__/pep562.cpython-38.pyc,, -markdown/__pycache__/postprocessors.cpython-38.pyc,, -markdown/__pycache__/preprocessors.cpython-38.pyc,, -markdown/__pycache__/serializers.cpython-38.pyc,, -markdown/__pycache__/test_tools.cpython-38.pyc,, -markdown/__pycache__/treeprocessors.cpython-38.pyc,, -markdown/__pycache__/util.cpython-38.pyc,, -markdown/blockparser.py,sha256=JpBhOokOoBUGCXolftOc5m1hPcR2y9s9hVd9WSuhHzo,4285 -markdown/blockprocessors.py,sha256=l4gmkAN9b2L340EX0gm24EyWS7UzBviPqX6wYrcgEco,23736 -markdown/core.py,sha256=JLR5hIMwWSeIHRQhTzAymB3QUD3gHCdITFvmuuCpIcA,15360 -markdown/extensions/__init__.py,sha256=6kUSgoqDT4gGUVsqf7F9oQD_jA0RJCbX5EK3JVo8iQE,3517 -markdown/extensions/__pycache__/__init__.cpython-38.pyc,, -markdown/extensions/__pycache__/abbr.cpython-38.pyc,, -markdown/extensions/__pycache__/admonition.cpython-38.pyc,, -markdown/extensions/__pycache__/attr_list.cpython-38.pyc,, -markdown/extensions/__pycache__/codehilite.cpython-38.pyc,, -markdown/extensions/__pycache__/def_list.cpython-38.pyc,, -markdown/extensions/__pycache__/extra.cpython-38.pyc,, -markdown/extensions/__pycache__/fenced_code.cpython-38.pyc,, -markdown/extensions/__pycache__/footnotes.cpython-38.pyc,, -markdown/extensions/__pycache__/legacy_attrs.cpython-38.pyc,, -markdown/extensions/__pycache__/legacy_em.cpython-38.pyc,, -markdown/extensions/__pycache__/md_in_html.cpython-38.pyc,, -markdown/extensions/__pycache__/meta.cpython-38.pyc,, -markdown/extensions/__pycache__/nl2br.cpython-38.pyc,, -markdown/extensions/__pycache__/sane_lists.cpython-38.pyc,, -markdown/extensions/__pycache__/smarty.cpython-38.pyc,, -markdown/extensions/__pycache__/tables.cpython-38.pyc,, -markdown/extensions/__pycache__/toc.cpython-38.pyc,, -markdown/extensions/__pycache__/wikilinks.cpython-38.pyc,, -markdown/extensions/abbr.py,sha256=pqp2HnOR2giT-iYKyqtsp2_eUOWBR0j_hUfjvUV5c88,2916 -markdown/extensions/admonition.py,sha256=HWHHjuYZPAPOg5X8hbpDuSbw8gB6k0odw8GuTT1v_N4,3124 -markdown/extensions/attr_list.py,sha256=m9a1H-S33rV2twtlFYuoxSiCAf22ndU5tziSzNF2dNg,6003 -markdown/extensions/codehilite.py,sha256=rVZVOIjp2KEIZsnz90mX6E2_xnwVPQZpVVQVJMuMVU0,9834 -markdown/extensions/def_list.py,sha256=iqRXAEl2XnyF415afCxihAgOmEUOK1hIuBPIK1k7Tzo,3521 -markdown/extensions/extra.py,sha256=udRN8OvSWcq3UwkPygvsFl1RlCVtCJ-ARVg2IwVH6VY,1831 -markdown/extensions/fenced_code.py,sha256=dww9rDu2kQtkoTpjn9BBgeGCTNdE1bMPJ2wgR6695iM,3897 -markdown/extensions/footnotes.py,sha256=a9sb8RoKqFU8p8ZhpTObrn_Uek0hbyPFVGYpRaEDXaw,15339 -markdown/extensions/legacy_attrs.py,sha256=2EaVQkxQoNnP8_lMPvGRBdNda8L4weUQroiyEuVdS-w,2547 -markdown/extensions/legacy_em.py,sha256=9ZMGCTrFh01eiOpnFjS0jVkqgYXiTzCGn-eNvYcvObg,1579 -markdown/extensions/md_in_html.py,sha256=ohSiGcgR5yBqusuTs0opbTO_5fq442fqPK-klFd_qaM,4040 -markdown/extensions/meta.py,sha256=EUfkzM7l7UpH__Or9K3pl8ldVddwndlCZWA3d712RAE,2331 -markdown/extensions/nl2br.py,sha256=wAqTNOuf2L1NzlEvEqoID70n9y-aiYaGLkuyQk3CD0w,783 -markdown/extensions/sane_lists.py,sha256=ZQmCf-247KBexVG0fc62nDvokGkV6W1uavYbieNKSG4,1505 -markdown/extensions/smarty.py,sha256=0padzkVCNACainKw-Xj1S5UfT0125VCTfNejmrCZItA,10238 -markdown/extensions/tables.py,sha256=bicFx_wqhnEx6Y_8MJqA56rh71pt5fOe94oiWbvcobY,7685 -markdown/extensions/toc.py,sha256=E-d3R4etcM_R2sQyTpKkejRv2NHrHPCvaXK9hUqfK58,13224 -markdown/extensions/wikilinks.py,sha256=GkgT9BY7b1-qW--dIwFAhC9V20RoeF13b7CFdw_V21Q,2812 -markdown/inlinepatterns.py,sha256=EnYq9aU_Hi1gu5e8dcbUxUu0mRz-pHFV79uGQCYbD5I,29378 -markdown/pep562.py,sha256=5UkqT7sb-cQufgbOl_jF-RYUVVHS7VThzlMzR9vrd3I,8917 -markdown/postprocessors.py,sha256=25g6qqpJ4kuiq4RBrGz8RA6GMb7ArUi1AN2VDVnR35U,3738 -markdown/preprocessors.py,sha256=dsmMVPP2afKAZ0s59_mFidM_mCiNfgdBJ9aVDWu_viE,15323 -markdown/serializers.py,sha256=_wQl-iJrPSUEQ4Q1owWYqN9qceVh6TOlAOH_i44BKAQ,6540 -markdown/test_tools.py,sha256=zFHFzmtzjfMRroyyli3LY4SP8yLfLf4S7SsU3z7Z1SQ,6823 -markdown/treeprocessors.py,sha256=NBaYc9TEGP7TBaN6YRROIqE5Lj-AMoAqp0jN-coGW3Q,15401 -markdown/util.py,sha256=0ySktJgYplEV7g6TOOs8fatAS4Fi-6F7iv4D9Vw3g0c,15201 diff --git a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/WHEEL b/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/WHEEL deleted file mode 100644 index 78e6f69..0000000 --- a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.33.4) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/entry_points.txt b/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/entry_points.txt deleted file mode 100644 index f49693d..0000000 --- a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/entry_points.txt +++ /dev/null @@ -1,23 +0,0 @@ -[console_scripts] -markdown_py = markdown.__main__:run - -[markdown.extensions] -abbr = markdown.extensions.abbr:AbbrExtension -admonition = markdown.extensions.admonition:AdmonitionExtension -attr_list = markdown.extensions.attr_list:AttrListExtension -codehilite = markdown.extensions.codehilite:CodeHiliteExtension -def_list = markdown.extensions.def_list:DefListExtension -extra = markdown.extensions.extra:ExtraExtension -fenced_code = markdown.extensions.fenced_code:FencedCodeExtension -footnotes = markdown.extensions.footnotes:FootnoteExtension -legacy_attrs = markdown.extensions.legacy_attrs:LegacyAttrExtension -legacy_em = markdown.extensions.legacy_em:LegacyEmExtension -md_in_html = markdown.extensions.md_in_html:MarkdownInHtmlExtension -meta = markdown.extensions.meta:MetaExtension -nl2br = markdown.extensions.nl2br:Nl2BrExtension -sane_lists = markdown.extensions.sane_lists:SaneListExtension -smarty = markdown.extensions.smarty:SmartyExtension -tables = markdown.extensions.tables:TableExtension -toc = markdown.extensions.toc:TocExtension -wikilinks = markdown.extensions.wikilinks:WikiLinkExtension - diff --git a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/top_level.txt b/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/top_level.txt deleted file mode 100644 index 0918c97..0000000 --- a/venv/lib/python3.8/site-packages/Markdown-3.2.1.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -markdown diff --git a/venv/lib/python3.8/site-packages/__pycache__/easy_install.cpython-38.pyc b/venv/lib/python3.8/site-packages/__pycache__/easy_install.cpython-38.pyc index 70b402432727d1108bc0f371c89c7fbc77e6e008..6495ebc6d5a42e7395cbb93fd76ea627ba108382 100644 GIT binary patch delta 90 zcmbQsw3~@1l$V!_0SGw%?TVksbJ!_JKO;XkRllgRv@|PIzqlw_KP53QGc_kUzo;a& sSg)e8O1~^MuS`EDGfBUovLquv&sfhwzc{lbRkt89IXf{ub>e3&08d{aDgXcg delta 61 zcmdnZG?$4dl$V!_0SKO#ZHSx5b6CYhza+OnzaX)008#<65{{> diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/_compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/_compat.cpython-38.pyc index f91d13e2651045038cc7a34d2e5e629d7c7b2f81..f82fb0bd5c1d94481da7214060694b2194e6a403 100644 GIT binary patch delta 94 zcmZ1^cSMdSl$V!_0SJ`-?TX*XGo8sfL_Z@xH&wr=va~cSQ@^+iw@8jBl$V!_0SFYzH^gn^na-qWq+gO-pkI(#pqrUjT#}fRqZ?lmpB-PBm8zeW OnU|GlwD}oR91j2$G!u0I diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/_identifier.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/_identifier.cpython-38.pyc index 190453fd53e5252a4b87b6a77026fa70efca3c38..28ddb16b007d3d4e9dca1c52bdb4e9fe4ddcf75c 100644 GIT binary patch delta 93 zcmX@c_kxcnl$V!_0SJ`-?TX*X^NP(mLO&xvH&wr=va~cSQ@^+67>K8 diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/asyncfilters.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/asyncfilters.cpython-38.pyc index 2d16bca75272b44ab843e1c0b5fa746907bc124e..1a38c64560f5f51b267c83c8d5f849b5b31c8782 100644 GIT binary patch delta 94 zcmcbq`dgJJl$V!_0SJ`-?TX*XW6k6osh^Rbo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<*DuK}&@ad=(9O&%E=kPE(Ty*O&yKImO4ZNG O%*#qN+T6udC;$K=b`wXt8fl$V!_0SJ`-?TX*X6UOQsqMwnUo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRpnNJOBUy delta 60 zcmcZ{zcHRCl$V!_0SFYzH^gn^31d|>(l5y^&@ad=(9O&%E=kPE(Ty*O&yKImO4ZNG O%*#qN+PsuiPYVDpWD|z~ diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/compiler.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/compiler.cpython-38.pyc index ad500f5f5ec22937c677ab6c121e15d990dcb9d1..94f92a2e6b9e24f5c8aa2f84a025711861aaac18 100644 GIT binary patch delta 1335 zcmZXTZBSHI7{__;x(kY$kPKxhBQiQ5?4k>4fxV29WHqj_B$|l}T-b~I#@Wlul8HDV z8rc|+ilFi$sVosx2Pv1*`rz=rFHJkmFivBQGrdkTPJU^+|GP8wq5bfi|2gOX{O@yK z_Vz>N?n7m1<+5cW?=H^Dt5f-(MI!{1TeYHWMt6_Uv zq}|b?23j0Gt;P|G=-yz!Y2WGyYr0wx^3)#oG^k;uTRNUv^OY=NpZRD8)x{!lO+ z)@ppJsN>VU>oPnrNEqs&@}U~|PH$Ga+2DdPj$3QJny*f{<%8bkM6XKg=>?*f<-PaH ziJp`8Gcko~_Dz}8in7LsWyDrOh#|*1+_Lz<@4u(|W(Ssr^&LSaU zBOaa1E|M}P}_Xe5WcvU}tSqEb0J`UCdXJ(f%R zczP`J@%@Hrf12_5H4zN>)qq~F`E*r?H+W&}00m{~2Ogt94qdHRj5_Oh_TsozZ3~G_ zqJ#^_Gg3$K5p&BU>>B@thWOd&F6!h{(Hz>zQ_;t$T+T;#lHyAAyy3&IlxvV{Wb)*7 zMTsW5o}aq5h;En|6LnT&*Ud=RsJ@!nP`r)XP>9TWA7z8c@9SA!HjA2*~Tm`NJ5kGmt#CYa-_89^vsa-MKlJJOXUCfXGFRh|YMa))=`uO1GL)8(}* z!A)7##}EbK;xITd2p=_!Mpo*ZqWS4v(nrKO1szyfRptiUFqL@s!T$xy25qZU5h zYT_Z^7Fy5W`6|f91^&IXSqlF*1}f&~!!=}=iSQqa;YnD_c`%YscD@xURGuQ<7JY#K zjAYU?ysu{^n>v4`4Q!0&kxdpwf6K_PRV^uR`7(*?=;jp6&6nb@iC}1ob{u znRQED+Gq`?w0?)=_{%z_8f&gJ3T?I;t4dqfamqzwDt*bh5mDBqd~EC6?%xes&>^k= z_Q_#o-Af3@eT!BeXq#A2 z>v{d5!yaFYsFtSF_Y>`wMLi2dmD2dePNJ={>dc1=I%>)5t;c z%Z3rBYLK@sxfRt{G*)1C=v|#5Q6lWB(|pf67{a33(Fa+K{XzrWl-flx9#0ig1%Ht; z(GIzodX8w1y5X-WiEYb*D-#O6E9WL=)9I@Aa+304y62nm+_mDR&nmO8ml93$_8U)= zM>F)@2vY1ZEM5jY4r~LS1-1h_fnC5}pbAiM_xLY}Y^Z}!2LSEWYVWZbrS=|OP)7hC z5CBfV7J?GAMr9bX6F3IE0(1i>IXV4i>0@;c)6dAyP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS vE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc5Fjn^heErS>40 delta 59 zcmZqSdBn{V%FD~e00au<8{#(d^sy?M=$GUc=oe%b=w{{>mn7!o=*E}CXUA7&rRry8 N=4B-sO}@*j4gmLm65{{> diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/debug.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/debug.cpython-38.pyc index 4e6b4c8409ab4da69c5052a2b5ad9207abbf1282..3600d2af6796a7a885507f1e965e466169bb6416 100644 GIT binary patch delta 94 zcmbQGu}6a^l$V!_0SJ`-?TX*Xvzpa8NIxS#H&wr=va~cSQ@^+j}wak diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/defaults.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/defaults.cpython-38.pyc index ffc808ae8b4cb163b2c190f156c69c638fc2f522..aa2c4fec309c08b3e1f21905eb81db53b1fb80dd 100644 GIT binary patch delta 110 zcmdnRafgE^l$V!_0SJ`-?TX*XQ^d%4YjZuL29vJ{P^<_<{0i02$j?pHFRCmp&C1j- zE=txX!OX9QRE3;DdvoiCt5{)K*Va@;m?n)Mw diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/environment.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/environment.cpython-38.pyc index 106d05dc3e675f0d46eeb526ad463b3cee90cc78..34d84fbbeb07b80f4acc1804662d2643b8676a00 100644 GIT binary patch delta 774 zcmYk3OH5Ni6oz|-0@nhH5(TVUG{$(-(pzW%tGge6=Zz)^6oA^ym`T9XKOLgP)B;30gcS`5vF!>I{cMvE5ih)&h+729r>4GYU zssIXMRzf*|DxezJ1~`FQu`v~=GWqGz7g8^LIUQ%`(RR0(d(yfovxR+T$a7jn>sD?@ z(iz|^a0?x3pehr+fGVI?e4MFCtH;R&0DW?D%ar_JwOAtfM2%UKZCkY@Es2-Ox~F@X z<02vxZ#a$`2H=9v12l;7XA{(jLc%*cN+oi2_Oq2viHCD{>{k)-QzhuBiSd7Bond|% z&MTsLejl}n#(7CTv1LK0CgEN9k>bapPv$Om(tZ<~pDTWo5J4f*_uyGc8O~XN{s*o3P4FdXrHKI&;sSNfI;$(O8XG z*00vui#N?m)Vv-tw`Vk3?g$H*_f z6hE2h7{7dU(-B9}uHogb9B2r1flL)m4=X6{&A{0sjawbK9q diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/exceptions.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/exceptions.cpython-38.pyc index 186c8230b269700687637741699e280b42e9e914..ae42d9070cb81ce1dbb334431a7856da1ccffb08 100644 GIT binary patch delta 94 zcmaE*-J`=3%FD~e00c_^cExYx31e~&*U!k$P1P@|EG^B-)Gsbd)=x>y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7cu%#X+me=oe%b=w{{>mn7!o=*E}CXUA7&rRry8 O=4B-sZC=WhE(`z@p%XCx diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/ext.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/ext.cpython-38.pyc index f02ed078f162fd980a2b7cc52147e7492451df61..e3c8da69b7d15b1fe18c877f81d0b148741f6195 100644 GIT binary patch delta 96 zcmaE~oUvsEBTpzVFBbz4DE-?NzmaDdt8;*UMt*LpeonSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B&J@#f2{{C)sJEFw|> delta 62 zcmZo!!T4x7BTpzVFBbz4D3ouA+sLzwRZ&mBB)34nAhSR>Gq1QLF(*eiz9c?7zA`IS QKPxjYE7554S5|&M09lI^od5s; diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/filters.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/filters.cpython-38.pyc index 75a261b8ac11a08d4a2326b98c4344d35c70dd28..d9867756fbe3cc8da98e759fdd15160eedf1da22 100644 GIT binary patch delta 96 zcmaE|jj3%r6Hh2FFBbz4DE-?NzmZ3Q%{fFrBR@A)zo@dbG%HiTxF}gaB{45EH77a0 ys3f&mucER_zbrMcOg|?xNxz`7BqKl1SkFSgII|>Gw;(Y&J25@Ac(X5?_*4KVz9GK= delta 62 zcmZqM&h%s(6Hh2FFBbz4D3ouA+sLE9rf8&Jl3So(kXfLcnO9trn3JO$UlN}kUzwGv QpOu-Hm1wj%pG|x!084ii3IG5A diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/idtracking.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/idtracking.cpython-38.pyc index e65c76a4bc451ffdaa23efe67ac860c6ce898139..eb341a5d35bbee58a42120432c584957d2835875 100644 GIT binary patch delta 94 zcmez1Gs%}Hl$V!_0SJ`-?TX*X)4}K*uAh;go2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp0nee)i22{&@ad=(9O&%E=kPE(Ty*O&yKImO4ZNG O%*#qN+I*dHw+a9*u@puC diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/lexer.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/lexer.cpython-38.pyc index 58536a5b58616b038fdad714a9b125fc96ad8a2d..ff0e889041e8214e35fef656464ce9f655f5faab 100644 GIT binary patch delta 96 zcmbO=opH}}MxIb!UM>b8Q2Mtkek0E`PUj%~jQreG{i4d!(yUDV;-X~zl*GKu)STq} zqLS2Ny^6{z{j$`&GX0#)B>jTQl8pR3V?7J~;>?m%-GapA?8Nlc;?0LSuR8(&Ezcsx delta 62 zcmdlpopIK5MxIb!UM>b8P$=IJw~=QWr=o#=Np69DL1uw&W?pegVor{3d`WzEd}UUu QepY5)R-)17r<~Uv0ZxGx5dZ)H diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/loaders.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/loaders.cpython-38.pyc index 8c4e86a42223b4db30a9191c0cd8f7dc735e22e7..29e2ebc23007fdda4e4d46fb332bff21ad0d8b50 100644 GIT binary patch delta 96 zcmX@!!uYaY6C-^kO)>>Q$>k)NBYUsPFInw6csj~xI!*dmeu delta 62 zcmaFa!g#!ektdXwmx}=i6v{WmZRF`=Ry5Kt$t}FNx2Nugpr- Q&&tfpN;KMhm$}Cd09ZN{-2eap diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/meta.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/meta.cpython-38.pyc index 94e6cfccf9000ccab0b5f5f54037c2f1da8a1e0d..a30d5061037de0b6b216b794a12ca6fa05853c7c 100644 GIT binary patch delta 123 zcmZpYULwsC%FD~e00c_^cExYxab$81)X&JzP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS zE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7b@$MlJl;}&a3X+civ Yt;rcY3mLU1bMe{($#pE^lM{Ir0r3?n_y7O^ delta 89 zcmZ1?-6YKu%FD~e00au<8{#(dI5H{f>zCvf=oe%b=w{{>mn7!o=*E}CXUA7&rRry8 q=4B-sZJxmNiIXFWHKep4CpBtv7tcaQ&B;2v_CWFii}>VbUPS<;=NrcW diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/nativetypes.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/nativetypes.cpython-38.pyc index ef6ab7905e50d23fea61440fabb114cc59fd878c..0b504895e16e308c3fecefb7756ff1ddf35fff8d 100644 GIT binary patch delta 94 zcmdlYcTJ8bl$V!_0SJ`-?TX*Xvz6I7LO&xvH&wr=va~cSQ@^+k delta 60 zcmca6w?&R8l$V!_0SFYzH^gn^*~+YFreBgQJ>f{BcgBWy_u<0t_xb+*o^#$Va$gp? zrV+cn!GfQE?_G4Ysm^--nw-dG6q!y>Or(;sM&t5mESpr)@fbKj6st+a=hbmuot9(!u=IYY6IW*eI615h;ME#f0oMfYn3B ztJzCL>P8qaK^yHZ!!!4IA_Wolo1j30Ffunx+F^MvM0$+vx!1(Y9st#_n=MgeZ)lYE tqCrJ?Iqw%847y-*-s@yXL)j5fwrbqkpLxHN^+s6_l+~g=#*zCH`47r1;#U9w delta 902 zcmY+CPe>F|9LM*KZ)O(P(cNZTU7a>v&D_Y=Jfx_H4v|S97(@})Dk8PBf1G){X#PP~ zB2$7wenKZnI&~0C=F}nZq(l)Kbg4s^po0)Z;H~KQW>y>LFwFcupZA^j`_22hBD`4< zDsCuBxeu>~$=7!`E6U`?_Cz6TCd`!CmdfP|BbiKFvXD$Cr;M?Lk;)k(9rks3Xqeo# zH|_4be_ z)>UB5pvp~;LSfVBhWF`nC0>KGRc#rQe)Vf!ndb7O8@w%P(|R`R6V>KkCGs7h=hQc zst|Jf957>UxTa#%6YnOO>MEbjxTEM~8J?PbFlt>c?WY=-JO|yn0s*!STNYK;JOLE; ztZrM+_YkcH#aA9Avl?fH_RGQu(IQA~50zNNX~8}_VG7|oq;EMbwJ2kYbq;r0{Po}< ztfTVLqX?+zhsut467c|RMe5*S`U{D|-i#_lIo6@dUt>pR=LOiEp_ThQLU0DjP91Uh zHuqO-z=%KaV(t>eiWg5b;+up==}>O`FRvEc#TeppxKoV7u2B!+`ChFFE0uh~(fMoQ zOFHe<`R_z)Myh$J!kS(B;bA|~T9BUhP(N#N>F^^;)K;VyJXB<@Fu5>D@P{vSk+>~9 yUMGaY#$s6FXPwEgy%>{1{85FUi?u;Me4HoV_!L3ZvB3hUlaf!_Do7Te&~oyNTOFL=Vw} zP;g#)(|Ra;3F;>izLcq%8HO`4H;oFd{4+}la)qmVuHA2{_mUqNc1^-~`G9^s}QV!Y?@2EY)mmt?~r-YsNN&fAafgUn$iLQL!IkfjmTKf&)-DV`{f9ZO_RDNV^uc&9dJaJu^Q|G~5TO^ps9 zjT(Oh2*G3>4{g#-@N zFTx7;HrU`NrW$f#4fh-GDV}G>T4g9bU=DN6E(uAR`CAp{`QCHaK)*mrBjKxpNDk`? zFlUgt@_i03%lAw9zL2+#NzyV|Ht>~+!7A#_#lm|M*3o9Jf=zzM90J(DU5zeCak=r6 zMoDIA?#W97#q^7uR>DETUqTrn$+Im6fIryOQVmJG-BO+jbU{PV^2wGyFpeq4=F?Ik z`TGg!)a+BL;*4!|kyHvVeIrn7JM9Wp5yErAOB^|GFH!%1iO!XTr-V6zM!|*jW+n%v zBXoX^W@};Ab`)9(fLE;tV2k%!uWNT_kYp#Hg`hr6;1#wLnu~)Zj1tBP6ND&XhA>Nr v6V%lKsuF}Xf|_KWs!c+QpeDXT)fPru9|}5J{RMB>P4E_{?L{z!TlT;|txx}A delta 733 zcmXZZUr1AN6bJB~sW)iuDS8S~^FfSsDXG(zW<_bMt-&_h!nTovwoLXZzW?SLP?)Tb#_;7yT`@6q$e%u>ll#NoUO{?9i zlAnr!`)3}Mrb{a8b&(4JUBDNp_4S1#p5ESCSHyMRb?D9ynx137uPtCp5H)ip;Mjvni#Rjx3WQI^|`cjP@Y#zXR< zxX3iO98XJmocT)$Qo?ZJGHGU!Sin5LG?htdlq;Mud1;YPnro!@2)^^6xs`I_iMgL> zh4)x`s32}yX4Le72duZs|6?=L!idXA-SsAvYCECIu8~AUWJrtGpH_sr{D!IoO16{Zfe3>4<3VQpq6nK zTfN~(s1fT|9CTEbZjOSM8!Eo-sHAlfbzCXhUV_MteKw$6tXMd@52#O%B8Y);fIlCa y00}S!l0a!4K(z$2K$#?kDhCQcnK+1Qo!4B$k_N5k_@3KDZ#eI+rb#aM1pWadi|^zB diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/runtime.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/runtime.cpython-38.pyc index 88987d1bdbbd32f9bf42761d0a560ce7212d3abb..693552aff275198fc59f271e72fbfcd0707c1ace 100644 GIT binary patch delta 96 zcmaEOow4}_BTpzVFBbz4DE-?NzmdnD)j32zBR@A)zo@dbG%HiTxF}gaB{45EH77a0 ys3f&mucER_zbrMcOg|?xNxz`7BqKl1SkFSgII|>Gw;(Y&J25@AcykVGX&L}Vx*}u% delta 62 zcmZp^!T9hxBTpzVFBbz4D3ouA+sI?js%WHNl3So(kXfLcnO9trn3JO$UlN}kUzwGv QpOu-Hm1wlNkF_)n0A9lsuK)l5 diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/sandbox.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/sandbox.cpython-38.pyc index f0bc310fc6f50ff89dde7dcf02a701d395374a6f..e6823276c5736c67c920a728ba8a20b61b6d1975 100644 GIT binary patch delta 94 zcmbQ5w>^(1l$V!_0SJ`-?TX*Xb8Q2Mtkej|?(i*t~EMt*LpeonSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B&J@n(M(1An$}KvRoW KY;Fyn%?bd^10}uy delta 74 zcmX@KiE+UuMxIb!UM>b8P$=IJw~Gq1QLF(*eiz9c?7zA`IS cKPxjYE753kA&Y@O+X|qbqHmj*2hU~&08NP)D*ylh diff --git a/venv/lib/python3.8/site-packages/jinja2/__pycache__/visitor.cpython-38.pyc b/venv/lib/python3.8/site-packages/jinja2/__pycache__/visitor.cpython-38.pyc index 45ba90f9f23e30afe338b15d4209b1654b050efb..8ecd3d3952ecbfb9e88a56ecb1899aa0771e4750 100644 GIT binary patch delta 94 zcmX>s`Bai8l$V!_0SJ`-?TX*X6VKutqMwnUo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp "1.1.2.dev0" @@ -31,25 +26,24 @@ except ImportError: # (1, 2, 0, 'beta', 2) => "1.2b2" # (1, 2, 0, 'rc', 4) => "1.2rc4" # (1, 2, 0, 'final', 0) => "1.2" -__version_info__ = (3, 2, 1, 'final', 0) +__version_info__ = (3, 3, 3, 'final', 0) -def _get_version(): # pragma: no cover +def _get_version(version_info): " Returns a PEP 440-compliant version number from version_info. " - assert len(__version_info__) == 5 - assert __version_info__[3] in ('dev', 'alpha', 'beta', 'rc', 'final') + assert len(version_info) == 5 + assert version_info[3] in ('dev', 'alpha', 'beta', 'rc', 'final') - parts = 2 if __version_info__[2] == 0 else 3 - v = '.'.join(map(str, __version_info__[:parts])) + parts = 2 if version_info[2] == 0 else 3 + v = '.'.join(map(str, version_info[:parts])) - if __version_info__[3] == 'dev': - v += '.dev' + str(__version_info__[4]) - elif __version_info__[3] != 'final': + if version_info[3] == 'dev': + v += '.dev' + str(version_info[4]) + elif version_info[3] != 'final': mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'rc'} - v += mapping[__version_info__[3]] + str(__version_info__[4]) + v += mapping[version_info[3]] + str(version_info[4]) - # Ensure version is valid and normalized - return str(packaging.version.Version(v)) + return v -__version__ = _get_version() +__version__ = _get_version(__version_info__) diff --git a/venv/lib/python3.8/site-packages/markdown/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/__pycache__/__init__.cpython-38.pyc index 1516effae9137efc464bea66be96470c7db1e44d..324abdfc2c0778f6870cb63c300e033ad28773c9 100644 GIT binary patch delta 94 zcmdnRcZ-iFl$V!_0SJ`-?TX*X^O4m#Tt6c}H&wr=va~cSQ@^+g0Q34FsQ>@~ delta 62 zcmcb`w~LP_l$V!_0SFYzH^gn^`N*nlu3wT{pkI(#pqrUjT#}fRqZ?lmpB-PBm8zec QSd^WTU!J$wflZ1L08sQ48vpsl>h($ delta 62 zcmaE)cu0{al$V!_0SFYzH^gn^;p0^{*DuK}&@ad=(9O&%E=kPE(Ty*O&yKImO4ZLz QEXq#FFVEW?%iGEf06IJr2LJ#7 diff --git a/venv/lib/python3.8/site-packages/markdown/__pycache__/__meta__.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/__pycache__/__meta__.cpython-38.pyc index 270065a598c04c5aac020571bb7a6346a6ead4ac..72224d2d01baa4d6a608fd3c83a5e7df4b084a7c 100644 GIT binary patch delta 642 zcmZ8eL2FY%5Z;;Hm&7K~2*oy#L(o$W<`op|p@`s3r57ne4z91+ZTn2JFYLaAro2!v zdKYr_U_A&Pz4}x3;=zLi`~@Dwd1;EldCbRrGv6#T^L|!-m7g6{s~e2$_MdO^Wr49D zIaxO(@`&6u2o&ou1szbR_*>RNjT&aq;YvJbt>EkFcRX(e3rzdpYjYdep#!t|GP4r zABd*_^9#{^Zp>`H_GKdQysyo? z9yCo$_{vyY7bix><|y&OFtVxhF!sekG#tj}_zSaJ)cX5Hc#;fsXeXo5>o|0_8>+~} zy5CJ~s$KhZau$xY8HfG&FdRL>?}jc;_1$6A?M27h&EE%i&YSd@+azFEgBota zHdf#kROoAcO1Ac)kZ_SJ`Sj|1ut#j_}`}kG=*%&^Zo2vnymBY_3TLHii z=bS$kbnc)P4-h0oaMX}Q(v(DW3-k&H#gdv?Bj7${Sju}eq6A)mrq4n0$djJ*-$CRn z{}`e`(oG11*iwMnlP{a!>2QphVIw5An#Y|a-tFq$&>J&+9HR)v1i^YcT^*;!-8*P! z$H}m6xQAAJMJS;p$3&8Z7V{;2OG>PE2_#GWVrAxY^u2_dHOV!VLplKIpRkgb9*ToL zyvKlJdP)X=gDWW3eIlz9MGaYU8P;Jy^vzlNdcw>{*^qOxDKC6r1KKBjI^~w&|0wkR zz2KzMC#P8IsKy@;T^pfinN$bXi_`p7Z27h-aZILTd?XEbFc}4DZy2|hBi=^&ctSXd zC9x&jrjFN;nX1#f-A*5>mZeJDc_9vzDY}^!UA>bDVVif0LXE!hD_h1*+Xge<2G6F# zkXbK}O<7oSV1r(q=eVFxV3tw+dwsR+<*Ru&Z*_H1#%bCTrAWk^J+<14O(L^HJ$mF_ zCpSjgTOKlV4THjp4TO+cM~G delta 62 zcmeBBf1$<`%FD~e00au<8{#(d%wtow(l5y^&@ad=(9O&%E=kPE(Ty*O&yKImO4ZLz QEXq#FFVEZjmTfi<07=gk5&!@I diff --git a/venv/lib/python3.8/site-packages/markdown/__pycache__/blockprocessors.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/__pycache__/blockprocessors.cpython-38.pyc index 09c54fab7403efea3cf9ea699a1d4086ccb6e828..232398673563a0a20289bbc9007c29b58629156d 100644 GIT binary patch delta 5500 zcmaJ_YfN0n72dh~ULGMfHW)uxFc>Zl;3p;+39A zCUMe7(jSe+QrkQvh?G{ADn%7le?(2ws#1ScRTNcCq}(4#Ri#oaHA))EQtKaW&v&lb zi#Ir+{dRWF%$b>UzH{c>d;59u#Y>|6@v^dzi~j2W`%dKc#aGI=h;_f*Da6J;SG+bJ ze!&$F8)ets~;&avO`>^_wSk$s*IqkZLZ-{SPatl`uW2)3P|IKj6?f9?V2#bXrC;GqpWORBeV6AMa)9n`V{kw_wy$VMV3)JG++ zH9dqrA8p%6W$jVU&|orZW{=GzlJS$vKPlZJ>RWhlG?Ot>am#CFWg=sFE~OJG*-jGO zD<4uHm4!DJt>}##+34hBs4N%NqG=$ktp72D49;1#&N83Vfn%X@48#DhnsF&!7f%XnM}tn7fcB!|w^c-aG!+Ek7a13x5WBq1gGMPwC%X8>*?9BUv?SG+~ zxBl_;DQXSr9(j?ztib~%;I<}l`Z1{T&PKDb z8Q#0)otEjjj7{3YDdiK;!o=XC;(&Z!-M@N0^>*!sFdxVpLzES-d!D9!s6MM5&i6q< zKVSfG62SIj%}m4N=)>71wkt8$D!WUHn2}7b5QD8XiXm*RYHBI^m=y#dq)!C2QjoGC z;FXZZXu$Nr9l`v}>a$9Z zWYe>W*eKiOX?)nz3Qok^#@>!@v4*&g&88!h|Nhe zkxoUDiP=QE#OM>-+93G%XKnsz>1J$yYT)tJk(L5@)s(&>% zgie#t61&IbpsLkBJN+#EBx4NG7iVPYtjl*D7PkV&`UeJ&Q(~8oVcbptN2#+o!u*sP zZn@YF($M8Lhe3`-?iYz?mOpLzMC6gD?Su)7N+i1RAm5u{0>w18Ee8S50Tuu=0FL=8 zJE>C%GHXgE3kUUC8eo-<4jdgE80w3R9qAk8z_nvEirI)!%ah#^O(dBsmM>|CaRa1h z08AX@V`-?#)*S~r(1dODlA_qQy!Hk_9Lo(wxB|xANy^8k)O)QPY#upA1CO3u{=D^^ z$aC$1L(Y4fC*nJG2~yoc)bSn0$Gqdcwh+3upqJTHe;z`n+xO9O90%gbmjDL+7rt;RQ5o{`RmTQMrc0FgGF8pMA z`;zHtDq=0q(@~lFmc%E&LsKkobSg`O#f)rR4;7B{!PY;hzwSF!oT}JZ4*fXjoqXju z+EImj=N*_WKn*gR8_7!6kl`xT!u}qyS^Z}JrR~Th@;cxsz){3x!3v+MfsS|W*g?G9 z5r^cn82So<9(qsF z;q%vaJ+ybB`S79U!^7QCu2;D7>rroZ?%SwS@1a$_I!$P4P*!J69`vQ#-?b=k`!Be2 zN(LbWzeE6+#&U|GgqI}A!n^PJmcuBo$a$Q02Jpf#HPvP2&Ue0R?wbZq#!m%#1 z=7joF*WUPAu4392{3Tz7p4R~1PUS5$7a^kvfbo^qS{)G9g#Gn$OiwG@aL*+i38<+(a`sbe+dH z#Bf~uPhIV)>b$89joHUo)2uXduSU$H4>51PYUN#rp`sm|^T<7Z`hYCv-w1NrqAM;q z4(y89O>IxkBR|M_7Ts}*5LCvC-X+(9mwQOQ=!<&@{c$gi^>MFnNo2;j<)=P>&X@B~ zX%uCFOTkN_oVVLW5$0Je$uGI$t{1gUE-00+(&D9YVT%e9Up%lRmNa^=3P4DF< zKRb57l?XSN2qBG#bz-BaB&^i7@yDZ;iusKNC*NgeTDH+UksYHBh?HY0;-|;zxMPkFo*pF_06j4bRLb+vx3xVYJ`hW2I BR#X50 delta 4524 zcmaJ^YiwIr9rwAmlWXTemNsdUCTr3>Z_>P)Hjgd~dA3QHnl5p>%zd~{e3Q7nvAuJh zc56~RT41OMP4}mOzl(nLm%e}Y2d8h8)-vVY4#o;czS-ONGNzVzl@hts43YNJl-MvS&F{eMZDg zO{~U@=uAc_sb#EH>?y5Q_t6r~%QZ1tT3?wb-5b?OkK^KE>4T+iY}`W-&S>XX>#Oy=jGxa01G4!7O5fKDl3 z(MT*^$Y1D5>1ImLytkv!BbR8oOA6!?Gk=Ynug6~#f7x~NQ|%;}cL5FoMgU`g34r5< ztowK~4PdTWN}w{2U-hVkYKdP}ck*TmVU_r1RftuJ|5ZJB0n#mn>sH}XVl5dnbmd3K03WbqxXC`-Vu+SWaAlx#dnK zl9q2pPZ9YLHR%{hym?G?n|g|$z`BzF8TywnP(++F^>GBsP8s?dcrDdAO}#YeY%)q6 z9Bc9=MyT&snQuMY%F+R9THdutYH3yKZh2RDVm)aSH)|yiLW(4ZG!+I)d$q#6{VcX- z702RH(&~}Fq=DWgWLdr*A(z|bx+?AV!pH?3A^SpT%kj)p8eYg;?mETN@*V&qFMHcg zM>{kQQr&kG$g@P6`Ov#@#lLYyE3v8mItC@(K980YI1rD20dN2yW0uvL$ElC*8nVQX zV*ENmhs;FD(2##75S%(PHHUahT^)t5(o`YRJ!7Ffw#r&7)sXwX0lC)z;6=_A00Q_0 zfFoHlsS$m<35G>Y?{4BMj{ZPz533dF-WCS3?i4@leQDsSOx>2688N-TZFXCwrIy>O zRZD8UgTyMJ2HjBd$QS?CZPICgz3?c<8HLyg5{p#+`A~b>4N0Z7OfEEACAB7~gb-J$QLV-Spb>1UTwU@UZ5!eDhOda}(1@@^$LtHvrOW%hdY#9k68; z6C9hQpT?-~Uogi{4Hql+G>LtO-mwE$LOoO>Wi^IKyJjcQY5>TR>V!`2|2YgGYERq= z$I&|qfSiz;|PblW0nG@p7bA8dRLMNH*5c_M8`*i?}+5VwYL!%EK zn`##Uid_+}k=MftF*Iy8z_}W;Nx3Dp#V>~c;LzH>z~L%)*|Twl3cJttmZWX=0JDSQ zhH`5F)Ngr=ZSA8_!E(%?rx8zL-V)%+pef{=){!G!uRJ;AaI}I3%9WgQM+~iyRz536 z#>X2qB@nb_ZfPT}?h$W~-%HEm`OEZq+3jyOs^nYO+jkgZ>gf(o?fVfn1zb)W)?r0tV-WRUlX7ifENbGm0Moi2Fp^1*AmfnLmwe(x=cv-)T>No<*b+$D}J|HR=Q9YE^8=jFD~O{ OMP+-+c9k`j?fyTJ+i|%7 diff --git a/venv/lib/python3.8/site-packages/markdown/__pycache__/core.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/__pycache__/core.cpython-38.pyc index 1e788b6e1b6858c057db255b2b84f4d6912a72f4..6c01de2ae93ccd04f81280cf25d27eb8378741be 100644 GIT binary patch delta 2242 zcmb7FU2Igx6`q;+p_VClv=#9(>zIWq`<7*O?9mQ1*6(cH9 z#YwoDp~bT5BwgLmV>#iZ+_aI7WzEUBStA?ENvFr{HF{%Ncec4XBNxjlXS>^H^tt^; zKg`oKL$g)M$Xil-fcA8-vEu}yy)=Cl2nz@RMois`R?0q?P2$G$F zFX+YmJ>~5u=`s2&oubq9I6Xn1qbKR})k95GlBx($rZa#Fo#oT&-h-#As6(2#jp&>W z5`Ezs!Qj=-#JU&h=?>}OSd;A_$nd3kRG9DnNd2muP#3GrZ`Ao8^vRM|_MLbZ5lSO@ z!KW)Ag^{wMRP72gT`MAvZK#e_wLEZg&2TZ2T(cf&o*$H%T@NGGZ-n)R7#EhTvKZ^3 z?R)%0YHzO=TCapAv&={dE50A{TIw)1_y?&6&)IPJ2lK^6-?fTtrO{ZjivcSasp;94 zQ}$VC1rx8VtQMCoZ@K8$3&r|MxafONPaG-+c4&R6ZkB6i)e88}(?jah;wFE{|C*lV zFJ^Q;nHhsIC;d~+bgfJl_gBHr#Eu)VBqX!Do-Gl4f&Znqv?q2jg!)?mkpyXP^{2eH zt+FP8IoOX83Q?0>!7cJ#RKXNea#aiQ5}87vlbRCya#NzxAZkk;)RLQW1-!50c|_%P zR8!gW>!>YLnJOLPsq2WU6>^?@54Dul;ZSLVrh{8*m}qM>v5xXE!|0pHJ0_#4Fj>>t zCm6L77_IK1nlQJtrdGkt#F9=GntY86q5;%Ql=N3&(LqF$t;FTTS#%D0=*o< zT;cS-%@_ybb&zUHqxw36NaX*ENRz;?l=*SDcl$1!(synCPFDEgzL{>fZw9Z)aB17c z#q9(TjJ}X-;U-=}a2bTjO?-n~lIJ&yQ^1kz0r3hXA`|-~V%2ZqNP~Kmg!WPWBK?SC z2VvQF>yz(_*eZaE2-4B&Q>RQ;qyEd@#6rV%D6i&6dl=LVJ-}aM1V(m_-^zbyh>2<% zeJAJU&m5hdot`R9pFJ}@H-GYlxp_W2Fs=r|HRP)UM@M6VtckfGh>^Cukgb&JzU_qp zTjhTm*z-ipugk(E<`)C$P56Rm08m;ZeSG(h&b|^%BGs(d;X&OZOvH_na6HQk;MF`% zI{vpEd3={EgTI@qfLB3fWf+){*@9T6lpV`tERL91Gy^jX8GB2Zw@_Uyxz`=uc^>2Q zd}Zj^_gqK?6GEkk@M@R6P?)A}s z5PXhbdEzF%#Pegj2ChPuk>c2%6);E05^H$O<)_AmQ=T}6pcA{u!?CaQ`ydul8&y&R zzro5DyT*SyHhw@f???%tyM@p$pgEFyed~D>W#3!2Somk~4QBby-G_T}I8Rhb#_H!X zCZG3pFYf-eJbYKgQZ2@O78Ef1vDh@nHg1^Dj338$_|5T&!8e3Hxsi-wd(d>5$b#MF ze;nUG{J)ioQk#1pw;k&Xd~e~R`m*p{=5H2;);6JQFU0t9{8O#w0C zMB!OSz#Rd<67XopSc+Mn215b9U=%>ZGLa>M$wO7q4robjM4QkQEz{k*Z-^8`pn}AH z2?JXMh=@xciy4Q@fIjHjPw8asK8SOh2L=&VioG^6xgZoIj>3K`w2xAY!(>7CIy8Vl zoEc?xoW(lU9~Oq$Z-n3wanFAM45=_h delta 2184 zcmb7FON(*j-n4H8Y3|B1BN!WMKs#r~yQvMS6#+o}qX8F;w@W zV2>LV)c6ETP4qOQ2crig8TEiBXnZFm9*mdv=0S~#o=i+gME~jq#Pwt+{q;BhtNy?K zziQr|{?62Q>AHsC8GY#8{pgfFjK4T_U11JW;z))>Q#9?!u3{({0hb)r?J~L&E<2i= zF)|5PoUE%GdcsvF=XM+23GZ@x++L$M;hNLu_8a{P&p3>kQpRE{ z)mlQk+t?T!*@|cn%^nBkd#QdL8OvxN&B1r*^v|!SGbKp+E_j0rh`%how5V2! zkeR9>z%<QB)hWv@l zHTn1 z^ei{@ZTw?hGj@E4wyo=BDn&XMV4k6wN5T~q% z!-e+y_^-Xyxy_&s)?kD}6p_bqlTc{+aTMYfp{WSB$rJ)PH`Pe3;z*g%s7$pJWDqSzkz#6(fzvufwWji@vIp%&9@&E; ziJjy5{^ItP7h|kR{2(4E zM!jY-EAVGo#R^v0p~Xzg3)vB~;oDvqOkZ;7NCVsOo)qk{XhYBgAO`b6wTUBqiX2Ms zyrPXo5|dS{V`4QHv?|s%I(86Ne77<2nuwDIkP+c$^QG~l{g>uu6*SrM0^9cj1`S2$ z@y(3Dmu=^N=8r9p^?zj@_x>ks{_5g_To)b=|8nu42Mg{YX0j9VijtJJHgxe_gBA&ZSE}}op=PY ziY3SPtbkF$Q*72_7BE9^lv!X+`IT80IvguCD`dVOvMMOqDFJ)~nCqPU#ds;v; zdSV3Fs{-B;@P&YX@<`YLAUn#AfNG^^f jBat%`D_)Vs<=u$Yjjm5;9cu#8K|ui^J)mMPuO9y!p$8*< diff --git a/venv/lib/python3.8/site-packages/markdown/__pycache__/inlinepatterns.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/__pycache__/inlinepatterns.cpython-38.pyc index 7dd5c2d9b4e7dc92e5a4a8210f0c1644c372e4e6..cda7e13907d0d34ae28a2d13f2475c3b487117bb 100644 GIT binary patch delta 6875 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 delta 633 zcmZuu&u-ofs3JXSno`r4Hfc05Rcfr5N+?Syu)s2GBsN1l z&_ukL==0=37tbDAy&C@uFPwYuXws`zXVb=$Gnp^n`{sLZ-pl+-zfBnrbX`S!#rp?O z-Wi9+4=K5nb6R%JuG`sqyXTZGD_e3(&C;_*HPKD6y*^kBXpW|s^w8PGD7r?<98L4xT-0d(mu~zUO_`V=6fJA(G9#nJJ^&>-@c#W zu`rO@BEtp5B!-&;{m3NFk*hIj%vICRhfv_FnpG!Q-Ba@R&2$fbs$IMe+kp>(dwif{ ze$d_=*nuSEGzIIhpv}z}bz1JPIW6m!)u}Xl6RqCc_LxxdpgBU8G%N;GXE>> z{bCokrXEFRJSUk5_gCpP&+Xm7p>a-%a^k?z)KbE0nO@~Ek#{ZA|b(swi2slhc?hQcM>ObxXTBQQ0P8HoO167aZixuz@ZgVkT6~X zNl8%PJ>bjS2i`Au#+@gqR*BwN2(i_@te&>Vmm|5w(^qZAKAya`Mr%0t7uS}T7Irfk z#aSwUni^MPtoz=u`xt0-Td&!7YzXA&cXpk?GvX}hm(KWN8Pva?1@*Kg0=d`eG#i1E zaloT?LnLu3Gohw;_x6Jw(cTG?#zwGR)G#wW8>mJmrnaMaD|#W6{^A6~w@fYy2oZ{_ zaAidY-rY~L?mD??GSx_KE0JvGPSR)#C5`Ma^7RQ_pRAtq7c@pTXq*9*4Txf!$w7!b zhpA4y?|5HNv3r>5EjBSRWXvxC%3YOqWGpTwF}kY$z-A_g4f!ugLHR~z%AW@~%S0rF zO!xJ-(n2pLpg23G5*P}40H9_8aeR!rxQ`D=hP$Xq4)KB2wT`VW>0^w5vik@&f`FCP zbo%(%s=fm0@eJyynLOf5>Q HBSYmsoM^L& literal 9808 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 diff --git a/venv/lib/python3.8/site-packages/markdown/__pycache__/serializers.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/__pycache__/serializers.cpython-38.pyc index f2133ce28454541c7c1e201f8a3c423ac60fa907..35b942333df2150128ffaaa0e396f2d3bca89b0e 100644 GIT binary patch delta 94 zcmbOzxlxiQl$V!_0SJ`-?TX*XW6R_mrJs?Xo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp5(>vor;2NWE#=Mr~R`OI1E9D4+zjSt@Neo=LpTde@yD zJ8|Suw@V(rS{Oi3}jIK-+PqQ?l63t80lUA~xvQo0Nk|j8!TlzK0 zAJin8Ud*uTvV? zA4$O|Mf+hkN3x{Ad6$4XI& z^}53rNwDO{T9dn8^oP12C)Ovm0qw04IQY-3SqtjaWbJ12mTQKrY7)nHsaFjcr(tEe zy<)bg-!eUS&TO=KE$~lP&X}Rg>G6hBU33;`7`60@d^Y-4|7JJ~B4dryWzJA~5B4Cn z58zUCGyTpn9ft!Oylv~m4zV}^vqz&p)6aJmpe{fUj{#80l8Iy~M7C6-5EWvg5e*}0 ziP*wFNpx^N9p@OWHd*KfzUS6m?))T6QpSLG(WnMK8ferVAFOA_Qq8T_3{LBffH}-yYreY81rLr(o_ zTc`yVE=A4Zs35^xMtyFC98RSt!*D|&IAwL$rv&_@Ajt7NO2ihhg%IFBQQKfa%f<0_ z_qvytoqEHgMl%F&CVM_(7?)gL+X{);a%_C8JSnWh1=vP}fnYqLMvXGs+dfTU#Cao} zG)-YG#%kURmMYbtZaU`au@mECCr?b6XC@}PW8)J-WEB%(qals`67+BgfJ)^k;0;~+_P?nVQJfjoS@9MZ^GtK#86%te8#RPi>ktOScwg3 zwF|JjWjhRGM`0y90#Me3DNqI44H_p}j@P8I!sm7g8ePVqRbkVHX*)w^fdgXE)pCj* zKotiOo!bT$DD3{q08ez(Rr!tze+~ZHHR<-6Ch;V^BwzPll8&^NA_+{3S(v*n`8n9R zCb&uD0;PAfj`~1>#DU`}r=mx>p^+mqE@?yceknAnaJT1rwI|?)({fzTne%8R`aO4m zq+=~;Pb>d9=&z-Ri*92E>JRG!emT)Qba_5bxPGI_ zSq`^gfF5db()H(EkFtF9T7J;nJQ;i_LjF0d5tkV6Oi9kE2j#4+%L?=?a-vW2m#*L* z&@qWZ&m){e$RoUpAY`6JN(8@uf%;H?Iki#4XTX1QD@(Zj9A6@Qn-Z$z)GXhHqLA_3yopZ0ISf$3V@{O16hbs@5?DU zh*mUInmD^7opIAPL7U-cV=(b4baDA~nT?4nkzD_!bVE~kZT;~63(Db_|8I8^CVq%I z2M%`k^seF+TxlSDfUprR5@x;*@Q}i)7mjpL~W_HP(n*<90hMR)~g+ z>7I2(i}WuwW-^P}>xSoC(3r!_JHX-kM&`ERWq^}mHgIg7h4UE8vavgwmjix|<$<5) zdEmQnc9{idtB9uDW#jj$H_r5nTD|boKQHt#qMVK|+N^scl7AcPgbqDANsmrI0xwTB zlTNSM3wn(piW5H!8?B_(Zf$Mw=AO+j<M}|8%~e83PkV6Mi!hXuS(Xq)Gtii->`3Kf#9>@{P-2}W*Kz~ z0LtP*bVWR3P?X;lD&%wdb779m4u3DaAmkhQYtef@x~q#QF$czNa?607!cHR>xPyWA zz+&b@LNuW40Ua0*b?B7_Wwd1fKy`cSQoy#tV6_%?lbV0s4?=%6E!BxF`=zr->g1D= z>Zk7ZBXrJ$erJ{W%RBOq(g(znGgBw#kAOenAY=fPvl#^m-lizl39{Piad~rUZo7#( zZzH^mkVgIG zpm4j()m-CRHSCF^EV!Bod=}}LiI0)OI0U-;uPBvs krqgAcAzvn-5o0*CgtOw1oUTLiF3IXyqqtZworyy875FU%G5`Po diff --git a/venv/lib/python3.8/site-packages/markdown/__pycache__/treeprocessors.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/__pycache__/treeprocessors.cpython-38.pyc index dfd46d5c0b485286ed17d6ae59006f6f21d26cd2..8b7daea0380254cecc431a360e1651a7c65080d2 100644 GIT binary patch delta 106 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 delta 3270 zcmZ`*X>43q6@K^4o0&H=_9V6wFG-r!jv2>GsGZa)NgVH4yv3f{$u#xlW$ukV_RPHL zea}fu2oBgRfrci%5<3lnNKI)dR1*>^et;0_51 zEJ>6ylZR%aGaD}GEW|giV3?OdJHpEWOTOh#RIpMOz4e#G!c&uoQu*K&KClG?T`^%Tr>FVAdeJ&7G` zlJ&9vC6d_5ce3M)gq>g~m$XHa*u@qo8)QQ;wVMsIktHp$r(a{I+31qSM)}4?U!oTJ zV=NB+_@bVugWhv&9D3u>+sh3$!OpO=Q#$nOVJ^X*hq>pW_YroEy#V%Ny!0k<-r*76 zutPJ3q7c9J5MbG?8) z=jP^ISre?2!@-gK!{EP3Ll@Bhy7u4J7B`b?$)$2lsjTB#>2woy=`5X};Vl_U%rg5@ zR(=@TO}N|=rtK#|NerQ;E>2+^t;C2>qJ~!PyBH* zUz5C|cB~IYY=j)bB>>ON2|LGyJ1PBSjnEUL2Wcc6m!Pvz59 zi8|C2R}t1($ny*CaQ9vLR#nd-BqT<>jmP7I19W7dv%B~B@IX)RC={+**Eh@Oi&he! z2A$u@=IVQ7LjIw8A6>wOt^s%(;+_3#t*F8gpMt4apuqP8%3eqKBEpvt77mUBg!!0J_mi6v}(76IK7SW|0ktrUW|0uyh-=ac|I(fG}vS#BDpPh81= zP*WBBzbPq^+jdH@AJB}B)h(+(jmMJq*F3+s-LB&%-Y0}QR7MvcG zmdW4lx_tnBgEIjQ#eAOLyx$|UVlVX8Bu(jt52sU(o3t~zqg&+N-Q9a$c~VH_SV>~F zyIfFOEyH{6Ehwi$;+rUro_l^Lol0_X69>?UX9_+AwxOC-Jib)c6<>yln7@#&FQAaY zEY}iWMus{yUT?p9Ig;%lf&E{l8czmO9o zN_+#LO`hA!PAYN~7yeY1@ymkaJi4%)Pi3i~s*EV2%OPSoSU{d$um#Op8Qzo+*Z)T! zl&Fqm7NWfdEw7Z0h?Ff-?)(X0DP|P7{R#@9o8o1JCs`G@VXR#aH~h2n4V+aeS7y<_ z$0ktQ3ji;vq$|FUaz$3|!`N{C%D!gOs1iZcT2OUr@h62n^KjbAoM+ZiCf{ppepcl^ zDB!Yyvwa8-A{CmV%5ZG4ZZcG@y^ufBbe5PMur?&3OTOB?bzuyh!)ruzBlIBjBdD10 zoGg^7ic|4{1bCtNe2(`DVT;EhqgUbr!aA&ZP>XQ16>2eswYVK5H9aibTTYQixzw^Z zVz|a<2s7Y?;FmvZxz>+viafv&6g~1)?BOFE`#eGsU$7YC>B3^y@{ji4Can)ZED@mR zVOM3vL+luoXPNjhs;3ZU5c~i`?}xG3A+JCE$inqw5wQ*rUKpMm!gVgC+-adoK@}*n zQ{-sOT-~#ZANUbs~#9Y|TCQB6jhz6JJI6Ho|ui z?jpQ~pgd7dD9Y3>`Uy_Fjqr1X)zwr>?K?bq{w8m>)sdU>VcVOLAoSnIYg` z)#AV%s4B!WM$WcA<3&4NDD(4kZlN61p#VEn?Vr;qySkj(p@mb)0wqe{mf?e2cf12q zQ2Chem>%zo?GqTMrwi`+oOwr{I=F{)OZ#Bcvn5#aKpX6E*xkQG>m?`}=}q$t&$@BJ zd7+q93L_}+3xsi5^-N~rbI?pw6yK`fR(MC8LH#L& z3_=z`AmGI%et@8kZHz(%zb4=neqjq|?CoqW&5uIyYtDTDW3#EAR`|ezCzel6ws(Xy zo#-0;boo;I)[ ]?(.*)') def test(self, parent, block): - return bool(self.RE.search(block)) + return bool(self.RE.search(block)) and not util.nearing_recursion_limit() def run(self, parent, blocks): block = blocks.pop(0) @@ -495,16 +496,15 @@ class SetextHeaderProcessor(BlockProcessor): class HRProcessor(BlockProcessor): """ Process Horizontal Rules. """ - RE = r'^[ ]{0,3}((-+[ ]{0,2}){3,}|(_+[ ]{0,2}){3,}|(\*+[ ]{0,2}){3,})[ ]*' + # Python's re module doesn't officially support atomic grouping. However you can fake it. + # See https://stackoverflow.com/a/13577411/866026 + RE = r'^[ ]{0,3}(?=(?P(-+[ ]{0,2}){3,}|(_+[ ]{0,2}){3,}|(\*+[ ]{0,2}){3,}))(?P=atomicgroup)[ ]*$' # Detect hr on any line of a block. SEARCH_RE = re.compile(RE, re.MULTILINE) def test(self, parent, block): m = self.SEARCH_RE.search(block) - # No atomic grouping in python so we simulate it here for performance. - # The regex only matches what would be in the atomic group - the HR. - # Then check if we are at end of block or if next char is a newline. - if m and (m.end() == len(block) or block[m.end()] == '\n'): + if m: # Save match object on class instance so we can use it later. self.match = m return True @@ -554,6 +554,35 @@ class EmptyBlockProcessor(BlockProcessor): ) +class ReferenceProcessor(BlockProcessor): + """ Process link references. """ + RE = re.compile( + r'^[ ]{0,3}\[([^\]]*)\]:[ ]*\n?[ ]*([^\s]+)[ ]*\n?[ ]*((["\'])(.*)\4|\((.*)\))?[ ]*$', re.MULTILINE + ) + + def test(self, parent, block): + return True + + def run(self, parent, blocks): + block = blocks.pop(0) + m = self.RE.search(block) + if m: + id = m.group(1).strip().lower() + link = m.group(2).lstrip('<').rstrip('>') + title = m.group(5) or m.group(6) + self.parser.md.references[id] = (link, title) + if block[m.end():].strip(): + # Add any content after match back to blocks as separate block + blocks.insert(0, block[m.end():].lstrip('\n')) + if block[:m.start()].strip(): + # Add any content before match back to blocks as separate block + blocks.insert(0, block[:m.start()].rstrip('\n')) + return True + # No match. Restore block. + blocks.insert(0, block) + return False + + class ParagraphProcessor(BlockProcessor): """ Process Paragraph blocks. """ diff --git a/venv/lib/python3.8/site-packages/markdown/core.py b/venv/lib/python3.8/site-packages/markdown/core.py index 6c7822c..2f7f2d5 100644 --- a/venv/lib/python3.8/site-packages/markdown/core.py +++ b/venv/lib/python3.8/site-packages/markdown/core.py @@ -23,7 +23,6 @@ import codecs import sys import logging import importlib -import pkg_resources from . import util from .preprocessors import build_preprocessors from .blockprocessors import build_block_parser @@ -78,11 +77,12 @@ class Markdown: # See https://w3c.github.io/html/grouping-content.html#the-p-element 'address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', - 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', - 'section', 'table', 'ul', + 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', + 'p', 'pre', 'section', 'table', 'ul', # Other elements which Markdown should not be mucking up the contents of. - 'canvas', 'dd', 'dt', 'group', 'iframe', 'li', 'math', 'noscript', 'output', - 'progress', 'script', 'style', 'tbody', 'td', 'th', 'thead', 'tr', 'video' + 'canvas', 'colgroup', 'dd', 'body', 'dt', 'group', 'iframe', 'li', 'legend', + 'math', 'map', 'noscript', 'output', 'object', 'option', 'progress', 'script', + 'style', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'tr', 'video' ] self.registeredExtensions = [] @@ -141,9 +141,8 @@ class Markdown: Build extension from a string name, then return an instance. First attempt to load an entry point. The string name must be registered as an entry point in the - `markdown.extensions` group which points to a subclass of the `markdown.extensions.Extension` class. If - multiple distributions have registered the same name, the first one found by `pkg_resources.iter_entry_points` - is returned. + `markdown.extensions` group which points to a subclass of the `markdown.extensions.Extension` class. + If multiple distributions have registered the same name, the first one found is returned. If no entry point is found, assume dot notation (`path.to.module:ClassName`). Load the specified class and return an instance. If no class is specified, import the module and call a `makeExtension` function and return @@ -151,7 +150,7 @@ class Markdown: """ configs = dict(configs) - entry_points = [ep for ep in pkg_resources.iter_entry_points('markdown.extensions', ext_name)] + entry_points = [ep for ep in util.INSTALLED_EXTENSIONS if ep.name == ext_name] if entry_points: ext = entry_points[0].load() return ext(**configs) @@ -278,14 +277,14 @@ class Markdown: '<%s>' % self.doc_tag) + len(self.doc_tag) + 2 end = output.rindex('' % self.doc_tag) output = output[start:end].strip() - except ValueError: # pragma: no cover + except ValueError as e: # pragma: no cover if output.strip().endswith('<%s />' % self.doc_tag): # We have an empty document output = '' else: # We have a serious problem raise ValueError('Markdown failed to strip top-level ' - 'tags. Document=%r' % output.strip()) + 'tags. Document=%r' % output.strip()) from e # Run the text post-processors for pp in self.postprocessors: diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/__init__.py b/venv/lib/python3.8/site-packages/markdown/extensions/__init__.py index 010e310..4bc8e5f 100644 --- a/venv/lib/python3.8/site-packages/markdown/extensions/__init__.py +++ b/venv/lib/python3.8/site-packages/markdown/extensions/__init__.py @@ -75,15 +75,18 @@ class Extension: md = args[0] try: self.extendMarkdown(md) - except TypeError: - # Must be a 2.x extension. Pass in a dumby md_globals. - self.extendMarkdown(md, {}) - warnings.warn( - "The 'md_globals' parameter of '{}.{}.extendMarkdown' is " - "deprecated.".format(self.__class__.__module__, self.__class__.__name__), - category=DeprecationWarning, - stacklevel=2 - ) + except TypeError as e: + if "missing 1 required positional argument" in str(e): + # Must be a 2.x extension. Pass in a dumby md_globals. + self.extendMarkdown(md, {}) + warnings.warn( + "The 'md_globals' parameter of '{}.{}.extendMarkdown' is " + "deprecated.".format(self.__class__.__module__, self.__class__.__name__), + category=DeprecationWarning, + stacklevel=2 + ) + else: + raise def extendMarkdown(self, md): """ diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/__init__.cpython-38.pyc index 9d4d5828842c7bbe5907a94d05d68e8c9eea98ea..347abe43fa5558951d670bb0e65678c485c80b73 100644 GIT binary patch delta 454 zcmX|-ziL}C6vofdm9HJ!QA(O65K@y+7pK%pFdYI5arEiahormpn@8+uaj^(~Z2Z3d@S1&R zn!arE)1)uC9uJ2d#f@%p5yeXOT8XyO)IW_Ud?e!$@2MsqjO}R>H|o#1QC2=1M6GVr zmged!T?x;r&&|SL`DrE|DGFSLDVeYoE+Hi|M0gAFdkPl2MQstL0m9@!5KGeF3wA@@ z{O43KBM3I=P!U|_Qs{)8{5=aZViyDzxeI?XCZB!YE{Jd%oCWL{-g)WRFAt%Xch%DN zlWJcXqvCdDr=sP@q0&-R28qABO5&(jiFA9|m$7w6C4ohEU0MqQW8Kfvn}<|~{snXD zEoM&oVvf=^%8xhJy$Ym&1Q|ZSGASeV6+-xj5Q5}aA%8V0|3F^zHocYMsYi|6$LV?| q6#io&>oz@3T*CIk%&E8BH@1)4?v}k+TGrX0)^fU$?Nr^~(!pQq{B0Hh delta 356 zcmXAkze~eV5XbK>udzSU#KA?88YqQEsKLoesV+`}AZi7*1XCnw8^i0vVu|<{IK6+M z8QqkwI=T5LbaT_cz(vrP_Ky2-eD4Q$-)lb=^SE3tf--yfeEC*>F*&R5xuPGtaS%6x zXdt{^uhACmZu>6mxP6az{hMJld1p)dgQn*4D)vZ`lxOn^5E7J9ec>V zIF_Ph%h%Es7Nl*g%3b4NQRBKgW6C^!J(yD8m#I;!tSAX6kAxH)PL6M8m709A Fn*X}IO@aUb diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/abbr.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/abbr.cpython-38.pyc index af8f21f77e3cd7576c77b3fb5cf9a95a0a3f8deb..c9b60c6d04c93b5fadc78e165bb0b0db150fbea4 100644 GIT binary patch delta 1599 zcmZt`OK;pn*kh0FeR!QsNYW;$R#B)Rn}%JYmhcKmTN>I*ZIqT2)XfXWGwSZf>s^hV zDv2EBkoJO*pqew%u7p%^<8kAFP{k1m!HxM5`~VKXH?!RkqS~6z-}~(mW8W0qd%0Xj zgJTeRAQ>{B@0_N#>D8GE_e@DmkFD!~xo&7-$#h9C3kmsReW&=_C0^ zS|v|XA8N(^Z-2IQ+r1hz{q1G`t3Ja^#uo$UAWDMjS{=3Z*pL|i#aJHB1AD26h1K#{ zM49N@l4g7ozj312EkBqikQTLZ<^R71>X!wLkBX<<%xOqaDR4Vb!vTW zb#h^O&fD5z^Q#+c>+4g+we{8U^@Vo;Os$0r@*_3kS{%^%(p2%hZ$RwcBXI=heK?WK zjvxr3FRiE=iU#Wgp6VYBV_~ZPb<4Y`DwXvK49$usr3W2=hW3Z9Kt9Wiwpi1rQPgB5 zso@*^C-dy#@1TJk2d1JxrYH+^&AL^$+o?F6 zXzfg5c2Hs+=>#X{utv;|fwaT`n`}oT)?;}S_lgp3oB4sQrVLvQ)JOrb75z}R#<8% z5gU;NYOu6)I3~e=yQs!wu$}M%@S_O;nw3Eg!pMa;gIvwh^nb81s23~*0O9Zdu#XTD z{F8K{sCEE`ybBxPSK(I@sCLRZdl_6_<4@DGhgmiVI2)2+Sb{SEgwCk2{br+83#drn zzISWo=B=Aci>x3uMkSD`DK{rvAMY4*K`LWJ@@bjLfb`Pr2ub`7{W6 z$tjobN)?r+oZkwZ$O0gH;b1nwzjCJ0oBTIt=<=xyat&{rF7C!OjB3qrOB#0nQ+5sT zV!s*?n+BXoK6Cghxyb`|32-sA+XzZfI;Ew>fHvR~SOJ{9CuP}_9C^p7VKAAU^8BJX giqu@ANp|2WlDAGITY(20*hKlJ(14Lo!s(n3V|kSK%{BC(=a*3OV@VtdVa zqJ+xZ9MTgAK^YFHr`;o*inwv&#*zE{1^fw!3%v2RWh=4PynVkn?>+zCdozCAQWwLI zg1|-aYac!SlzI=t1^oTPYahJL>Z5?x$G985g{Vut2Z(yiI5oR7fPESO4j2L4036a8 zz%$GSJWCsN_5tcPsdEQ)nm_+)8DJZ_(H9B3xq7uD z|1!P}&jX7R@1qeGMv3JkbIbR^^j^nQLC)ECVv9#t9C1Vq#(iqh#*fILt(Ynq%(Se73 z?~&VX%cAy!Y&aKQRjA`C@AZw1?Pz=RO<2lGW6|4F)-E3$=E^Dr@8^65=yt~W z6$`<5R&ZY?&hnle=Q+zL6c~b&vb0OlbuxAo33epI0S0M&z&4Ks%ZmOWyQ>rF%YiU|MTei6G+$p- zuI=2DUxiC2%HT|$Jx-HV=mle|n+Z!D$ZVf=#5pl>19^WvI% o^_nSC&qk`88|i=^!q)_|S)2qwxBRERkw5o8Foyw>0!TJ1&Z_6v{MP6@pJEAVP`uz>R9!amx-Ov|-*Ojq|R^Qti z)Hg-ASr7d6dT%Rkb;DDuFV!PI7AJbH*LIsCs&`!3=G~iN`ZHZj`|9^Po)Nv1p4N_9 zcgS_hHLl+_Qde8p$4j?Kqr~TU8Roe=L?w;#6;i9DTiUxLhIX@ovNEISAP6z}fQ)HE zCzKLS6XGz=fGeDWy)vl08TzsB2L8Z}{cgB=NortJQ!_2<_k_$0$MHeKak7fnmr{hW z6Zz|bA2u6%ylxo7!Ww9Bn8Ccp!4m(ARK5yVNFHaFu2jyLBfO7=|S?l9WNnVYN+PdEbLq}(a_I}WT@Tf;qHxI!bT6> zPiXWPUM0V;DYqdK;t(`)cB879gO6Spu{}$N?eY%f19NCu_H0}hvGm2Ju;Z4n-Cj?2 zd(wAfF*WKmZ4rnLq;A!|+VV${?YW`d1fO8#wSz7DW=n*-&bR=WgiZUVAGhqlkK*W& zlcu=Iv^?J#`SSscf2l1ol{F<}{UBpqARg3Axde-i@(eyR^fXKppc1dO{D7zL>x+jo zD~eqiM|fPrirsZ55MeWJWlHQeYkK;berVLN(8lr5DAT7foI-6EZ&?un+QIB81kpKQ z#I&eR%Ro9cn8j?Ws}@zM%Gd)&=N~Y}wiz?FS;3<7TA2b$Srv8-v|xk7ui<0+=^uJ| z^oaY%fQymu0{1!ifQ(}$GQdq0t8WTR_=bwyPdI6tSAb(xUb;H1LU^~!7cxB(uJl^+ z82G3u(*k=IWO)?Xavtf!a8+nOaSL{)^~FkX>-0DM=%@s11)#i;{s95-426`V6$%KD znK71)d9c;dY6`1pt!qA8dVt_>CwqV+bDA#D&|*^N>e^8@&6q(@;r^z465<TDl zD|p>b&kw}(1rQN=Th3oVp1{vnk)gwEZq~#-5d=GpJU@6Js^l#lq4f+88wM;bo)cTtGAS75vM0DL7-d@>+?%~$qFp!({7 z^j3W}&=`RX9Z?3PyXtF9X_^=VovBP4sDS}$WIz~gYVeX?`9X40ueWNhE0wRmU=^a$ zgriqlX*ew=)wQxTT)W2W4QYW>?z#Jp*VweY+D^4)cXqvo)OKx8(kD)bNpt0XX??v? zdQdJQz z8W4uIDcAtBJ_WA(I-mEcuLpFXFy*D1RZtIfR3E8*+Be|FE66|;->o?kh?!V^oBCSc zggVI}<(qI8sWHKoN z`ec5;E8#cEIc}t)R_jZKYHzHrE|{ugS5#cKOrut*+pgi{*EcrRHN#p{Yv!!Fyx~^s zR)7AA>X@!^ez{y(EYBNG;|aITEk^0s>-0FYR1Ba&3^atH#u0A21&~#_9_w4kH?(0@(@vklR z=2%qsHzjKOwtPm}&7^KI=O1!2TRu79KWAPc06Z9g5ZnZNsQAoB9$0_@^3VcZcn{fg zQ&K?T^1`kmi%g0v)3?@KM z7|U@@gxw}`F+EkXBV|yog}j!w$zWm%YJ?(9ta_%A3&Gp#+vc6>)NH7>A2qo+MJ7!$I7V=Eo~d~ zG-lX^b=R;Qvu@>(JVtXmJL z4aN&*PR7eF2M?Y!B%VC?nehF zV&g->{ixrggEJYgTFcZ*wb7F8daG+|qeZV+DLyV+nd+)jVe1?A?kBoQs}ht=!Eo~c z7Rq6Ua)jX=wWJ`zh(&u*h;z}7q6bRuDCt1OIw}IY6c%OjbCgqAj43c{Ol2C(aTZ@d zX}#UUrxQKnbu<4Ye|hrEav|Ty+bhHAe50-{pI8}5xq!n%bvk*$E7a> zAs+`QL|4%^S^3-`J}TpY_@qojyiJ@f&{BhX5uZH6?gim9Tp_zhm44ja^l6}il?ZV| z_GQ@Kch6|Y?3yaH90alBgyiv!zC%pv=uqAX~vZ8?8x#EoW{(6 z!~o+4h7!laY^t<})K+C{PszoVBDZo$<(k9Rp7U4WlB(q7N>%PrWq0#?-2et7%U)My zC^UdZ_v`N0@8kDg>!Z23vWDN{Z-3o#*EH=v=_UIs;pI(S!M~#5T2tdXH(b4MG!0$j zIc~bSzS%V8bKcGO3(bPAjjr(mFS^Bksae980x!8U{c^M1pKZ>{_Zhd+pKH$Hx!f#% zqIp+L&8{Am#X#5SkIy!XKh`|suQXoab3fIZ^M9uCDxd$U#^)a!%>}$I@C$gmV4II~ z%?o(H$S>jjl5ODqBEQU^L$6Ex`8}=ng7s@%)5_aEx9>Wx6WZ*ZN1^Qnj_)$_bqY6{fAz8^E>{^<=dPGtPQ%2;KU29N37>`doHff@wzPZSrA$tw*-HB4B3et zxPJR6sF%xow#_zrVK@lZ8;z%?Q|~%qZ+K95{Dz%OJ800Lt)5)XR+$#T{r0eLV-g{j z1(F{Kr|Wo@t47-P2PdfLh3v+)Yd=^+@dms9iFM*y9(&K}AK0S%V1*`t@vU|bv+vm! zuebevqXuHPUC`-SUe^xT6sb2r>iSJ~uV=?AWC<79uJ8}-c33XI=d{6Wd!5~XYwv9} z3N6zgpw=IXwq5r{x8bT*LE|9cYw=5c&>Pgs<*%@NT1}5;(rx?7P&IS+gl!Lm-?oFm z7idx)SR%0B@_qMX%N^QZp_%NN?n}*xE_Cg%<=T&I(KTKZ ze0Q~i_G8pSzI8~bG5WW?;b7p4kbxsC7AD$OyFchzfiog`YTF{T9FMt3K`ZPAssB~XK0WgxiD_N4N{#0e5k$g1U? zF#mv*o;`%kf&|qCtcVmEXp(RahM^tL`Kp`+h^XGAg~W(-l~O-x?Zd#9Mmp7C3|0pl zJJ!$**V+D#@7en)(O8ec+I4n&82W1*{HFQzoOX|8iPqV>UC$RbXHJLh(`M{5Ct!gc z(x?_Ywp@qDyutI(&JKD{3^RjbimgGsJ?m_jwodK==p@y039@o}9q(f7JC+;R`%1xN z6DNqrb-W-11KC4i4F;Gg8H8+qc5s53{<(E*?X`t72%(<`!V)LnJXP8Y=x+e-cnmAF zq#CDO-bFUx zWwl}h%%ZTF)o$B^5K|yCN~(&-iKZ$kqfaRl>*OIZf5_Xa+*>JKF>9gdUfUf)X{7?G z;bV!N8V$QmmSCS0b&8on(v&i8A7crzoTDvqbvc;W8gM75vmGB8DC}7w>-#YAvUvam z!8|`?J?mJ`MAD2`U1xXwheR6IiFNFUsuA8#NIyG6H(AOm3x-fMh}G`hT@1Vr03-m0 zNUru1QIeF2vyL~-2U@KYYb99_e;6{GTt>V>cb*bTh+G1i5=E0(0$3<$q|6T*OLxJs zw6h%kJ@WtQUVjT2#hgZL2>G$)wXxg3*W}7U$ac~X<`RZ=Vu7bVk{IIaGO*6F5)Rb~ z-6p(41F|`*>eCWa(@#`$&vRfOLhK-%JME$Dsf_Uc#w}2Wg-oc@Jyvs~56U-h#B>>3 zVkw)F-C_xKNffw40TA?>rkQwF5WIi$^;LHBPgmLN*B-1sljhw7C(Ee>Ea^a6^ZK=E z!trE@M@o>Eyf*p#6$AlQaS=~Zsnv2kCv3I$@fN&C;g@{dI8;Mac$!Y?g6onwL^`z?Obi4c4%N+sG_!ZjZ z#jk+k3wSa*Xn9!txqb>1?|lXoUjmB%Qla?K3ck&VURcImo3!*QVSzuF>Br)Jf3N!C z>+{K173HcjoaHaX^+s4Bnh-U_vwLdZb6g71X>Oc5o8v`ZIyd6y8D37GXL*I5yV|J< z3dS#VQ5lFgDM@ zuhTrgBqo37})?G zOT(3tQ=)@FmgF-DKBPlMtP~F5BI2+ILwOYY1mTGb6D=Vq=&n7U!0aVWCCGp zqk$${W$`^wsOjRBsoOHWU6iVdC=T;ix*b(oGRVFQWNM43l+z_dT(vS4=ArL+wSriprg`aoqnXr~N4XG;DoTFaL32hv zv@p4+?MOjk$pBP>H&JM_RimtzaH&wwfK|C@EWoZ@(JOj2S4ByGChW`exR>!%fVH7_ zLpOdix{$FoiuTtmO_~jeFrLhkX{Tg8^fPh{`YAby9N8Xdt$v2EajYNap{pjeuK<05 zj*X?|8RyT6Jb$jAmCm81tr=LJmtaB4usl6wK{y%z8D%wO>%zG%{s#1CxeiLm%wgOL zFTMy3g?;;_Y*Rv;U&77EFB@7oCu_^+`eT}9g_k!p56)&ngXhkwW7rDV0n82~BJ&4* zpSAA7C#GVahO`-+`BY|sb%fuCp4tZlcBCScrw3w((h5SgDYd|Y|CTK#*$iR#{bRz| z1Z_JZa3hlvgczQR)9xDOy6 zA+8K6U_va0z|~DDeQn}$7M6?9GlPr~M|z0(XebcuIv6dbuwvI8Sc|2XRn$!@SzljQ zFW)+kJ~D&}<5Fr+hY6&2IB<^BaoRHTm&xgLge6l3GD=BUC^sU@Z?Xw05ecm1fG|a^ zDx*e5kA{*>vT3qP0$zS|et3{GrE@c$iplqKyxfYNCzx6v>oU z+Xr)%VU~TCI zr${OS`O45tdLoq=OL-z!h8!8C-PR`#fE+iTJLb*kypFH6WS9XKJSEhy$i#t%uoi8-L=OL3eA&VP;LN|~{NlmQaUS|w2}95 zoj#}~DI7KIO1cNcOlrBcI9{&NOY&u_e)SerY|__S?bg&{B)E-C;-hrEQ8C_-d(Bcp zptcYh0!9t{DXLVwi~=sp?++Z;j*1_@^Wj?`?7b5e0^1VpUXi}vLxe5V0Ofa) z;CLjHrBMME40&JWQ!f#{A5w80MeHTTEgB$C$`wRL$Bp!Mr1zh4h~fqs{S&T$oV<3i zl&ctJqfj*e$DDz$ixZ&mdqzdSf-leG`{;#?&&xXf9RPj+bxPW`T2Z;x>ic}?(sQNN z`g~})@t0z&g;2cJ5`Tgr#Re5Ljm*>}`X}HoE~9AR3doC=bn{y2Qt7&^ZKGo9N5R>f zxB`aa+Y_?zR>kO&3K6Ex3P#^&R7)o!ndB>(nTbI}rerD*q;V+_+{Pu7!SLeJ&%=l7 z@)@UL>9fM>sHZuMsvlu@+SWj&Wa{Eo&=6Otz?qvSR;j2_K}lvnv72-=BnpzSEW;MBNNs`L^*r{ z=(M_06vZwPCJl;=J{KR+LjgFW<8-B(H)qnR5HUFK6|DwFS ziw}v`tb{c^-vzRMddG8O==~QO1%HG>BQUGK1ZZ0QonaL8%5O~5{NF<1qEX5f^wA5? z+I{rj!4xQsA>O0neJXaSkjo-H%M3bE%@6S5-*E*}N?44 z8BSHFl(MH3mE1VMNpjR9#UVaHWm8z3bd+KaT50f)C^)pVi%6g6P~xx#C5~!PmiUaU zFQY`1zY7D5Ou z#;E=s+5@p)24XJ&vHz_?>@il)@%gT#H8wW1&(~%8W?^Tv`4Nseqy^7JxJdYoA)T&0 zR(Y?@6B`&q9v5tS{wmVAp1o<|l;hrLl@2?Quy@+27e*LMM;~;^y*9~uQx;K>1dV>M zhm4_&pO`#-A*81c8U)+m&hb{Z8)*@3161N3b>2!sdUp5T`|o9vhI^!6Y-Jk&Lo|+m^S2}stp@Wjqed?JG4}qBE5;Fz@M<7l> zyrbitA)y5JdrnFuXI`Ym{pId=I%>$K*CfcL>1B>yG6xK`q72eiIQ)kgL+qhw&Uk(t z$xd=*HN80p69%7uY_~k@upqAp0-xd*<*@^O#JxDC+LmS~Dmz#lU@X$oNWviy&J+20 z>SL-Px^VQ+65Sxm9oZ*QUY=!T)Lc4W^3RAFwO|VmS`Gm(tV*U-HQ6$cufH|^yL4p% zp>j2cuv!Mwusz>LkR5M2nX)Tlu*~MW-`kw*FRHXkGA>mM+NqhViDFE3*vSQ6LPWu%z z1I6TOnEhV`$cGBMi$iT&G%qAisky4h1^(<55L1TG2P38>ZVLLc}v<0X)h^H6KWmg4}MO_ zMc)A!p&q#PaLbIMa7f=evQuu{pq0rj)`gGOJGINo!H^6K`XF2?Ocaqh3>{aA>uXd= z$)V;7Soco=-?_PQMS@U`}Ye?`|ci#Q#+KGqe6#2=+Q`5c8vot|9C(+g_ z8j(OwI?1+P(c7s?O4N17Xs0V_kW-b!4auEQC6-w?I3*JPs8LD0EV=SciKc1hzEsIR zFVQSD?@QFYCs$0U4bfq!4KwwgQW=8!2pxs`D3h^1Ovh*rhK@)^N;>Q-usih zP3DGSt&f)HgLY@W)9RdQxqe_f&Y5aZU9a9EYgC4%4MoN! zkFw9VoL0c>6-AN^3!Y^bFdhbplNVZU;8~r!jW%-w-)cg?MibgfhUoXK?YC;yb>D8V z1);#fOG``P2Z{U<>!MZgy*9G~_F7OV9%z4*ITD`Np6|6>=5Dn81#9kE&vTgV7OiV6 zupH1^&~TgamfNsk2?ftBSaYjd98KRXzNvLu22Ifpm76M_|&_*G1_0wig(9aVXrdhfVZ@PyT*D4 z9Ax2wNRuVE49rH)x`J?zDoYWm_fAY$`lw2LVI~#sWSN5Ak%^=6XI% ziGH+TGPJcHdwY7%-C$3c-m4#&B7~6Xl~*HU&s0&e@6yX3s}T0JG{EkIvJB-C6n`0@ zOS)23>Lvh5R|b^33ZT+e0oASsnCK<}wXP1B?4~*w8WKo)*8ogW>6+Aghm?y(q<~!_ z6+g+X$MGzU$X0v*EMq?l~)_ zBh_b4oln5R`C)`32sft?ClQV!AVKhH1PkE_1Z0>PMnH=6YPIFIf@<{&)chQPq-f;e z&miG1&3UpM{?#n?%m7TWCf_4l1bFc!RSJ^8i*LldxOoiPbpDkf1#b!axO$*brQdt1 z-}{?!@7(32FjUc7K&02e{%g|q2u)IbN8VDp z3dkvH3}hhZfeiGFazom}56BM)*ShNVC>_FDUfLl9XG?>ALg*btMn37i>BH-tzDYnO`kxm1IAdD?0dExOSgQEUA1f*kK)qeJoH#H zia8M(7+k#7;gex$bn45(`$_mRHxWd@=qRNSL=cJa*^3+t8#I6@$yvv-Yb?@`m0TLB zYhKGOYJ4XA!RUPNv6#|grn(6ueGDrpZOR7Gp~#S+OhAofzu<*k+uKO7T}}L<%pC9U||C*T)vg&%*DHy?9k#*ZEuB#CDP< zcL;xr;(^TsS)obokb8L4O*hk(x6_n#l^q!zt!xi<eD|Y{<`+J3!F zk1Z@L#FYWThX2V;g>R2%3RWF>ZZ|Nj7KI$!s<#3gQw{Ln;KRQgKOTNEK3mvT2s(vi z+-Qn)3>;jtZZw$-B;59D>){LeLik}mAATc06n;Nn(09j$zsgU9f6SlRQ=|^vO(wvD zW&Y%Q-#YYTQbKZx)Q%10lyt$?89tbtxFP}!?D%GoCr>1DvL=s)6NjfJiblD-%8|Ls zd>rsH&!fB=K6Ci&m01w^0s;=*H=PJsWI#R!P=ewknd(G60{1(7Vw9x+8m9g<9}C|; z{QFyTpyveyyhrgO!fAw407b&j<4cY=bR6}Mos2A=(&`56v1WJJZ=r{eM^J*pkRjoR zM=l)2yd-kck3i^>ZHbZ{vL$!rW$D&~urPJH2fU-v#3YiHMz#Js*?;T(cS^jIYY_R+ z%b0|F>YKVCzT{eJ+W>+~?*QcixhdP39lX(Ix(cK`s8oVLD;%K_< zK;%HQhrgJb>0wAjDsE<9_CfZD%-tMS6^SiQK}bEtRT9E}=jPr>1 zMG%XuqO|Avy-+Jd!*8JYNU9KOvYzCqt3f&NDE*p`0k{9U{<>5LVxr1@y)vd!l_v1U z{<@^XeH}cegQ1@%kbK0zor+-czDkG0|hgRGb|E^$P{0K5A1WW!f${A9I(*=)8fhN zAB9L;zhm=;{|<>#)%eO=t;PltClI^-4T?V(4$aId|Il;cOEcTk=)#Zj3R8wpqnRp3 zg9Vp_>wSJB9GX3UPEZFXno2TG2mj|&6aHL4#=6@7C2f6kuj@k5{nHozY6x(%;=;edmqY};OE&*92^ z;PNbRjgM}V2wwv%7f0i8LSEw7!0QNji{hizknHpn4u zxNu`TX8I`oLc8Pf;5p7cF8(aW#|sTCRxDPqZ@q)?jr7H~M>ia{gw*JxXVeiOF8Je_ YflQr&6JioW(Nn`_PdYq2GyLTL06Ju*i~s-t diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/def_list.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/def_list.cpython-38.pyc index b596afadf035d520187bebd33873419369bd05f2..e382d74d72cf08a47f40eba4372e6ea5a738ddb9 100644 GIT binary patch delta 381 zcmW+v%SyvQ6wOT1w24iqDEM3quB_5V?53`al-jNMLb6cO&X7jaNt`6rcI_89;5WE% zp#(SX{028A;Lc^gL7aNwp8GiWoI6>2UN_GSLzhHs{C-^Rns4Td-0E8Wa6l|JO4DoK zidoOXF7-*!3t2+q`u%8Z4GA4uf#0>FQPK}-qu#V)KOwcq?cKN@iL-C{78aC*ut9dD zK7j&T6hE?QaTV}asO@ZtiAWB>k^?btWDK$FK}W#~E@0J@odPc6(u3rvSUZubI^WYy z=W`hNY(*$@7zQ~^1OBKT)Gknq5jP>oMU>njj8Vu?;G<1UB0{lGJrq(Dxs1@H%73)+ z+@-LH6#L~zy-YvI5d&Vr-;*yB`*OY()na#h-4Pf)4 ov5n}AfdVAJIs&UEYl@OfY_?=Aerz17_N?s)wb3>Xhl$V!_0SFYzH^d#}-N?6wS=mXyB)34nAhSR>Gq1QLF(*eiz9c?7zA`IS zKR2-`J0-t7Z}VT~LMA50oXy2-(-_&JSV~fhayRpFNHH2S0nKs%;$jsbk;)Lon8Fan zl)@OroWhjO7{!vp3?x}oSW;M97^2ux*n$}}*(WD*hOib%0@Y7G#_1?%qu^YWnpl#m zkf@NCTCR|iGTDTyiaQo$CJT^YV4A#>D~!=*vH-UR3lke7+h!Z?QbxwK$(wjw8J&Ql z62i7XRmm{*9E>bXMYfZbd5sxuCx`QDE98J=K+a@fEOG&ontVkTKcl1>$0mehx+!CJvS& zmdWNEhT8Vgjk*1`!}lMIc!uEnpitCtu*u F0RZDBIXM6T delta 245 zcmbOu^hb~7AnDE7-JnSa4@nkaj+DzP7dcV6bH#@G8SJ40=AKB@&^tb04v=s#{d8T diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/fenced_code.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/fenced_code.cpython-38.pyc index 4c43484b60bf26a200177074e75c587a18dfd956..28393fa15eaab527105db1ebbefcc6cce7d58445 100644 GIT binary patch literal 5508 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 D)>o8o literal 3528 zcma)9&2tmU74M!IjYeZhw)xt?Ze=HCA&A8i$!=vg;16tLSc2E4z?-cSu)}z|EsZ>y zk-J9)77`ao?J24K6Qm=z+;Y#KG1r{PKadKCB=5B(TZW}7WB2pxuh;MM*X{2L1)IR< zJpJnrzn>=LAK01v4Cvf|CK(V$s)SLdg|w+vHAA4Rh7pZNe;;dqr4|YcKVx4SkzUL4S%H(4S&?R(M6Kd6s=ZN=5H)lo0zCk9^LY zwU}{d{aL~z8N`vZ8w=;&K~e|yTTkq<_-SM>{=c7XZ`T9q@Iz@HW73&CXf=%eJ?SLz z=#csGA!XZsz`3(fPm-3rR;dhiIGU~nNxi*O4&ut8bXnO|Cb&MB;O;2NOEwz7V!z$w zQQ{?F5=h<>K`n^9(7}~paq9pE>WTB)t5?682lBP^@O$qd^de^?Xzp-PdwdD?05v?n z9z?Y|_gLAFo0Sp>vsXe8RQIA9m&av&4YGdorL$e<@4C>rC*lV86WiVheDE~C<~&?| zaC3MJnj5!ZG;Rx@mt#?@gu_*`vLo62s8ep$TP6DqgpQPGnmY{H8*Mm}zbAN0#6FiY z79~BkF|ywTVUY0jAd-m(DP4A|v+pIwo3n7}X340|3SJ9j!o{JYX`waYIGI}G z73oJqv)()UwU!!^hr6lPWUq;s1<`NUD@n6eX$7r$rAHXfyNSE!9yEBRIjW;0hK~#6 zSPGY02We4Fv9VF-&|ioUM6N`Pip$v~@GOsnP? zpwf?ImokH8URi)hfLscZ6mC@uKN5pfix75O6hNrAjSzKd`QCyG<7DE z_X*Nc>7n!ZvNQh9J6ljcP^iw6Cr=yzfEO=b*q0tXUw%|xMj24qwWWuTo}Mp%KL7Y~ zskA(~8#g0P06aXu;&>5raJfA(TnDfS6=0}Bx#CDTD&+Hc5{uhA!0xx>gwHb`22H3p zW?vdt)gqpcvrBW`Uze~mo>?kiUdDk%oE_<8_mpanqOoNk`a7YWAI7MU(^Kw3gd0g- zSbP+faBxxiP`T{0&L<0y?n?`}?t)ypAQviX%R&W*J5!DydQvXVU66C{Rj>|$!6rWe zl8~3APrDRrn9(kAwE!yG)fs^xYMZwp5i_#g;sWzAh=K%i@Qh#Q{vKy8fV4vG`VgL` zQH3E7!_lrN!U3-V*|eCA~O6M4kR~u4i`5esMs0+2|aso9==Z{h6@_1G=k$W?7h_joJQ* zZWe5@*i8RqR|mO9|I~o|NdxVyt`5D^1H$syALu=O|JqM<|Hl5cuHHWb$W0;gvz^}o zBqx4dRgz3%!GG=n5JU>Rze$?mgT#~dva_91J0+=s#g`hG5UGXb7PXsFSP-q$uC?KA zbJc>J51h)4YO!@t!^>W}GC2r&ns39UHXhqdb5X3;aX|KQ>6I+;E08GgCKBgSc1G3`2&7{@@7e0N^pU_@M9cuGo*Lg0oE_dIGPMIJ#o;w1Fg;Tf(>bUK1oG5q z#6gr!-&)^XTfgb9ZfvdHb?>jIrsSUR>uIJY;&v;wHdZ!oyW1<2kzW5oOP^-@qWUaQ5Er*z~GZY zJs`9mz!LEAb{>rR3^Nb;EVG6@q-(Bo+S&1B;5+C=N4XTi^ew&E$z1fBt?O^;LdUom zCcrEKQ$uF1V_rnmz77wuEIc02MI~+MT0MD|yyGZw71Z;gN%gM)xMuj%`Se4^j$&Jy z7WnECr;(fil4=m%EWAWp0c3ja+wV5E?`+)JgdDoLwY{>jk!Jt6et&iA!MgYyw^Wdn zksxS_>qtF&a- z9(4UB^aaj|DI}NzRr~1v7#0oIo~j(NiW~yIQdvoxI9u6_=BC!d@TIhbhDf}Bj9HA* MDQf96xtY8F1AVioc>n+a diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/footnotes.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/footnotes.cpython-38.pyc index d446ac20051a3aab2e951dd0dca7869f6ed55cc9..d0dc74ca6b731ef5881bbd62ba3cf1d99618b3bd 100644 GIT binary patch delta 3944 zcmZ`+>u*!Z6~A-u_4W0G#0hcUiA@Lr=V7yf1=_O9D}l1Gfs#ZUOhT|dH;Ey!&D={M z=BD0lQb?Dr_Ax3|X}7goRa;ioQi;+JZCCx$FV#wYNZW_5)DPPal`2*J18CLuoVgBx z)y9&4K4<34nKS1#XZZv9_QR~QsvOHC=JE?h zf-POUb~&3cStdbKxvVjt$un3Mzp+$IEE>7R#C$fLC@fiX`P`oPfrOd0jDbQbb0sxv zm^|d|A=~+W?;Kg4R!5 zxQegnyR_Og+QuK~;o8P^!>i{0LH|D4$t_=^eh8$^dUUVsCpyvOM*hh6m`pwViT_W8 z(1*8!zaXBMVEQIMQFEP~gmLduHCLIpd+8|u0U=lkpa*drv5pyU&A_9bAe z+p#k^^#UKP-$Cv@oTz_H$QeG`5U)FmdPyPH;HdLi(_(}CorZndIh5|7z%EojQGTS)7&BkYeOhsrS3C&Ju12 z?mMm+w z0-RcrsQOj8MS`e#K*C#H?FCx5b@smPrK+u$wTdL9yh6%HJ!Re2C~1*wsa*2eK2Ql8 zxJq#1AR6SS#P+(2-AyVok#d92EcV&3l~@}<)z!6H85%=*iw!z4bX3Fbz$8DIS5vOF zJ+{B>tw^ZPR!)P3>JtkC6$#GVU)>&Z@2NRqJuaf&(RBkA!Rrt-UvVIMod3GHw-jYQ z@G!%;GIaNdL;OYA?;krJ3pq+5UvT7e!;WSeDVCXIp92X;F>=(==Alrt1vY^r8WW78 zUe0H8j)xjnD(z_5oM|vf1b0p|ZdkZ52(w1U8cU_q24y9Ye^`RCfZI^63xy(iOm+hp zb{GK*+VRcgrrnvO*P1gJE9R_RR@QSi&6uswYI;_aQw1>(1XY8)@Y;|mZb_GQ$g%ZAR!|nhd3EjTttYaO z?kIazg;CX(A<&-UE&guXOFY)Twd8s(dOd5+MYA~yMVhj*`COD43;9KZ#{JRiN2J7K z6}b^sgfqo_j^DIW%rbE?y9qjM18Y(Z;6^-O$6Ka! z3#R@JUlXq*$)ge#nvWm+uR>fxaW0+c$~E)4B9aSUjK(Ta*aPVIUv?Zqtx0 zV#_OJNSf-JEXm6Xc8;IpL~kK4(PdjYVTV znxCn)v;qy}3A`BX7Gzf_ers1Ph&F{9}vPzMtt3fbK3Gy2>x zf%JSf2k($4T18YCrrSU8l-T2+hhJtOd>!F6fSAV(0D9f=2o(;=;w76iM1_<#>O_RC z3EF@uUTq#f2|<~G>=Lr`2$+IyjeHrX^`bZow4>4#RF!zE z+(oG*Pi%{jUVdiV(CN?ct9yli3ne#oRUgc5$1q}3LRSS<)(0-?;Q!fnh{XB9uF(Lx zh~aC7En*ecVMM-wYpQp07biPf`Cq!i#1EJ5Bd=on%064+?{6P3315xF0!Ly~s6x03 z7Q5F6+l$mufRR|xQQ?8i91VQVvS~+|H7qwxMbpP8m*Zin+^pfKnS5c%(Wzk+kP?l= z(eg7hCM>xGf-%3F%H%wMwY#zVMHpg-gaSzBE2i*tQa7{dY2?`gOz{u9BjiQ?*Y3Z& zufco#H#^$)eg{{+iy#W-i6!Ep${Jx}y=u+_?Z`7Zc8It1B*-~_vghOWOStkqgdYMx z*?UP0#D2phKC2X_ z6#wb2{qapx0&Q`vLPZQ$uuk!ej{|vtKNkx_=s)QjA_M%5SnAUW;K2ka@JfFJ@9zC@ zT=*o9I>h_<5>g_QXOUV#IF2v_5Yt@`pwY?T%=#a#q3j|&3Jmkwyv4qVve)^(zNk2g z$uIOBifnq64co&5uyEn&RMr(XAWpHH_w-ME<|%H$DOTI(a7%HFVWh4Atp8s*CftI% ze2t$UNN7Js0pY9gZXj2m+K<3~yZO%s*0#TeqoO!u_5mu3iazHC7suHyo{Dz{`jN!K zV+sCxJmO{VApJf5Al^pO{G)i=9$^{U!#Kizga87zIM#=NA!B%Uh6b?@_|8NR^n{T_ UXRQ({N&TUTP&o8_s3{cuKl53R?*IS* delta 3771 zcmai0Yit}>6`ngYJ3ITZy>`~#wPSnNPW%|h-i_NlN(gy4w$nT?A$EhaglyNIvAy>0* zW`m>}xfBAa>8zmF>UC>^UT27_Qfe>gd-O2qVM7MJ8T5L+0rUn#0lfwEh#mz!YN(*M zg5Ib%f!@UR80dTTX3(1rKa9uq7QJ;%NVVyKQAyBZo2SSX;t5`&MuFWEzd~BsNF>s9 z&Fbk+^k^%!-QCx0&FPNAPt(w}xlg(+?K_jS=L^X~w$PU~EjyFT^`-6fTzYxdNX}>I zoSt7Y*?USS>0ou<8S*T<>1}0qy(2MkLn4AhW&>r}4m!dr(TVOwo34%unvbb!C#hjc z^)WW3c6C-2AS#-lG%PDmEmx(+bk?#B>V}8&dE3m}1`qqk>Pw`PrF_Y{VMwu6hlv*b zL?wzCW_NuLNP2VK|9e8FHs^ysC7yFITx5OKOMxdrqA>tB%F@+Qa+AGL{X%U&7&M7C zpkPeKF&<`r3`NNZdk|_TFR+%{-*s}| zQ#b)#X+6RvfUULZ2pW#FXk7<+aq~po0|K)@5l+;e2D?iNTG*9y@Vd00-3T91K8xNR z?6q*b|U>rbh96}YYKi_smonepTdIhBxf* zi$s3~7E1&W$V$tu56m)sv62tW3Or}vvEBff7K)-yijpmqi9;NzQP?0w*^%kD9ic3u zMHeH2F5MP!8B>o>vA;C-%=sU>T`-oH@>I8u z?U;Hh?#JS%L9pz2erjtz2)1#<-toL_*o)MBq+@(3YtJy!R9}iyV?O^yLr?6?rT85v z0T`hYpiBHKqTlZdT9vB|4h^R-57DD&59)?(Oxk0ai3vk@73dNMwdoT$B+urvCdDe_ z4006;B+nM;3|bDMhXU~$W=W?8Xuup^iXNU0S2c~LibS&XBzlWeW=c$FX&jW4-&~we zPvr8Ga~5p{Lj`z^OLWov4VWx+6aq4l#cCpxCQ?UPA99jOCLi1 zy^SU8;2wB52mcAeHV1XFDC?3guL(tuLk5K}ya`-W%EE>~9mnG+tH>!Y9R_Lun~)}s ztb2e4@5=DUsqryT|SBld1GByz3hOJl0 zstDU31YQCo8wDQ1YZbZZBf`Qj7S?eC=()Q$Scj3nL7=`>LjSZg4#7onWFgA;seyPM zh-0ck+PBz0_MR_oF)^N@(~I-aS^g&_GbW7F%rcS^zqL7S?NF*hN9$NT^N_fOJP>%R z@f&(PYa8>GI{SA= z3Yc_oS1)^bnk9DEN8&gTHj}eXpfxkW>uZcIVHk?*sZ&rtk=CnaeSTvfy z(nh}oGIVy#R?0t-%b0U%9_uZf^(?||fK(OV1j>?+x@0!xGoj!rz8|d_x(pLOfX6xk zAo!tXplVc)3Wuu-vcJUts`+Uvi*=GrR4Ah$p1rak3rSKj38EsZ;!4~9O~i=irFqzh z77!K?C_)(F83YVyS7Ec034fCYwqL?ysQ?g`s7h)ZMJwx?EUu90A_<9!*mhP->M5Z z1B(UD-*#5(Yh<&1ein=dNq~KK-|Jq#<170dKTGX@s>IVWh6^A|=`{qN7+6E#Cj)&P zrPBZ-TF{k&mDE)r!!$eLO4EkTJAEZ@{0i|Lc)IdrzOd}7x?vPh;{D%M@>5e5Ou)2h z0iGg}jf9~ofGpx4z{j=DQ=uQsfsN!{P1U6Vl4a59_0c}|S8b5=vO_(Yk28hb zVn6Bm^L)l+C&K^Q{7&ZVi9oSkPsJJ6(@Me{xO_JOzu17BrQ@5!b| z2F@d`?*+#qMv9%a5-IKFF(%oYz2pBC<2pOnx7Iw3JMlpIZG09~ZR^rG@Gx=TVI+|x zFJVIJli>0Eu5F;7(ImT`cy3=At-L%$`Uup`3x|=orYnm$-plmXtI)HlC7(#>Ods zGkhP{JDHy^WOGL4bkNqoMvou_5U>r>9t8Z>6w^rYCFv{hz7h6TvW6tsyUEr)(5L-U Rs3i1;rb6|h!=Xqh_#eB%cxeCt diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/legacy_attrs.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/legacy_attrs.cpython-38.pyc index 1b645306f27d09a61ca75590f81ad8f0543e7125..af5380fb2a8f70c9632eb4f764e556b32abd75ec 100644 GIT binary patch delta 94 zcmaDa(J#pp%FD~e00c_^cExYx>0)y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7cOlYJWt0NzL;ivR!s delta 62 zcmeB|d@sQh%FD~e00au<8{#(dbg?VD>6hdd=oe%b=w{{>mn7!o=*E}CXUA7&rRwJ< Q7G#)QFCYkKL@x#Kz>Dte=se zo2p+_Sz4Nvsb5@_te=vYmzkQAoL^LuTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp?40O@umD*ylh delta 83 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 QEXq#FFVEXNpGBV)05uyE=l}o! diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/nl2br.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/nl2br.cpython-38.pyc index 6eb574fabaf93920f190e1855e4cd9e63e57f839..cb2251cbc3d804d0a66c560e131e142b2acef4b3 100644 GIT binary patch delta 94 zcmdnXd6$zXl$V!_0SJ`-?TX*X!^i9#ub+{ho2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRpS04xj>x&QzG diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/sane_lists.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/sane_lists.cpython-38.pyc index dec36ec0e97b2ce464c3604356ce816c2241d4dc..c2915ffac72965ba8c675996ffbcd0be02a9068e 100644 GIT binary patch delta 94 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 B-O2y} diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/wikilinks.cpython-38.pyc b/venv/lib/python3.8/site-packages/markdown/extensions/__pycache__/wikilinks.cpython-38.pyc index f1c945d0a163222fa8c2aa9608a5ef2169363bc3..2102caffa32e65b730ac541036144f2d00f57d0b 100644 GIT binary patch delta 107 zcmeB^TqnsB%FD~e00c_^cExYx5oPvC*3Zb#P1P@|EG^B-)Gsbd)=x>y%S_El&MzuS zE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7EZO)Sbz$uG~F?8qp( JIf+?^698#SBy#`& delta 75 zcmZ1{*(b>p%FD~e00au<8{#(dh%)Oq>zCvf=oe%b=w{{>mn7!o=*E}CXUA7&rRwJ< W7GG5lN}jFH#afsZ~_2AzZc~I diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/abbr.py b/venv/lib/python3.8/site-packages/markdown/extensions/abbr.py index b53f2c4..9879314 100644 --- a/venv/lib/python3.8/site-packages/markdown/extensions/abbr.py +++ b/venv/lib/python3.8/site-packages/markdown/extensions/abbr.py @@ -17,48 +17,53 @@ License: [BSD](https://opensource.org/licenses/bsd-license.php) ''' from . import Extension -from ..preprocessors import Preprocessor +from ..blockprocessors import BlockProcessor from ..inlinepatterns import InlineProcessor from ..util import AtomicString import re import xml.etree.ElementTree as etree -# Global Vars -ABBR_REF_RE = re.compile(r'[*]\[(?P[^\]]*)\][ ]?:\s*(?P.*)') - class AbbrExtension(Extension): """ Abbreviation Extension for Python-Markdown. """ def extendMarkdown(self, md): """ Insert AbbrPreprocessor before ReferencePreprocessor. """ - md.preprocessors.register(AbbrPreprocessor(md), 'abbr', 12) + md.parser.blockprocessors.register(AbbrPreprocessor(md.parser), 'abbr', 16) -class AbbrPreprocessor(Preprocessor): +class AbbrPreprocessor(BlockProcessor): """ Abbreviation Preprocessor - parse text for abbr references. """ - def run(self, lines): + RE = re.compile(r'^[*]\[(?P<abbr>[^\]]*)\][ ]?:[ ]*\n?[ ]*(?P<title>.*)$', re.MULTILINE) + + def test(self, parent, block): + return True + + def run(self, parent, blocks): ''' Find and remove all Abbreviation references from the text. Each reference is set as a new AbbrPattern in the markdown instance. ''' - new_text = [] - for line in lines: - m = ABBR_REF_RE.match(line) - if m: - abbr = m.group('abbr').strip() - title = m.group('title').strip() - self.md.inlinePatterns.register( - AbbrInlineProcessor(self._generate_pattern(abbr), title), 'abbr-%s' % abbr, 2 - ) - # Preserve the line to prevent raw HTML indexing issue. - # https://github.com/Python-Markdown/markdown/issues/584 - new_text.append('') - else: - new_text.append(line) - return new_text + block = blocks.pop(0) + m = self.RE.search(block) + if m: + abbr = m.group('abbr').strip() + title = m.group('title').strip() + self.parser.md.inlinePatterns.register( + AbbrInlineProcessor(self._generate_pattern(abbr), title), 'abbr-%s' % abbr, 2 + ) + if block[m.end():].strip(): + # Add any content after match back to blocks as separate block + blocks.insert(0, block[m.end():].lstrip('\n')) + if block[:m.start()].strip(): + # Add any content before match back to blocks as separate block + blocks.insert(0, block[:m.start()].rstrip('\n')) + return True + # No match. Restore block. + blocks.insert(0, block) + return False def _generate_pattern(self, text): ''' diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/admonition.py b/venv/lib/python3.8/site-packages/markdown/extensions/admonition.py index 3926628..01f9940 100644 --- a/venv/lib/python3.8/site-packages/markdown/extensions/admonition.py +++ b/venv/lib/python3.8/site-packages/markdown/extensions/admonition.py @@ -40,19 +40,82 @@ class AdmonitionProcessor(BlockProcessor): RE = re.compile(r'(?:^|\n)!!! ?([\w\-]+(?: +[\w\-]+)*)(?: +"(.*?)")? *(?:\n|$)') RE_SPACES = re.compile(' +') - def test(self, parent, block): + def __init__(self, parser): + """Initialization.""" + + super().__init__(parser) + + self.current_sibling = None + self.content_indention = 0 + + def get_sibling(self, parent, block): + """Get sibling admontion. + + Retrieve the appropriate siblimg element. This can get trickly when + dealing with lists. + + """ + + # We already acquired the block via test + if self.current_sibling is not None: + sibling = self.current_sibling + block = block[self.content_indent:] + self.current_sibling = None + self.content_indent = 0 + return sibling, block + sibling = self.lastChild(parent) - return self.RE.search(block) or \ - (block.startswith(' ' * self.tab_length) and sibling is not None and - sibling.get('class', '').find(self.CLASSNAME) != -1) + + if sibling is None or sibling.get('class', '').find(self.CLASSNAME) == -1: + sibling = None + else: + # If the last child is a list and the content is idented sufficient + # to be under it, then the content's is sibling is in the list. + last_child = self.lastChild(sibling) + indent = 0 + while last_child: + if ( + sibling and block.startswith(' ' * self.tab_length * 2) and + last_child and last_child.tag in ('ul', 'ol', 'dl') + ): + + # The expectation is that we'll find an <li> or <dt>. + # We should get it's last child as well. + sibling = self.lastChild(last_child) + last_child = self.lastChild(sibling) if sibling else None + + # Context has been lost at this point, so we must adjust the + # text's identation level so it will be evaluated correctly + # under the list. + block = block[self.tab_length:] + indent += self.tab_length + else: + last_child = None + + if not block.startswith(' ' * self.tab_length): + sibling = None + + if sibling is not None: + self.current_sibling = sibling + self.content_indent = indent + + return sibling, block + + def test(self, parent, block): + + if self.RE.search(block): + return True + else: + return self.get_sibling(parent, block)[0] is not None def run(self, parent, blocks): - sibling = self.lastChild(parent) block = blocks.pop(0) m = self.RE.search(block) if m: block = block[m.end():] # removes the first line + else: + sibling, block = self.get_sibling(parent, block) block, theRest = self.detab(block) @@ -65,6 +128,13 @@ class AdmonitionProcessor(BlockProcessor): p.text = title p.set('class', self.CLASSNAME_TITLE) else: + # Sibling is a list item, but we need to wrap it's content should be wrapped in <p> + if sibling.tag in ('li', 'dd') and sibling.text: + text = sibling.text + sibling.text = '' + p = etree.SubElement(sibling, 'p') + p.text = text + div = sibling self.parser.parseChunk(div, block) diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/attr_list.py b/venv/lib/python3.8/site-packages/markdown/extensions/attr_list.py index 23c6ad0..9a67551 100644 --- a/venv/lib/python3.8/site-packages/markdown/extensions/attr_list.py +++ b/venv/lib/python3.8/site-packages/markdown/extensions/attr_list.py @@ -64,10 +64,10 @@ def isheader(elem): class AttrListTreeprocessor(Treeprocessor): - BASE_RE = r'\{\:?([^\}\n]*)\}' - HEADER_RE = re.compile(r'[ ]+%s[ ]*$' % BASE_RE) - BLOCK_RE = re.compile(r'\n[ ]*%s[ ]*$' % BASE_RE) - INLINE_RE = re.compile(r'^%s' % BASE_RE) + BASE_RE = r'\{\:?[ ]*([^\}\n ][^\}\n]*)[ ]*\}' + HEADER_RE = re.compile(r'[ ]+{}[ ]*$'.format(BASE_RE)) + BLOCK_RE = re.compile(r'\n[ ]*{}[ ]*$'.format(BASE_RE)) + INLINE_RE = re.compile(r'^{}'.format(BASE_RE)) NAME_RE = re.compile(r'[^A-Z_a-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02ff' r'\u0370-\u037d\u037f-\u1fff\u200c-\u200d' r'\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff' @@ -79,8 +79,8 @@ class AttrListTreeprocessor(Treeprocessor): if self.md.is_block_level(elem.tag): # Block level: check for attrs on last line of text RE = self.BLOCK_RE - if isheader(elem) or elem.tag == 'dt': - # header or def-term: check for attrs at end of line + if isheader(elem) or elem.tag in ['dt', 'td', 'th']: + # header, def-term, or table cell: check for attrs at end of element RE = self.HEADER_RE if len(elem) and elem.tag == 'li': # special case list items. children may include a ul or ol. @@ -120,8 +120,6 @@ class AttrListTreeprocessor(Treeprocessor): elif elem.text: # no children. Get from text. m = RE.search(elem.text) - if not m and elem.tag == 'td': - m = re.search(self.BASE_RE, elem.text) if m: self.assign_attrs(elem, m.group(1)) elem.text = elem.text[:m.start()] @@ -161,6 +159,7 @@ class AttrListTreeprocessor(Treeprocessor): class AttrListExtension(Extension): def extendMarkdown(self, md): md.treeprocessors.register(AttrListTreeprocessor(md), 'attr_list', 8) + md.registerExtension(self) def makeExtension(**kwargs): # pragma: no cover diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/codehilite.py b/venv/lib/python3.8/site-packages/markdown/extensions/codehilite.py index c3f3257..9eed561 100644 --- a/venv/lib/python3.8/site-packages/markdown/extensions/codehilite.py +++ b/venv/lib/python3.8/site-packages/markdown/extensions/codehilite.py @@ -17,13 +17,14 @@ License: [BSD](https://opensource.org/licenses/bsd-license.php) from . import Extension from ..treeprocessors import Treeprocessor +from ..util import parseBoolValue -try: +try: # pragma: no cover from pygments import highlight from pygments.lexers import get_lexer_by_name, guess_lexer from pygments.formatters import get_formatter_by_name pygments = True -except ImportError: +except ImportError: # pragma: no cover pygments = False @@ -38,52 +39,78 @@ def parse_hl_lines(expr): try: return list(map(int, expr.split())) - except ValueError: + except ValueError: # pragma: no cover return [] # ------------------ The Main CodeHilite Class ---------------------- class CodeHilite: """ - Determine language of source code, and pass it into pygments hilighter. + Determine language of source code, and pass it on to the Pygments highlighter. - Basic Usage: - >>> code = CodeHilite(src = 'some text') - >>> html = code.hilite() + Usage: + code = CodeHilite(src=some_code, lang='python') + html = code.hilite() + Arguments: * src: Source string or any object with a .readline attribute. - * linenums: (Boolean) Set line numbering to 'on' (True), - 'off' (False) or 'auto'(None). Set to 'auto' by default. + * lang: String name of Pygments lexer to use for highlighting. Default: `None`. - * guess_lang: (Boolean) Turn language auto-detection - 'on' or 'off' (on by default). + * guess_lang: Auto-detect which lexer to use. Ignored if `lang` is set to a valid + value. Default: `True`. - * css_class: Set class name of wrapper div ('codehilite' by default). + * use_pygments: Pass code to pygments for code highlighting. If `False`, the code is + instead wrapped for highlighting by a JavaScript library. Default: `True`. - * hl_lines: (List of integers) Lines to emphasize, 1-indexed. + * linenums: An alias to Pygments `linenos` formatter option. Default: `None`. - Low Level Usage: - >>> code = CodeHilite() - >>> code.src = 'some text' # String or anything with a .readline attr. - >>> code.linenos = True # Turns line numbering on or of. - >>> html = code.hilite() + * css_class: An alias to Pygments `cssclass` formatter option. Default: 'codehilite'. + + * lang_prefix: Prefix prepended to the language when `use_pygments` is `False`. + Default: "language-". + + Other Options: + Any other options are accepted and passed on to the lexer and formatter. Therefore, + valid options include any options which are accepted by the `html` formatter or + whichever lexer the code's language uses. Note that most lexers do not have any + options. However, a few have very useful options, such as PHP's `startinline` option. + Any invalid options are ignored without error. + + Formatter options: https://pygments.org/docs/formatters/#HtmlFormatter + Lexer Options: https://pygments.org/docs/lexers/ + + Advanced Usage: + code = CodeHilite( + src = some_code, + lang = 'php', + startinline = True, # Lexer option. Snippet does not start with `<?php`. + linenostart = 42, # Formatter option. Snippet starts on line 42. + hl_lines = [45, 49, 50], # Formatter option. Highlight lines 45, 49, and 50. + linenos = 'inline' # Formatter option. Avoid alignment problems. + ) + html = code.hilite() """ - def __init__(self, src=None, linenums=None, guess_lang=True, - css_class="codehilite", lang=None, style='default', - noclasses=False, tab_length=4, hl_lines=None, use_pygments=True): + def __init__(self, src, **options): self.src = src - self.lang = lang - self.linenums = linenums - self.guess_lang = guess_lang - self.css_class = css_class - self.style = style - self.noclasses = noclasses - self.tab_length = tab_length - self.hl_lines = hl_lines or [] - self.use_pygments = use_pygments + self.lang = options.pop('lang', None) + self.guess_lang = options.pop('guess_lang', True) + self.use_pygments = options.pop('use_pygments', True) + self.lang_prefix = options.pop('lang_prefix', 'language-') + + if 'linenos' not in options: + options['linenos'] = options.pop('linenums', None) + if 'cssclass' not in options: + options['cssclass'] = options.pop('css_class', 'codehilite') + if 'wrapcode' not in options: + # Override pygments default + options['wrapcode'] = True + # Disallow use of `full` option + options['full'] = False + + self.options = options def hilite(self): """ @@ -103,22 +130,16 @@ class CodeHilite: if pygments and self.use_pygments: try: - lexer = get_lexer_by_name(self.lang) + lexer = get_lexer_by_name(self.lang, **self.options) except ValueError: try: if self.guess_lang: - lexer = guess_lexer(self.src) + lexer = guess_lexer(self.src, **self.options) else: - lexer = get_lexer_by_name('text') - except ValueError: - lexer = get_lexer_by_name('text') - formatter = get_formatter_by_name('html', - linenos=self.linenums, - cssclass=self.css_class, - style=self.style, - noclasses=self.noclasses, - hl_lines=self.hl_lines, - wrapcode=True) + lexer = get_lexer_by_name('text', **self.options) + except ValueError: # pragma: no cover + lexer = get_lexer_by_name('text', **self.options) + formatter = get_formatter_by_name('html', **self.options) return highlight(self.src, lexer, formatter) else: # just escape and build markup usable by JS highlighting libs @@ -128,27 +149,30 @@ class CodeHilite: txt = txt.replace('"', '"') classes = [] if self.lang: - classes.append('language-%s' % self.lang) - if self.linenums: + classes.append('{}{}'.format(self.lang_prefix, self.lang)) + if self.options['linenos']: classes.append('linenums') class_str = '' if classes: - class_str = ' class="%s"' % ' '.join(classes) - return '<pre class="%s"><code%s>%s</code></pre>\n' % \ - (self.css_class, class_str, txt) + class_str = ' class="{}"'.format(' '.join(classes)) + return '<pre class="{}"><code{}>{}\n</code></pre>\n'.format( + self.options['cssclass'], + class_str, + txt + ) def _parseHeader(self): """ - Determines language of a code block from shebang line and whether said - line should be removed or left in place. If the sheband line contains a - path (even a single /) then it is assumed to be a real shebang line and - left alone. However, if no path is given (e.i.: #!python or :::python) - then it is assumed to be a mock shebang for language identifitation of - a code fragment and removed from the code block prior to processing for - code highlighting. When a mock shebang (e.i: #!python) is found, line - numbering is turned on. When colons are found in place of a shebang - (e.i.: :::python), line numbering is left in the current state - off - by default. + Determines language of a code block from shebang line and whether the + said line should be removed or left in place. If the sheband line + contains a path (even a single /) then it is assumed to be a real + shebang line and left alone. However, if no path is given + (e.i.: #!python or :::python) then it is assumed to be a mock shebang + for language identification of a code fragment and removed from the + code block prior to processing for code highlighting. When a mock + shebang (e.i: #!python) is found, line numbering is turned on. When + colons are found in place of a shebang (e.i.: :::python), line + numbering is left in the current state - off by default. Also parses optional list of highlight lines, like: @@ -176,16 +200,16 @@ class CodeHilite: # we have a match try: self.lang = m.group('lang').lower() - except IndexError: + except IndexError: # pragma: no cover self.lang = None if m.group('path'): # path exists - restore first line lines.insert(0, fl) - if self.linenums is None and m.group('shebang'): + if self.options['linenos'] is None and m.group('shebang'): # Overridable and Shebang exists - use line numbers - self.linenums = True + self.options['linenos'] = True - self.hl_lines = parse_hl_lines(m.group('hl_lines')) + self.options['hl_lines'] = parse_hl_lines(m.group('hl_lines')) else: # No match lines.insert(0, fl) @@ -201,9 +225,11 @@ class HiliteTreeprocessor(Treeprocessor): def code_unescape(self, text): """Unescape code.""" - text = text.replace("&", "&") text = text.replace("<", "<") text = text.replace(">", ">") + # Escaped '&' should be replaced at the end to avoid + # conflicting with < and >. + text = text.replace("&", "&") return text def run(self, root): @@ -213,13 +239,9 @@ class HiliteTreeprocessor(Treeprocessor): if len(block) == 1 and block[0].tag == 'code': code = CodeHilite( self.code_unescape(block[0].text), - linenums=self.config['linenums'], - guess_lang=self.config['guess_lang'], - css_class=self.config['css_class'], - style=self.config['pygments_style'], - noclasses=self.config['noclasses'], tab_length=self.md.tab_length, - use_pygments=self.config['use_pygments'] + style=self.config.pop('pygments_style', 'default'), + **self.config ) placeholder = self.md.htmlStash.store(code.hilite()) # Clear codeblock in etree instance @@ -237,7 +259,7 @@ class CodeHiliteExtension(Extension): # define default configs self.config = { 'linenums': [None, - "Use lines numbers. True=yes, False=no, None=auto"], + "Use lines numbers. True|table|inline=yes, False=no, None=auto"], 'guess_lang': [True, "Automatic language detection - Default: True"], 'css_class': ["codehilite", @@ -252,10 +274,25 @@ class CodeHiliteExtension(Extension): 'use_pygments': [True, 'Use Pygments to Highlight code blocks. ' 'Disable if using a JavaScript library. ' - 'Default: True'] + 'Default: True'], + 'lang_prefix': [ + 'language-', + 'Prefix prepended to the language when use_pygments is false. Default: "language-"' + ] } - super().__init__(**kwargs) + for key, value in kwargs.items(): + if key in self.config: + self.setConfig(key, value) + else: + # manually set unknown keywords. + if isinstance(value, str): + try: + # Attempt to parse str as a bool value + value = parseBoolValue(value, preserve_none=True) + except ValueError: + pass # Assume it's not a bool value. Use as-is. + self.config[key] = [value, ''] def extendMarkdown(self, md): """ Add HilitePostprocessor to Markdown instance. """ diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/def_list.py b/venv/lib/python3.8/site-packages/markdown/extensions/def_list.py index 3978b4d..0e8e452 100644 --- a/venv/lib/python3.8/site-packages/markdown/extensions/def_list.py +++ b/venv/lib/python3.8/site-packages/markdown/extensions/def_list.py @@ -34,8 +34,8 @@ class DefListProcessor(BlockProcessor): raw_block = blocks.pop(0) m = self.RE.search(raw_block) - terms = [l.strip() for l in - raw_block[:m.start()].split('\n') if l.strip()] + terms = [term.strip() for term in + raw_block[:m.start()].split('\n') if term.strip()] block = raw_block[m.end():] no_indent = self.NO_INDENT_RE.match(block) if no_indent: @@ -87,11 +87,13 @@ class DefListProcessor(BlockProcessor): class DefListIndentProcessor(ListIndentProcessor): """ Process indented children of definition list items. """ - ITEM_TYPES = ['dd'] - LIST_TYPES = ['dl'] + # Defintion lists need to be aware of all list types + ITEM_TYPES = ['dd', 'li'] + LIST_TYPES = ['dl', 'ol', 'ul'] def create_item(self, parent, block): - """ Create a new dd and parse the block with it as the parent. """ + """ Create a new dd or li (depending on parent) and parse the block with it as the parent. """ + dd = etree.SubElement(parent, 'dd') self.parser.parseBlocks(dd, [block]) diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/fenced_code.py b/venv/lib/python3.8/site-packages/markdown/extensions/fenced_code.py index 71fac1a..716b467 100644 --- a/venv/lib/python3.8/site-packages/markdown/extensions/fenced_code.py +++ b/venv/lib/python3.8/site-packages/markdown/extensions/fenced_code.py @@ -15,78 +15,130 @@ All changes Copyright 2008-2014 The Python Markdown Project License: [BSD](https://opensource.org/licenses/bsd-license.php) """ + +from textwrap import dedent from . import Extension from ..preprocessors import Preprocessor from .codehilite import CodeHilite, CodeHiliteExtension, parse_hl_lines +from .attr_list import get_attrs, AttrListExtension +from ..util import parseBoolValue import re class FencedCodeExtension(Extension): + def __init__(self, **kwargs): + self.config = { + 'lang_prefix': ['language-', 'Prefix prepended to the language. Default: "language-"'] + } + super().__init__(**kwargs) def extendMarkdown(self, md): """ Add FencedBlockPreprocessor to the Markdown instance. """ md.registerExtension(self) - md.preprocessors.register(FencedBlockPreprocessor(md), 'fenced_code_block', 25) + md.preprocessors.register(FencedBlockPreprocessor(md, self.getConfigs()), 'fenced_code_block', 25) class FencedBlockPreprocessor(Preprocessor): - FENCED_BLOCK_RE = re.compile(r''' -(?P<fence>^(?:~{3,}|`{3,}))[ ]* # Opening ``` or ~~~ -(\{?\.?(?P<lang>[\w#.+-]*))?[ ]* # Optional {, and lang -# Optional highlight lines, single- or double-quote-delimited -(hl_lines=(?P<quot>"|')(?P<hl_lines>.*?)(?P=quot))?[ ]* -}?[ ]*\n # Optional closing } -(?P<code>.*?)(?<=\n) -(?P=fence)[ ]*$''', re.MULTILINE | re.DOTALL | re.VERBOSE) - CODE_WRAP = '<pre><code%s>%s</code></pre>' - LANG_TAG = ' class="%s"' + FENCED_BLOCK_RE = re.compile( + dedent(r''' + (?P<fence>^(?:~{3,}|`{3,}))[ ]* # opening fence + ((\{(?P<attrs>[^\}\n]*)\})?| # (optional {attrs} or + (\.?(?P<lang>[\w#.+-]*))?[ ]* # optional (.)lang + (hl_lines=(?P<quot>"|')(?P<hl_lines>.*?)(?P=quot))?) # optional hl_lines) + [ ]*\n # newline (end of opening fence) + (?P<code>.*?)(?<=\n) # the code block + (?P=fence)[ ]*$ # closing fence + '''), + re.MULTILINE | re.DOTALL | re.VERBOSE + ) - def __init__(self, md): + def __init__(self, md, config): super().__init__(md) - - self.checked_for_codehilite = False + self.config = config + self.checked_for_deps = False self.codehilite_conf = {} + self.use_attr_list = False + # List of options to convert to bool values + self.bool_options = [ + 'linenums', + 'guess_lang', + 'noclasses', + 'use_pygments' + ] def run(self, lines): """ Match and store Fenced Code Blocks in the HtmlStash. """ - # Check for code hilite extension - if not self.checked_for_codehilite: + # Check for dependent extensions + if not self.checked_for_deps: for ext in self.md.registeredExtensions: if isinstance(ext, CodeHiliteExtension): - self.codehilite_conf = ext.config - break + self.codehilite_conf = ext.getConfigs() + if isinstance(ext, AttrListExtension): + self.use_attr_list = True - self.checked_for_codehilite = True + self.checked_for_deps = True text = "\n".join(lines) while 1: m = self.FENCED_BLOCK_RE.search(text) if m: - lang = '' - if m.group('lang'): - lang = self.LANG_TAG % m.group('lang') + lang, id, classes, config = None, '', [], {} + if m.group('attrs'): + id, classes, config = self.handle_attrs(get_attrs(m.group('attrs'))) + if len(classes): + lang = classes.pop(0) + else: + if m.group('lang'): + lang = m.group('lang') + if m.group('hl_lines'): + # Support hl_lines outside of attrs for backward-compatibility + config['hl_lines'] = parse_hl_lines(m.group('hl_lines')) # If config is not empty, then the codehighlite extension # is enabled, so we call it to highlight the code - if self.codehilite_conf: + if self.codehilite_conf and self.codehilite_conf['use_pygments'] and config.get('use_pygments', True): + local_config = self.codehilite_conf.copy() + local_config.update(config) + # Combine classes with cssclass. Ensure cssclass is at end + # as pygments appends a suffix under certain circumstances. + # Ignore ID as Pygments does not offer an option to set it. + if classes: + local_config['css_class'] = '{} {}'.format( + ' '.join(classes), + local_config['css_class'] + ) highliter = CodeHilite( m.group('code'), - linenums=self.codehilite_conf['linenums'][0], - guess_lang=self.codehilite_conf['guess_lang'][0], - css_class=self.codehilite_conf['css_class'][0], - style=self.codehilite_conf['pygments_style'][0], - use_pygments=self.codehilite_conf['use_pygments'][0], - lang=(m.group('lang') or None), - noclasses=self.codehilite_conf['noclasses'][0], - hl_lines=parse_hl_lines(m.group('hl_lines')) + lang=lang, + style=local_config.pop('pygments_style', 'default'), + **local_config ) code = highliter.hilite() else: - code = self.CODE_WRAP % (lang, - self._escape(m.group('code'))) + id_attr = lang_attr = class_attr = kv_pairs = '' + if lang: + lang_attr = ' class="{}{}"'.format(self.config.get('lang_prefix', 'language-'), lang) + if classes: + class_attr = ' class="{}"'.format(' '.join(classes)) + if id: + id_attr = ' id="{}"'.format(id) + if self.use_attr_list and config and not config.get('use_pygments', False): + # Only assign key/value pairs to code element if attr_list ext is enabled, key/value pairs + # were defined on the code block, and the `use_pygments` key was not set to True. The + # `use_pygments` key could be either set to False or not defined. It is omitted from output. + kv_pairs = ' ' + ' '.join( + '{k}="{v}"'.format(k=k, v=v) for k, v in config.items() if k != 'use_pygments' + ) + code = '<pre{id}{cls}><code{lang}{kv}>{code}</code></pre>'.format( + id=id_attr, + cls=class_attr, + lang=lang_attr, + kv=kv_pairs, + code=self._escape(m.group('code')) + ) placeholder = self.md.htmlStash.store(code) text = '{}\n{}\n{}'.format(text[:m.start()], @@ -96,6 +148,24 @@ class FencedBlockPreprocessor(Preprocessor): break return text.split("\n") + def handle_attrs(self, attrs): + """ Return tuple: (id, [list, of, classes], {configs}) """ + id = '' + classes = [] + configs = {} + for k, v in attrs: + if k == 'id': + id = v + elif k == '.': + classes.append(v) + elif k == 'hl_lines': + configs[k] = parse_hl_lines(v) + elif k in self.bool_options: + configs[k] = parseBoolValue(v, fail_on_errors=False, preserve_none=True) + else: + configs[k] = v + return id, classes, configs + def _escape(self, txt): """ basic html escaping """ txt = txt.replace('&', '&') diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/footnotes.py b/venv/lib/python3.8/site-packages/markdown/extensions/footnotes.py index 7d7ad3f..f6f4c85 100644 --- a/venv/lib/python3.8/site-packages/markdown/extensions/footnotes.py +++ b/venv/lib/python3.8/site-packages/markdown/extensions/footnotes.py @@ -14,7 +14,7 @@ License: [BSD](https://opensource.org/licenses/bsd-license.php) """ from . import Extension -from ..preprocessors import Preprocessor +from ..blockprocessors import BlockProcessor from ..inlinepatterns import InlineProcessor from ..treeprocessors import Treeprocessor from ..postprocessors import Postprocessor @@ -26,8 +26,6 @@ import xml.etree.ElementTree as etree FN_BACKLINK_TEXT = util.STX + "zz1337820767766393qq" + util.ETX NBSP_PLACEHOLDER = util.STX + "qq3936677670287331zz" + util.ETX -DEF_RE = re.compile(r'[ ]{0,3}\[\^([^\]]*)\]:\s*(.*)') -TABBED_RE = re.compile(r'((\t)|( ))(.*)') RE_REF_ID = re.compile(r'(fnref)(\d+)') @@ -72,8 +70,8 @@ class FootnoteExtension(Extension): md.registerExtension(self) self.parser = md.parser self.md = md - # Insert a preprocessor before ReferencePreprocessor - md.preprocessors.register(FootnotePreprocessor(self), 'footnote', 15) + # Insert a blockprocessor before ReferencePreprocessor + md.parser.blockprocessors.register(FootnoteBlockProcessor(self), 'footnote', 17) # Insert an inline pattern before ImageReferencePattern FOOTNOTE_RE = r'\[\^([^\]]*)\]' # blah blah [^1] blah @@ -202,106 +200,92 @@ class FootnoteExtension(Extension): return div -class FootnotePreprocessor(Preprocessor): +class FootnoteBlockProcessor(BlockProcessor): """ Find all footnote references and store for later use. """ + RE = re.compile(r'^[ ]{0,3}\[\^([^\]]*)\]:[ ]*(.*)$', re.MULTILINE) + def __init__(self, footnotes): + super().__init__(footnotes.parser) self.footnotes = footnotes - def run(self, lines): - """ - Loop through lines and find, set, and remove footnote definitions. + def test(self, parent, block): + return True - Keywords: + def run(self, parent, blocks): + """ Find, set, and remove footnote definitions. """ + block = blocks.pop(0) + m = self.RE.search(block) + if m: + id = m.group(1) + fn_blocks = [m.group(2)] - * lines: A list of lines of text - - Return: A list of lines of text with footnote definitions removed. - - """ - newlines = [] - i = 0 - while True: - m = DEF_RE.match(lines[i]) - if m: - fn, _i = self.detectTabbed(lines[i+1:]) - fn.insert(0, m.group(2)) - i += _i-1 # skip past footnote - footnote = "\n".join(fn) - self.footnotes.setFootnote(m.group(1), footnote.rstrip()) - # Preserve a line for each block to prevent raw HTML indexing issue. - # https://github.com/Python-Markdown/markdown/issues/584 - num_blocks = (len(footnote.split('\n\n')) * 2) - newlines.extend([''] * (num_blocks)) + # Handle rest of block + therest = block[m.end():].lstrip('\n') + m2 = self.RE.search(therest) + if m2: + # Another footnote exists in the rest of this block. + # Any content before match is continuation of this footnote, which may be lazily indented. + before = therest[:m2.start()].rstrip('\n') + fn_blocks[0] = '\n'.join([fn_blocks[0], self.detab(before)]).lstrip('\n') + # Add back to blocks everything from begining of match forward for next iteration. + blocks.insert(0, therest[m2.start():]) else: - newlines.append(lines[i]) - if len(lines) > i+1: - i += 1 - else: - break - return newlines + # All remaining lines of block are continuation of this footnote, which may be lazily indented. + fn_blocks[0] = '\n'.join([fn_blocks[0], self.detab(therest)]).strip('\n') - def detectTabbed(self, lines): + # Check for child elements in remaining blocks. + fn_blocks.extend(self.detectTabbed(blocks)) + + footnote = "\n\n".join(fn_blocks) + self.footnotes.setFootnote(id, footnote.rstrip()) + + if block[:m.start()].strip(): + # Add any content before match back to blocks as separate block + blocks.insert(0, block[:m.start()].rstrip('\n')) + return True + # No match. Restore block. + blocks.insert(0, block) + return False + + def detectTabbed(self, blocks): """ Find indented text and remove indent before further proccesing. - Keyword arguments: - - * lines: an array of strings - - Returns: a list of post processed items and the index of last line. - + Returns: a list of blocks with indentation removed. """ - items = [] - blank_line = False # have we encountered a blank line yet? - i = 0 # to keep track of where we are - - def detab(line): - match = TABBED_RE.match(line) - if match: - return match.group(4) - - for line in lines: - if line.strip(): # Non-blank line - detabbed_line = detab(line) - if detabbed_line: - items.append(detabbed_line) - i += 1 - continue - elif not blank_line and not DEF_RE.match(line): - # not tabbed but still part of first par. - items.append(line) - i += 1 - continue + fn_blocks = [] + while blocks: + if blocks[0].startswith(' '*4): + block = blocks.pop(0) + # Check for new footnotes within this block and split at new footnote. + m = self.RE.search(block) + if m: + # Another footnote exists in this block. + # Any content before match is continuation of this footnote, which may be lazily indented. + before = block[:m.start()].rstrip('\n') + fn_blocks.append(self.detab(before)) + # Add back to blocks everything from begining of match forward for next iteration. + blocks.insert(0, block[m.start():]) + # End of this footnote. + break else: - return items, i+1 + # Entire block is part of this footnote. + fn_blocks.append(self.detab(block)) + else: + # End of this footnote. + break + return fn_blocks - else: # Blank line: _maybe_ we are done. - blank_line = True - i += 1 # advance + def detab(self, block): + """ Remove one level of indent from a block. - # Find the next non-blank line - for j in range(i, len(lines)): - if lines[j].strip(): - next_line = lines[j] - break - else: - # Include extreaneous padding to prevent raw HTML - # parsing issue: https://github.com/Python-Markdown/markdown/issues/584 - items.append("") - i += 1 - else: - break # There is no more text; we are done. - - # Check if the next non-blank line is tabbed - if detab(next_line): # Yes, more work to do. - items.append("") - continue - else: - break # No, we are done. - else: - i += 1 - - return items, i + Preserve lazily indented blocks by only removing indent from indented lines. + """ + lines = block.split('\n') + for i, line in enumerate(lines): + if line.startswith(' '*4): + lines[i] = line[4:] + return '\n'.join(lines) class FootnoteInlineProcessor(InlineProcessor): @@ -347,8 +331,8 @@ class FootnotePostTreeprocessor(Treeprocessor): self.offset += 1 # Add all the new duplicate links. el = list(li)[-1] - for l in links: - el.append(l) + for link in links: + el.append(link) break def get_num_duplicates(self, li): diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/legacy_em.py b/venv/lib/python3.8/site-packages/markdown/extensions/legacy_em.py index c3d7b54..7fddb77 100644 --- a/venv/lib/python3.8/site-packages/markdown/extensions/legacy_em.py +++ b/venv/lib/python3.8/site-packages/markdown/extensions/legacy_em.py @@ -21,7 +21,7 @@ EMPHASIS_RE = r'(_)([^_]+)\1' STRONG_RE = r'(_{2})(.+?)\1' # __strong_em___ -STRONG_EM_RE = r'(_)\1(?!\1)(.+?)\1(?!\1)(.+?)\1{3}' +STRONG_EM_RE = r'(_)\1(?!\1)([^_]+?)\1(?!\1)(.+?)\1{3}' class LegacyUnderscoreProcessor(UnderscoreProcessor): diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/md_in_html.py b/venv/lib/python3.8/site-packages/markdown/extensions/md_in_html.py index 500c166..eb8902e 100644 --- a/venv/lib/python3.8/site-packages/markdown/extensions/md_in_html.py +++ b/venv/lib/python3.8/site-packages/markdown/extensions/md_in_html.py @@ -16,68 +16,313 @@ License: [BSD](https://opensource.org/licenses/bsd-license.php) from . import Extension from ..blockprocessors import BlockProcessor +from ..preprocessors import Preprocessor +from ..postprocessors import RawHtmlPostprocessor from .. import util -import re +from ..htmlparser import HTMLExtractor import xml.etree.ElementTree as etree -class MarkdownInHtmlProcessor(BlockProcessor): - """Process Markdown Inside HTML Blocks.""" - def test(self, parent, block): - return block == util.TAG_PLACEHOLDER % \ - str(self.parser.blockprocessors.tag_counter + 1) +class HTMLExtractorExtra(HTMLExtractor): + """ + Override HTMLExtractor and create etree Elements for any elements which should have content parsed as Markdown. + """ - def _process_nests(self, element, block): - """Process the element's child elements in self.run.""" - # Build list of indexes of each nest within the parent element. - nest_index = [] # a list of tuples: (left index, right index) - i = self.parser.blockprocessors.tag_counter + 1 - while len(self._tag_data) > i and self._tag_data[i]['left_index']: - left_child_index = self._tag_data[i]['left_index'] - right_child_index = self._tag_data[i]['right_index'] - nest_index.append((left_child_index - 1, right_child_index)) - i += 1 + def __init__(self, md, *args, **kwargs): + # All block-level tags. + self.block_level_tags = set(md.block_level_elements.copy()) + # Block-level tags in which the content only gets span level parsing + self.span_tags = set( + ['address', 'dd', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'legend', 'li', 'p', 'td', 'th'] + ) + # Block-level tags which never get their content parsed. + self.raw_tags = set(['canvas', 'math', 'option', 'pre', 'script', 'style', 'textarea']) + # Block-level tags in which the content gets parsed as blocks + super().__init__(md, *args, **kwargs) - # Create each nest subelement. - for i, (left_index, right_index) in enumerate(nest_index[:-1]): - self.run(element, block[left_index:right_index], - block[right_index:nest_index[i + 1][0]], True) - self.run(element, block[nest_index[-1][0]:nest_index[-1][1]], # last - block[nest_index[-1][1]:], True) # nest + self.block_tags = set(self.block_level_tags) - (self.span_tags | self.raw_tags | self.empty_tags) + self.span_and_blocks_tags = self.block_tags | self.span_tags - def run(self, parent, blocks, tail=None, nest=False): - self._tag_data = self.parser.md.htmlStash.tag_data + def reset(self): + """Reset this instance. Loses all unprocessed data.""" + self.mdstack = [] # When markdown=1, stack contains a list of tags + self.treebuilder = etree.TreeBuilder() + self.mdstate = [] # one of 'block', 'span', 'off', or None + super().reset() - self.parser.blockprocessors.tag_counter += 1 - tag = self._tag_data[self.parser.blockprocessors.tag_counter] + def close(self): + """Handle any buffered data.""" + super().close() + # Handle any unclosed tags. + if self.mdstack: + # Close the outermost parent. handle_endtag will close all unclosed children. + self.handle_endtag(self.mdstack[0]) - # Create Element - markdown_value = tag['attrs'].pop('markdown') - element = etree.SubElement(parent, tag['tag'], tag['attrs']) + def get_element(self): + """ Return element from treebuilder and reset treebuilder for later use. """ + element = self.treebuilder.close() + self.treebuilder = etree.TreeBuilder() + return element - # Slice Off Block - if nest: - self.parser.parseBlocks(parent, tail) # Process Tail - block = blocks[1:] - else: # includes nests since a third level of nesting isn't supported - block = blocks[tag['left_index'] + 1: tag['right_index']] - del blocks[:tag['right_index']] + def get_state(self, tag, attrs): + """ Return state from tag and `markdown` attr. One of 'block', 'span', or 'off'. """ + md_attr = attrs.get('markdown', '0') + if md_attr == 'markdown': + # `<tag markdown>` is the same as `<tag markdown='1'>`. + md_attr = '1' + parent_state = self.mdstate[-1] if self.mdstate else None + if parent_state == 'off' or (parent_state == 'span' and md_attr != '0'): + # Only use the parent state if it is more restrictive than the markdown attribute. + md_attr = parent_state + if ((md_attr == '1' and tag in self.block_tags) or + (md_attr == 'block' and tag in self.span_and_blocks_tags)): + return 'block' + elif ((md_attr == '1' and tag in self.span_tags) or + (md_attr == 'span' and tag in self.span_and_blocks_tags)): + return 'span' + elif tag in self.block_level_tags: + return 'off' + else: # pragma: no cover + return None - # Process Text - if (self.parser.blockprocessors.contain_span_tags.match( # Span Mode - tag['tag']) and markdown_value != 'block') or \ - markdown_value == 'span': - element.text = '\n'.join(block) - else: # Block Mode - i = self.parser.blockprocessors.tag_counter + 1 - if len(self._tag_data) > i and self._tag_data[i]['left_index']: - first_subelement_index = self._tag_data[i]['left_index'] - 1 - self.parser.parseBlocks( - element, block[:first_subelement_index]) - if not nest: - block = self._process_nests(element, block) + def at_line_start(self): + """At line start.""" + + value = super().at_line_start() + if not value and self.cleandoc and self.cleandoc[-1].endswith('\n'): + value = True + return value + + def handle_starttag(self, tag, attrs): + # Handle tags that should always be empty and do not specify a closing tag + if tag in self.empty_tags: + attrs = {key: value if value is not None else key for key, value in attrs} + if "markdown" in attrs: + attrs.pop('markdown') + element = etree.Element(tag, attrs) + data = etree.tostring(element, encoding='unicode', method='html') else: - self.parser.parseBlocks(element, block) + data = self.get_starttag_text() + self.handle_empty_tag(data, True) + return + + if tag in self.block_level_tags: + # Valueless attr (ex: `<tag checked>`) results in `[('checked', None)]`. + # Convert to `{'checked': 'checked'}`. + attrs = {key: value if value is not None else key for key, value in attrs} + state = self.get_state(tag, attrs) + + if self.inraw or (state in [None, 'off'] and not self.mdstack) or not self.at_line_start(): + # fall back to default behavior + attrs.pop('markdown', None) + super().handle_starttag(tag, attrs) + else: + if 'p' in self.mdstack and tag in self.block_level_tags: + # Close unclosed 'p' tag + self.handle_endtag('p') + self.mdstate.append(state) + self.mdstack.append(tag) + attrs['markdown'] = state + self.treebuilder.start(tag, attrs) + else: + # Span level tag + if self.inraw: + super().handle_starttag(tag, attrs) + else: + text = self.get_starttag_text() + if self.mdstate and self.mdstate[-1] == "off": + self.handle_data(self.md.htmlStash.store(text)) + else: + self.handle_data(text) + + def handle_endtag(self, tag): + if tag in self.block_level_tags: + if self.inraw: + super().handle_endtag(tag) + elif tag in self.mdstack: + # Close element and any unclosed children + while self.mdstack: + item = self.mdstack.pop() + self.mdstate.pop() + self.treebuilder.end(item) + if item == tag: + break + if not self.mdstack: + # Last item in stack is closed. Stash it + element = self.get_element() + # Get last entry to see if it ends in newlines + # If it is an element, assume there is no newlines + item = self.cleandoc[-1] if self.cleandoc else '' + # If we only have one newline before block element, add another + if not item.endswith('\n\n') and item.endswith('\n'): + self.cleandoc.append('\n') + self.cleandoc.append(self.md.htmlStash.store(element)) + self.cleandoc.append('\n\n') + self.state = [] + else: + # Treat orphan closing tag as a span level tag. + text = self.get_endtag_text(tag) + if self.mdstate and self.mdstate[-1] == "off": + self.handle_data(self.md.htmlStash.store(text)) + else: + self.handle_data(text) + else: + # Span level tag + if self.inraw: + super().handle_endtag(tag) + else: + text = self.get_endtag_text(tag) + if self.mdstate and self.mdstate[-1] == "off": + self.handle_data(self.md.htmlStash.store(text)) + else: + self.handle_data(text) + + def handle_startendtag(self, tag, attrs): + if tag in self.empty_tags: + attrs = {key: value if value is not None else key for key, value in attrs} + if "markdown" in attrs: + attrs.pop('markdown') + element = etree.Element(tag, attrs) + data = etree.tostring(element, encoding='unicode', method='html') + else: + data = self.get_starttag_text() + else: + data = self.get_starttag_text() + self.handle_empty_tag(data, is_block=self.md.is_block_level(tag)) + + def handle_data(self, data): + if self.inraw or not self.mdstack: + super().handle_data(data) + else: + self.treebuilder.data(data) + + def handle_empty_tag(self, data, is_block): + if self.inraw or not self.mdstack: + super().handle_empty_tag(data, is_block) + else: + if self.at_line_start() and is_block: + self.handle_data('\n' + self.md.htmlStash.store(data) + '\n\n') + else: + if self.mdstate and self.mdstate[-1] == "off": + self.handle_data(self.md.htmlStash.store(data)) + else: + self.handle_data(data) + + +class HtmlBlockPreprocessor(Preprocessor): + """Remove html blocks from the text and store them for later retrieval.""" + + def run(self, lines): + source = '\n'.join(lines) + parser = HTMLExtractorExtra(self.md) + parser.feed(source) + parser.close() + return ''.join(parser.cleandoc).split('\n') + + +class MarkdownInHtmlProcessor(BlockProcessor): + """Process Markdown Inside HTML Blocks which have been stored in the HtmlStash.""" + + def test(self, parent, block): + # ALways return True. `run` will return `False` it not a valid match. + return True + + def parse_element_content(self, element): + """ + Resursively parse the text content of an etree Element as Markdown. + + Any block level elements generated from the Markdown will be inserted as children of the element in place + of the text content. All `markdown` attributes are removed. For any elements in which Markdown parsing has + been dissabled, the text content of it and its chidlren are wrapped in an `AtomicString`. + """ + + md_attr = element.attrib.pop('markdown', 'off') + + if md_attr == 'block': + # Parse content as block level + # The order in which the different parts are parsed (text, children, tails) is important here as the + # order of elements needs to be preserved. We can't be inserting items at a later point in the current + # iteration as we don't want to do raw processing on elements created from parsing Markdown text (for + # example). Therefore, the order of operations is children, tails, text. + + # Recursively parse existing children from raw HTML + for child in list(element): + self.parse_element_content(child) + + # Parse Markdown text in tail of children. Do this seperate to avoid raw HTML parsing. + # Save the position of each item to be inserted later in reverse. + tails = [] + for pos, child in enumerate(element): + if child.tail: + block = child.tail.rstrip('\n') + child.tail = '' + # Use a dummy placeholder element. + dummy = etree.Element('div') + self.parser.parseBlocks(dummy, block.split('\n\n')) + children = list(dummy) + children.reverse() + tails.append((pos + 1, children)) + + # Insert the elements created from the tails in reverse. + tails.reverse() + for pos, tail in tails: + for item in tail: + element.insert(pos, item) + + # Parse Markdown text content. Do this last to avoid raw HTML parsing. + if element.text: + block = element.text.rstrip('\n') + element.text = '' + # Use a dummy placeholder element as the content needs to get inserted before existing children. + dummy = etree.Element('div') + self.parser.parseBlocks(dummy, block.split('\n\n')) + children = list(dummy) + children.reverse() + for child in children: + element.insert(0, child) + + elif md_attr == 'span': + # Span level parsing will be handled by inlineprocessors. + # Walk children here to remove any `markdown` attributes. + for child in list(element): + self.parse_element_content(child) + + else: + # Disable inline parsing for everything else + if element.text is None: + element.text = '' + element.text = util.AtomicString(element.text) + for child in list(element): + self.parse_element_content(child) + if child.tail: + child.tail = util.AtomicString(child.tail) + + def run(self, parent, blocks): + m = util.HTML_PLACEHOLDER_RE.match(blocks[0]) + if m: + index = int(m.group(1)) + element = self.parser.md.htmlStash.rawHtmlBlocks[index] + if isinstance(element, etree.Element): + # We have a matched element. Process it. + blocks.pop(0) + self.parse_element_content(element) + parent.append(element) + # Cleanup stash. Replace element with empty string to avoid confusing postprocessor. + self.parser.md.htmlStash.rawHtmlBlocks.pop(index) + self.parser.md.htmlStash.rawHtmlBlocks.insert(index, '') + # Comfirm the match to the blockparser. + return True + # No match found. + return False + + +class MarkdownInHTMLPostprocessor(RawHtmlPostprocessor): + def stash_to_string(self, text): + """ Override default to handle any etree elements still in the stash. """ + if isinstance(text, etree.Element): + return self.md.serializer(text) + else: + return str(text) class MarkdownInHtmlExtension(Extension): @@ -86,14 +331,14 @@ class MarkdownInHtmlExtension(Extension): def extendMarkdown(self, md): """ Register extension instances. """ - # Turn on processing of markdown text within raw html - md.preprocessors['html_block'].markdown_in_raw = True + # Replace raw HTML preprocessor + md.preprocessors.register(HtmlBlockPreprocessor(md), 'html_block', 20) + # Add blockprocessor which handles the placeholders for etree elements md.parser.blockprocessors.register( MarkdownInHtmlProcessor(md.parser), 'markdown_block', 105 ) - md.parser.blockprocessors.tag_counter = -1 - md.parser.blockprocessors.contain_span_tags = re.compile( - r'^(p|h[1-6]|li|dd|dt|td|th|legend|address)$', re.IGNORECASE) + # Replace raw HTML postprocessor + md.postprocessors.register(MarkdownInHTMLPostprocessor(md), 'raw_html', 30) def makeExtension(**kwargs): # pragma: no cover diff --git a/venv/lib/python3.8/site-packages/markdown/extensions/toc.py b/venv/lib/python3.8/site-packages/markdown/extensions/toc.py index 8f2b13f..b2564c9 100644 --- a/venv/lib/python3.8/site-packages/markdown/extensions/toc.py +++ b/venv/lib/python3.8/site-packages/markdown/extensions/toc.py @@ -15,18 +15,24 @@ License: [BSD](https://opensource.org/licenses/bsd-license.php) from . import Extension from ..treeprocessors import Treeprocessor -from ..util import code_escape, parseBoolValue, AMP_SUBSTITUTE, HTML_PLACEHOLDER_RE +from ..util import code_escape, parseBoolValue, AMP_SUBSTITUTE, HTML_PLACEHOLDER_RE, AtomicString from ..postprocessors import UnescapePostprocessor import re +import html import unicodedata import xml.etree.ElementTree as etree -def slugify(value, separator): +def slugify(value, separator, encoding='ascii'): """ Slugify a string, to make it URL friendly. """ - value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore') - value = re.sub(r'[^\w\s-]', '', value.decode('ascii')).strip().lower() - return re.sub(r'[%s\s]+' % separator, separator, value) + value = unicodedata.normalize('NFKD', value).encode(encoding, 'ignore') + value = re.sub(r'[^\w\s-]', '', value.decode(encoding)).strip().lower() + return re.sub(r'[{}\s]+'.format(separator), separator, value) + + +def slugify_unicode(value, separator): + """ Slugify a string, to make it URL friendly while preserving Unicode characters. """ + return slugify(value, separator, 'utf-8') IDCOUNT_RE = re.compile(r'^(.*)_([0-9]+)$') @@ -44,6 +50,18 @@ def unique(id, ids): return id +def get_name(el): + """Get title name.""" + + text = [] + for c in el.itertext(): + if isinstance(c, AtomicString): + text.append(html.unescape(c)) + else: + text.append(c) + return ''.join(text).strip() + + def stashedHTML2text(text, md, strip_entities=True): """ Extract raw HTML from stash, reduce to plain text and swap with placeholder. """ def _html_sub(m): @@ -253,7 +271,7 @@ class TocTreeprocessor(Treeprocessor): self.set_level(el) if int(el.tag[-1]) < self.toc_top or int(el.tag[-1]) > self.toc_bottom: continue - text = ''.join(el.itertext()).strip() + text = get_name(el) # Do not override pre-existing ids if "id" not in el.attrib: diff --git a/venv/lib/python3.8/site-packages/markdown/inlinepatterns.py b/venv/lib/python3.8/site-packages/markdown/inlinepatterns.py index ad95519..1d0a7e1 100644 --- a/venv/lib/python3.8/site-packages/markdown/inlinepatterns.py +++ b/venv/lib/python3.8/site-packages/markdown/inlinepatterns.py @@ -84,6 +84,9 @@ def build_inlinepatterns(md, **kwargs): inlinePatterns.register( ShortReferenceInlineProcessor(REFERENCE_RE, md), 'short_reference', 130 ) + inlinePatterns.register( + ShortImageReferenceInlineProcessor(IMAGE_REFERENCE_RE, md), 'short_image_ref', 125 + ) inlinePatterns.register(AutolinkInlineProcessor(AUTOLINK_RE, md), 'autolink', 120) inlinePatterns.register(AutomailInlineProcessor(AUTOMAIL_RE, md), 'automail', 110) inlinePatterns.register(SubstituteTagInlineProcessor(LINE_BREAK_RE, 'br'), 'linebreak', 100) @@ -135,8 +138,8 @@ STRONG_EM_RE = r'(\*)\1{2}(.+?)\1{2}(.*?)\1' # ___strong__em_ STRONG_EM2_RE = r'(_)\1{2}(.+?)\1{2}(.*?)\1' -# __strong_em___ -STRONG_EM3_RE = r'(\*)\1(?!\1)(.+?)\1(?!\1)(.+?)\1{3}' +# **strong*em*** +STRONG_EM3_RE = r'(\*)\1(?!\1)([^*]+?)\1(?!\1)(.+?)\1{3}' # [text](url) or [text](<url>) or [text](url "title") LINK_RE = NOIMG + r'\[' @@ -844,6 +847,14 @@ class ImageReferenceInlineProcessor(ReferenceInlineProcessor): return el +class ShortImageReferenceInlineProcessor(ImageReferenceInlineProcessor): + """ Short form of inage reference: ![ref]. """ + def evalId(self, data, index, text): + """Evaluate the id from of [ref] """ + + return text.lower(), index, True + + class AutolinkInlineProcessor(InlineProcessor): """ Return a link Element given an autolink (`<http://example/com>`). """ def handleMatch(self, m, data): diff --git a/venv/lib/python3.8/site-packages/markdown/postprocessors.py b/venv/lib/python3.8/site-packages/markdown/postprocessors.py index 95b85cd..2e68cd9 100644 --- a/venv/lib/python3.8/site-packages/markdown/postprocessors.py +++ b/venv/lib/python3.8/site-packages/markdown/postprocessors.py @@ -69,11 +69,10 @@ class RawHtmlPostprocessor(Postprocessor): """ Iterate over html stash and restore html. """ replacements = OrderedDict() for i in range(self.md.htmlStash.html_counter): - html = self.md.htmlStash.rawHtmlBlocks[i] + html = self.stash_to_string(self.md.htmlStash.rawHtmlBlocks[i]) if self.isblocklevel(html): - replacements["<p>%s</p>" % - (self.md.htmlStash.get_placeholder(i))] = \ - html + "\n" + replacements["<p>{}</p>".format( + self.md.htmlStash.get_placeholder(i))] = html replacements[self.md.htmlStash.get_placeholder(i)] = html if replacements: @@ -96,6 +95,10 @@ class RawHtmlPostprocessor(Postprocessor): return self.md.is_block_level(m.group(1)) return False + def stash_to_string(self, text): + """ Convert a stashed object to a string. """ + return str(text) + class AndSubstitutePostprocessor(Postprocessor): """ Restore valid entities """ diff --git a/venv/lib/python3.8/site-packages/markdown/preprocessors.py b/venv/lib/python3.8/site-packages/markdown/preprocessors.py index f12a02a..e1023c5 100644 --- a/venv/lib/python3.8/site-packages/markdown/preprocessors.py +++ b/venv/lib/python3.8/site-packages/markdown/preprocessors.py @@ -26,6 +26,7 @@ complicated. """ from . import util +from .htmlparser import HTMLExtractor import re @@ -34,7 +35,6 @@ def build_preprocessors(md, **kwargs): preprocessors = util.Registry() preprocessors.register(NormalizeWhitespace(md), 'normalize_whitespace', 30) preprocessors.register(HtmlBlockPreprocessor(md), 'html_block', 20) - preprocessors.register(ReferencePreprocessor(md), 'reference', 10) return preprocessors @@ -74,297 +74,9 @@ class NormalizeWhitespace(Preprocessor): class HtmlBlockPreprocessor(Preprocessor): """Remove html blocks from the text and store them for later retrieval.""" - right_tag_patterns = ["</%s>", "%s>"] - attrs_pattern = r""" - \s+(?P<attr>[^>"'/= ]+)=(?P<q>['"])(?P<value>.*?)(?P=q) # attr="value" - | # OR - \s+(?P<attr1>[^>"'/= ]+)=(?P<value1>[^> ]+) # attr=value - | # OR - \s+(?P<attr2>[^>"'/= ]+) # attr - """ - left_tag_pattern = r'^\<(?P<tag>[^> ]+)(?P<attrs>(%s)*)\s*\/?\>?' % \ - attrs_pattern - attrs_re = re.compile(attrs_pattern, re.VERBOSE) - left_tag_re = re.compile(left_tag_pattern, re.VERBOSE) - markdown_in_raw = False - - def _get_left_tag(self, block): - m = self.left_tag_re.match(block) - if m: - tag = m.group('tag') - raw_attrs = m.group('attrs') - attrs = {} - if raw_attrs: - for ma in self.attrs_re.finditer(raw_attrs): - if ma.group('attr'): - if ma.group('value'): - attrs[ma.group('attr').strip()] = ma.group('value') - else: - attrs[ma.group('attr').strip()] = "" - elif ma.group('attr1'): - if ma.group('value1'): - attrs[ma.group('attr1').strip()] = ma.group( - 'value1' - ) - else: - attrs[ma.group('attr1').strip()] = "" - elif ma.group('attr2'): - attrs[ma.group('attr2').strip()] = "" - return tag, len(m.group(0)), attrs - else: - tag = block[1:].split(">", 1)[0].lower() - return tag, len(tag)+2, {} - - def _recursive_tagfind(self, ltag, rtag, start_index, block): - while 1: - i = block.find(rtag, start_index) - if i == -1: - return -1 - j = block.find(ltag, start_index) - # if no ltag, or rtag found before another ltag, return index - if (j > i or j == -1): - return i + len(rtag) - # another ltag found before rtag, use end of ltag as starting - # point and search again - j = block.find('>', j) - start_index = self._recursive_tagfind(ltag, rtag, j + 1, block) - if start_index == -1: - # HTML potentially malformed- ltag has no corresponding - # rtag - return -1 - - def _get_right_tag(self, left_tag, left_index, block): - for p in self.right_tag_patterns: - tag = p % left_tag - i = self._recursive_tagfind( - "<%s" % left_tag, tag, left_index, block - ) - if i > 2: - return tag.lstrip("<").rstrip(">"), i - return block.rstrip()[-left_index:-1].lower(), len(block) - - def _equal_tags(self, left_tag, right_tag): - if left_tag[0] in ['?', '@', '%']: # handle PHP, etc. - return True - if ("/" + left_tag) == right_tag: - return True - if (right_tag == "--" and left_tag == "--"): - return True - elif left_tag == right_tag[1:] and right_tag[0] == "/": - return True - else: - return False - - def _is_oneliner(self, tag): - return (tag in ['hr', 'hr/']) - - def _stringindex_to_listindex(self, stringindex, items): - """ - Same effect as concatenating the strings in items, - finding the character to which stringindex refers in that string, - and returning the index of the item in which that character resides. - """ - items.append('dummy') - i, count = 0, 0 - while count <= stringindex: - count += len(items[i]) - i += 1 - return i - 1 - - def _nested_markdown_in_html(self, items): - """Find and process html child elements of the given element block.""" - for i, item in enumerate(items): - if self.left_tag_re.match(item): - left_tag, left_index, attrs = \ - self._get_left_tag(''.join(items[i:])) - right_tag, data_index = self._get_right_tag( - left_tag, left_index, ''.join(items[i:])) - right_listindex = \ - self._stringindex_to_listindex(data_index, items[i:]) + i - if 'markdown' in attrs.keys(): - items[i] = items[i][left_index:] # remove opening tag - placeholder = self.md.htmlStash.store_tag( - left_tag, attrs, i + 1, right_listindex + 1) - items.insert(i, placeholder) - if len(items) - right_listindex <= 1: # last nest, no tail - right_listindex -= 1 - items[right_listindex] = items[right_listindex][ - :-len(right_tag) - 2] # remove closing tag - else: # raw html - if len(items) - right_listindex <= 1: # last element - right_listindex -= 1 - if right_listindex <= i: - right_listindex = i + 1 - placeholder = self.md.htmlStash.store('\n\n'.join( - items[i:right_listindex])) - del items[i:right_listindex] - items.insert(i, placeholder) - return items - def run(self, lines): - text = "\n".join(lines) - new_blocks = [] - text = text.rsplit("\n\n") - items = [] - left_tag = '' - right_tag = '' - in_tag = False # flag - - while text: - block = text[0] - if block.startswith("\n"): - block = block[1:] - text = text[1:] - - if block.startswith("\n"): - block = block[1:] - - if not in_tag: - if block.startswith("<") and len(block.strip()) > 1: - - if block[1:4] == "!--": - # is a comment block - left_tag, left_index, attrs = "--", 2, {} - else: - left_tag, left_index, attrs = self._get_left_tag(block) - right_tag, data_index = self._get_right_tag(left_tag, - left_index, - block) - # keep checking conditions below and maybe just append - - if data_index < len(block) and (self.md.is_block_level(left_tag) or left_tag == '--'): - text.insert(0, block[data_index:]) - block = block[:data_index] - - if not (self.md.is_block_level(left_tag) or block[1] in ["!", "?", "@", "%"]): - new_blocks.append(block) - continue - - if self._is_oneliner(left_tag): - new_blocks.append(block.strip()) - continue - - if block.rstrip().endswith(">") \ - and self._equal_tags(left_tag, right_tag): - if self.markdown_in_raw and 'markdown' in attrs.keys(): - block = block[left_index:-len(right_tag) - 2] - new_blocks.append(self.md.htmlStash. - store_tag(left_tag, attrs, 0, 2)) - new_blocks.extend([block]) - else: - new_blocks.append( - self.md.htmlStash.store(block.strip())) - continue - else: - # if is block level tag and is not complete - if (not self._equal_tags(left_tag, right_tag)) and \ - (self.md.is_block_level(left_tag) or left_tag == "--"): - items.append(block.strip()) - in_tag = True - else: - new_blocks.append( - self.md.htmlStash.store(block.strip()) - ) - continue - - else: - new_blocks.append(block) - - else: - items.append(block) - - # Need to evaluate all items so we can calculate relative to the left index. - right_tag, data_index = self._get_right_tag(left_tag, left_index, ''.join(items)) - # Adjust data_index: relative to items -> relative to last block - prev_block_length = 0 - for item in items[:-1]: - prev_block_length += len(item) - data_index -= prev_block_length - - if self._equal_tags(left_tag, right_tag): - # if find closing tag - - if data_index < len(block): - # we have more text after right_tag - items[-1] = block[:data_index] - text.insert(0, block[data_index:]) - - in_tag = False - if self.markdown_in_raw and 'markdown' in attrs.keys(): - items[0] = items[0][left_index:] - items[-1] = items[-1][:-len(right_tag) - 2] - if items[len(items) - 1]: # not a newline/empty string - right_index = len(items) + 3 - else: - right_index = len(items) + 2 - new_blocks.append(self.md.htmlStash.store_tag( - left_tag, attrs, 0, right_index)) - placeholderslen = len(self.md.htmlStash.tag_data) - new_blocks.extend( - self._nested_markdown_in_html(items)) - nests = len(self.md.htmlStash.tag_data) - \ - placeholderslen - self.md.htmlStash.tag_data[-1 - nests][ - 'right_index'] += nests - 2 - else: - new_blocks.append( - self.md.htmlStash.store('\n\n'.join(items))) - items = [] - - if items: - if self.markdown_in_raw and 'markdown' in attrs.keys(): - items[0] = items[0][left_index:] - items[-1] = items[-1][:-len(right_tag) - 2] - if items[len(items) - 1]: # not a newline/empty string - right_index = len(items) + 3 - else: - right_index = len(items) + 2 - new_blocks.append( - self.md.htmlStash.store_tag( - left_tag, attrs, 0, right_index)) - placeholderslen = len(self.md.htmlStash.tag_data) - new_blocks.extend(self._nested_markdown_in_html(items)) - nests = len(self.md.htmlStash.tag_data) - placeholderslen - self.md.htmlStash.tag_data[-1 - nests][ - 'right_index'] += nests - 2 - else: - new_blocks.append( - self.md.htmlStash.store('\n\n'.join(items))) - new_blocks.append('\n') - - new_text = "\n\n".join(new_blocks) - return new_text.split("\n") - - -class ReferencePreprocessor(Preprocessor): - """ Remove reference definitions from text and store for later use. """ - - TITLE = r'[ ]*(\"(.*)\"|\'(.*)\'|\((.*)\))[ ]*' - RE = re.compile( - r'^[ ]{0,3}\[([^\]]*)\]:\s*([^ ]*)[ ]*(%s)?$' % TITLE, re.DOTALL - ) - TITLE_RE = re.compile(r'^%s$' % TITLE) - - def run(self, lines): - new_text = [] - while lines: - line = lines.pop(0) - m = self.RE.match(line) - if m: - id = m.group(1).strip().lower() - link = m.group(2).lstrip('<').rstrip('>') - t = m.group(5) or m.group(6) or m.group(7) - if not t: - # Check next line for title - tm = self.TITLE_RE.match(lines[0]) - if tm: - lines.pop(0) - t = tm.group(2) or tm.group(3) or tm.group(4) - self.md.references[id] = (link, t) - # Preserve the line to prevent raw HTML indexing issue. - # https://github.com/Python-Markdown/markdown/issues/584 - new_text.append('') - else: - new_text.append(line) - - return new_text # + "\n" + source = '\n'.join(lines) + parser = HTMLExtractor(self.md) + parser.feed(source) + parser.close() + return ''.join(parser.cleandoc).split('\n') diff --git a/venv/lib/python3.8/site-packages/markdown/test_tools.py b/venv/lib/python3.8/site-packages/markdown/test_tools.py index a42b14b..5f33619 100644 --- a/venv/lib/python3.8/site-packages/markdown/test_tools.py +++ b/venv/lib/python3.8/site-packages/markdown/test_tools.py @@ -20,9 +20,10 @@ License: BSD (see LICENSE.md for details). """ import os +import sys import unittest import textwrap -from . import markdown +from . import markdown, util try: import tidylib @@ -73,6 +74,32 @@ class TestCase(unittest.TestCase): return textwrap.dedent(text).strip() +class recursionlimit: + """ + A context manager which temporarily modifies the Python recursion limit. + + The testing framework, coverage, etc. may add an arbitrary number of levels to the depth. To maintain consistency + in the tests, the current stack depth is determined when called, then added to the provided limit. + + Example usage: + + with recursionlimit(20): + # test code here + + See https://stackoverflow.com/a/50120316/866026 + """ + + def __init__(self, limit): + self.limit = util._get_stack_depth() + limit + self.old_limit = sys.getrecursionlimit() + + def __enter__(self): + sys.setrecursionlimit(self.limit) + + def __exit__(self, type, value, tb): + sys.setrecursionlimit(self.old_limit) + + ######################### # Legacy Test Framework # ######################### @@ -113,8 +140,11 @@ class LegacyTestMeta(type): expected = f.read().replace("\r\n", "\n") output = markdown(input, **kwargs) if tidylib and normalize: - expected = _normalize_whitespace(expected) - output = _normalize_whitespace(output) + try: + expected = _normalize_whitespace(expected) + output = _normalize_whitespace(output) + except OSError: + self.skipTest("Tidylib's c library not available.") elif normalize: self.skipTest('Tidylib not available.') self.assertMultiLineEqual(output, expected) @@ -167,7 +197,7 @@ class LegacyTestCase(unittest.TestCase, metaclass=LegacyTestMeta): arguments for all test files in the directory. In addition, properties can be defined for each individual set of test files within - the directory. The property should be given the name of the file wihtout the file + the directory. The property should be given the name of the file without the file extension. Any spaces and dashes in the filename should be replaced with underscores. The value of the property should be a `Kwargs` instance which contains the keyword arguments that should be passed to `Markdown` for that diff --git a/venv/lib/python3.8/site-packages/markdown/treeprocessors.py b/venv/lib/python3.8/site-packages/markdown/treeprocessors.py index 1089010..055d8ac 100644 --- a/venv/lib/python3.8/site-packages/markdown/treeprocessors.py +++ b/venv/lib/python3.8/site-packages/markdown/treeprocessors.py @@ -369,8 +369,8 @@ class InlineProcessor(Treeprocessor): lst = self.__processPlaceholders( self.__handleInline(text), child ) - for l in lst: - self.parent_map[l[0]] = child + for item in lst: + self.parent_map[item[0]] = child stack += lst insertQueue.append((child, lst)) self.ancestors.pop() diff --git a/venv/lib/python3.8/site-packages/markdown/util.py b/venv/lib/python3.8/site-packages/markdown/util.py index e7bc295..2cb2317 100644 --- a/venv/lib/python3.8/site-packages/markdown/util.py +++ b/venv/lib/python3.8/site-packages/markdown/util.py @@ -26,7 +26,13 @@ from functools import wraps import warnings import xml.etree.ElementTree from .pep562 import Pep562 +from itertools import count +try: + from importlib import metadata +except ImportError: + # <PY38 use backport + import importlib_metadata as metadata PY37 = (3, 7) <= sys.version_info @@ -52,11 +58,12 @@ BLOCK_LEVEL_ELEMENTS = [ # See https://w3c.github.io/html/grouping-content.html#the-p-element 'address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', - 'h4', 'h5', 'h6', 'header', 'hr', 'main', 'menu', 'nav', 'ol', 'p', 'pre', - 'section', 'table', 'ul', + 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', + 'p', 'pre', 'section', 'table', 'ul', # Other elements which Markdown should not be mucking up the contents of. - 'canvas', 'dd', 'dt', 'group', 'iframe', 'li', 'math', 'noscript', 'output', - 'progress', 'script', 'style', 'tbody', 'td', 'th', 'thead', 'tr', 'video' + 'canvas', 'colgroup', 'dd', 'body', 'dt', 'group', 'iframe', 'li', 'legend', + 'math', 'map', 'noscript', 'output', 'object', 'option', 'progress', 'script', + 'style', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'tr', 'video' ] # Placeholders @@ -76,6 +83,8 @@ Constants you probably do not need to change ----------------------------------------------------------------------------- """ +# Only load extension entry_points once. +INSTALLED_EXTENSIONS = metadata.entry_points().get('markdown.extensions', ()) RTL_BIDI_RANGES = ( ('\u0590', '\u07FF'), # Hebrew (0590-05FF), Arabic (0600-06FF), @@ -149,6 +158,23 @@ def code_escape(text): return text +def _get_stack_depth(size=2): + """Get stack size for caller's frame. + See https://stackoverflow.com/a/47956089/866026 + """ + frame = sys._getframe(size) + + for size in count(size): + frame = frame.f_back + if not frame: + return size + + +def nearing_recursion_limit(): + """Return true if current stack depth is withing 100 of maximum limit.""" + return sys.getrecursionlimit() - _get_stack_depth() < 100 + + """ MISC AUXILIARY CLASSES ============================================================================= @@ -392,7 +418,7 @@ class Registry: stacklevel=2, ) else: - raise TypeError + raise KeyError('Cannot delete key {}, not registered.'.format(key)) def add(self, key, value, location): """ Register a key by location. """ diff --git a/venv/lib/python3.8/site-packages/markupsafe/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/markupsafe/__pycache__/__init__.cpython-38.pyc index 546542d516d252d18197520c4d3d93f802412acd..101bd47a7787922c9d6782697608f7e630f971c6 100644 GIT binary patch delta 94 zcmdlMdL@)6l$V!_0SJ`-?TX*Xvxn0;Qa>X<H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lATh5aT02*8(oB#j- delta 64 zcmcZ-x-FC^l$V!_0SFYzH^gn^*~6)7tzVK`pkI(#pqrUjT#}fRqZ?lmpB-PBm8$QX SSd?8_5S*Bnx|y5nqyhkvVHKSK diff --git a/venv/lib/python3.8/site-packages/markupsafe/__pycache__/_compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/markupsafe/__pycache__/_compat.cpython-38.pyc index 9f17419207eaa0dd4c02edfc7ebd5f4c3587b21b..dd4438b7b0a6cf1f652d5a270a61a306904f2915 100644 GIT binary patch delta 94 zcmaFP+RDZg%FD~e00c_^cExYx@nUq2(9g)vP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7bD&6vXo0I&-nZU6uP delta 64 zcmZo=d(O%e%FD~e00au<8{#(dcrmJ4>6hdd=oe%b=w{{>mn7!o=*E}CXUA7&rRw`8 S7G;+f1Sh7YZl1}Q!w3LRt`u$n diff --git a/venv/lib/python3.8/site-packages/markupsafe/__pycache__/_constants.cpython-38.pyc b/venv/lib/python3.8/site-packages/markupsafe/__pycache__/_constants.cpython-38.pyc index 3424c12071480b2765038aebb928439678f702fd..b46d9fc204e85cc8f1d0ce470a5e0f952d01b40a 100644 GIT binary patch delta 94 zcmeBIT&u_v%FD~e00c_^cExYxG2wHL*3Zb#P1P@|EG^B-)Gsbd)=x>y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7b@%BRHy0IyUaB>(^b delta 64 zcmZ3h*ssVF%FD~e00au<8{#(dnDD9E>X+me=oe%b=w{{>mn7!o=*E}CXUA7&rRw`8 S7G;+f1Sh7YZf@q&Vgdk9*AyiH diff --git a/venv/lib/python3.8/site-packages/markupsafe/__pycache__/_native.cpython-38.pyc b/venv/lib/python3.8/site-packages/markupsafe/__pycache__/_native.cpython-38.pyc index 9ef33fd9c2b171df02b9618df8a43e54f53ac72e..b6da6ca8e8324575b0eb2174dc277ad3cd4a2390 100644 GIT binary patch delta 94 zcmX>q@K}H+l$V!_0SJ`-?TX*Xv!2;GLO&xvH&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lA1Ljl~0PLP2i2wiq delta 64 zcmaDXa8!UNl$V!_0SFYzH^gn^S<kF$rC*X;pkI(#pqrUjT#}fRqZ?lmpB-PBm8$QX SSd?8_5S*Bny7?b-DhmL2uN8>^ diff --git a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/INSTALLER b/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/INSTALLER deleted file mode 100644 index a1b589e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/LICENSE.txt b/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/LICENSE.txt deleted file mode 100644 index 737fec5..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2008-2019 The pip developers (see AUTHORS.txt file) - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/METADATA b/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/METADATA deleted file mode 100644 index 45e28ec..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/METADATA +++ /dev/null @@ -1,81 +0,0 @@ -Metadata-Version: 2.1 -Name: pip -Version: 19.2.3 -Summary: The PyPA recommended tool for installing Python packages. -Home-page: https://pip.pypa.io/ -Author: The pip developers -Author-email: pypa-dev@groups.google.com -License: MIT -Keywords: distutils easy_install egg setuptools wheel virtualenv -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Topic :: Software Development :: Build Tools -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 :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.* - -pip - The Python Package Installer -================================== - -.. image:: https://img.shields.io/pypi/v/pip.svg - :target: https://pypi.org/project/pip/ - -.. image:: https://readthedocs.org/projects/pip/badge/?version=latest - :target: https://pip.pypa.io/en/latest - -pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes. - -Please take a look at our documentation for how to install and use pip: - -* `Installation`_ -* `Usage`_ - -Updates are released regularly, with a new version every 3 months. More details can be found in our documentation: - -* `Release notes`_ -* `Release process`_ - -If you find bugs, need help, or want to talk to the developers please use our mailing lists or chat rooms: - -* `Issue tracking`_ -* `Discourse channel`_ -* `User IRC`_ - -If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms: - -* `GitHub page`_ -* `Dev documentation`_ -* `Dev mailing list`_ -* `Dev IRC`_ - -Code of Conduct ---------------- - -Everyone interacting in the pip project's codebases, issue trackers, chat -rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_. - -.. _package installer: https://packaging.python.org/en/latest/current/ -.. _Python Package Index: https://pypi.org -.. _Installation: https://pip.pypa.io/en/stable/installing.html -.. _Usage: https://pip.pypa.io/en/stable/ -.. _Release notes: https://pip.pypa.io/en/stable/news.html -.. _Release process: https://pip.pypa.io/en/latest/development/release-process/ -.. _GitHub page: https://github.com/pypa/pip -.. _Dev documentation: https://pip.pypa.io/en/latest/development -.. _Issue tracking: https://github.com/pypa/pip/issues -.. _Discourse channel: https://discuss.python.org/c/packaging -.. _Dev mailing list: https://groups.google.com/forum/#!forum/pypa-dev -.. _User IRC: https://webchat.freenode.net/?channels=%23pypa -.. _Dev IRC: https://webchat.freenode.net/?channels=%23pypa-dev -.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ - - diff --git a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/RECORD b/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/RECORD deleted file mode 100644 index cd6ddd1..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/RECORD +++ /dev/null @@ -1,668 +0,0 @@ -../../../bin/pip,sha256=6vRKXo7lKmO-fViyaql2GzFsv7YOEt8B810uc9_oEXo,241 -../../../bin/pip3,sha256=6vRKXo7lKmO-fViyaql2GzFsv7YOEt8B810uc9_oEXo,241 -../../../bin/pip3.8,sha256=6vRKXo7lKmO-fViyaql2GzFsv7YOEt8B810uc9_oEXo,241 -pip-19.2.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pip-19.2.3.dist-info/LICENSE.txt,sha256=W6Ifuwlk-TatfRU2LR7W1JMcyMj5_y1NkRkOEJvnRDE,1090 -pip-19.2.3.dist-info/METADATA,sha256=uA6603UkWcOVSlssH5-xiouxIBqVvzVkNDCHNkzsJs4,3195 -pip-19.2.3.dist-info/RECORD,, -pip-19.2.3.dist-info/WHEEL,sha256=8zNYZbwQSXoB9IfXOjPfeNwvAsALAjffgk27FqvCWbo,110 -pip-19.2.3.dist-info/entry_points.txt,sha256=S_zfxY25QtQDVY1BiLAmOKSkkI5llzCKPLiYOSEupsY,98 -pip-19.2.3.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -pip/__init__.py,sha256=DY1edKuavmOCGCG4RY236CTl5tiT71KY6-ewGOCDIJU,23 -pip/__main__.py,sha256=L3IHqBeasELUHvwy5CT_izVEMhM12tve289qut49DvU,623 -pip/__pycache__/__init__.cpython-38.pyc,, -pip/__pycache__/__main__.cpython-38.pyc,, -pip/_internal/__init__.py,sha256=uGzk4m-m6lYf1mnYIRjjsvO35Qf6iAFatbY4oa9ifOU,2797 -pip/_internal/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/__pycache__/build_env.cpython-38.pyc,, -pip/_internal/__pycache__/cache.cpython-38.pyc,, -pip/_internal/__pycache__/configuration.cpython-38.pyc,, -pip/_internal/__pycache__/download.cpython-38.pyc,, -pip/_internal/__pycache__/exceptions.cpython-38.pyc,, -pip/_internal/__pycache__/index.cpython-38.pyc,, -pip/_internal/__pycache__/legacy_resolve.cpython-38.pyc,, -pip/_internal/__pycache__/locations.cpython-38.pyc,, -pip/_internal/__pycache__/pep425tags.cpython-38.pyc,, -pip/_internal/__pycache__/pyproject.cpython-38.pyc,, -pip/_internal/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/build_env.py,sha256=jZHTbyb4XqoaIoPaOJP2uOp1Hnmh0HfplXBgY0TBWyM,7405 -pip/_internal/cache.py,sha256=MzHv-Z0h8_n6XfBMxIatHcoiyAmzvX1zKtDGoJBWHk0,7658 -pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132 -pip/_internal/cli/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc,, -pip/_internal/cli/__pycache__/base_command.cpython-38.pyc,, -pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc,, -pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc,, -pip/_internal/cli/__pycache__/parser.cpython-38.pyc,, -pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc,, -pip/_internal/cli/autocompletion.py,sha256=ptvsMdGjq42pzoY4skABVF43u2xAtLJlXAulPi-A10Y,6083 -pip/_internal/cli/base_command.py,sha256=KF1S58E8yilcKkqPyeJKU-jqQBSxBI25b_sBoq3uEAo,13029 -pip/_internal/cli/cmdoptions.py,sha256=cILKSj3jrwpQY3Xl76erVPhxnWuAIOoeJUcVjxttyaE,27543 -pip/_internal/cli/main_parser.py,sha256=J_gG7JnoAeUhSDy2PFGqMEZLNm9oNYnuZunjVz94Lyw,2817 -pip/_internal/cli/parser.py,sha256=VZKUKJPbU6I2cHPLDOikin-aCx7OvLcZ3fzYp3xytd8,9378 -pip/_internal/cli/status_codes.py,sha256=F6uDG6Gj7RNKQJUDnd87QKqI16Us-t-B0wPF_4QMpWc,156 -pip/_internal/commands/__init__.py,sha256=KF-mqzngZMtbOxkX9M6ayyGyroCNz5xdlZEc4lItUMI,2295 -pip/_internal/commands/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/commands/__pycache__/check.cpython-38.pyc,, -pip/_internal/commands/__pycache__/completion.cpython-38.pyc,, -pip/_internal/commands/__pycache__/configuration.cpython-38.pyc,, -pip/_internal/commands/__pycache__/debug.cpython-38.pyc,, -pip/_internal/commands/__pycache__/download.cpython-38.pyc,, -pip/_internal/commands/__pycache__/freeze.cpython-38.pyc,, -pip/_internal/commands/__pycache__/hash.cpython-38.pyc,, -pip/_internal/commands/__pycache__/help.cpython-38.pyc,, -pip/_internal/commands/__pycache__/install.cpython-38.pyc,, -pip/_internal/commands/__pycache__/list.cpython-38.pyc,, -pip/_internal/commands/__pycache__/search.cpython-38.pyc,, -pip/_internal/commands/__pycache__/show.cpython-38.pyc,, -pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc,, -pip/_internal/commands/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/commands/check.py,sha256=liigNVif0iz2mBfhvsajrLZT5zM5KIvgmKvhAW91EzA,1430 -pip/_internal/commands/completion.py,sha256=hqvCvoxsIHjysiD7olHKTqK2lzE1_lS6LWn69kN5qyI,2929 -pip/_internal/commands/configuration.py,sha256=c22362Rk7dAwvHFja9py4sSaV0Sryqo_PzuadI1mm0w,8156 -pip/_internal/commands/debug.py,sha256=0NJZT3Zz9vjqUqeKdPPbr_jUZubnHYp7Cmk--zlZiPs,3360 -pip/_internal/commands/download.py,sha256=zAyNBo0zwHixos6O-S6Kd9SAH1L_74filOoR83_Fa7U,6375 -pip/_internal/commands/freeze.py,sha256=lDrob-AG-qT2DyZTNWlYa9F4BqJQTy_F9h9KakBMnG0,3441 -pip/_internal/commands/hash.py,sha256=K1JycsD-rpjqrRcL_ijacY9UKmI82pQcLYq4kCM4Pv0,1681 -pip/_internal/commands/help.py,sha256=MwBhPJpW1Dt3GfJV3V8V6kgAy_pXT0jGrZJB1wCTW-E,1090 -pip/_internal/commands/install.py,sha256=cGXbByOjrJWKIv5myy7ZflX4jYMyjT6-w85tGhnI-Nw,22646 -pip/_internal/commands/list.py,sha256=MMiJnQJCfMwA1Qf0lSru7Nzm19otm49MFmbx8y01rwA,10497 -pip/_internal/commands/search.py,sha256=R2N1-r3RaxZqX5YeNL9QaYWnILsUn4MtPKZ1ji1i1sU,4972 -pip/_internal/commands/show.py,sha256=bE-ucu8fAjTTENpRRKhwD3QSWR8Rss7YgKAbMJoxock,6273 -pip/_internal/commands/uninstall.py,sha256=h0gfPF5jylDESx_IHgF6bZME7QAEOHzQHdn65GP-jrE,2963 -pip/_internal/commands/wheel.py,sha256=G2dOwQkDCH0-x6nlf9MvbMY2GUf-pqAG5epV4fjMGM0,6977 -pip/_internal/configuration.py,sha256=dKsnJZN9r4jVsl9IcoKTU0iI9s6XZQu3FzOsqTNElk0,14076 -pip/_internal/distributions/__init__.py,sha256=ydMdQRMM1DV6BdomjeP1em-YKikg90LZ9Tg5sJRhNF4,861 -pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/distributions/__pycache__/base.cpython-38.pyc,, -pip/_internal/distributions/__pycache__/installed.cpython-38.pyc,, -pip/_internal/distributions/__pycache__/source.cpython-38.pyc,, -pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc,, -pip/_internal/distributions/base.py,sha256=Js_vmU-MKOONF_u-k5vmu3vTJnrOk3cLD_rPRB8r7-w,1000 -pip/_internal/distributions/installed.py,sha256=uwB2CPqseB8rPv0ICBCIB1LMs8yQnd8h-JZe9B9oOB0,434 -pip/_internal/distributions/source.py,sha256=L4SEZsTtqx6F3D39P7yJDgqqrnc4dGMZr3BTWgA05jg,3514 -pip/_internal/distributions/wheel.py,sha256=lWaa9l-REefNSL9E3A0zf8h2bZRLBOlTSBqHhPTYE7M,508 -pip/_internal/download.py,sha256=Zd5EtNjqJct5tOzZ5DfmiR9zaWV2UbE24omoZcNsLd4,43323 -pip/_internal/exceptions.py,sha256=_mDPdvO9EFMxUX4VEjzw3qic0PRqPH8EPOx__-MBNb4,10168 -pip/_internal/index.py,sha256=RE8HCh8MjJPgO2EhW7hww4Jr0QWFaA3GiUgxhTPs59c,56017 -pip/_internal/legacy_resolve.py,sha256=GDWmB6KtWAIcTX4gvwFrU8Xc2w4X0KBEkbW8fGU24Fk,17303 -pip/_internal/locations.py,sha256=Tv1TotkC1brrTgqG8pvLhJGvwRfiDwAlXTOdzk7hYio,5045 -pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63 -pip/_internal/models/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/models/__pycache__/candidate.cpython-38.pyc,, -pip/_internal/models/__pycache__/format_control.cpython-38.pyc,, -pip/_internal/models/__pycache__/index.cpython-38.pyc,, -pip/_internal/models/__pycache__/link.cpython-38.pyc,, -pip/_internal/models/__pycache__/search_scope.cpython-38.pyc,, -pip/_internal/models/__pycache__/selection_prefs.cpython-38.pyc,, -pip/_internal/models/__pycache__/target_python.cpython-38.pyc,, -pip/_internal/models/candidate.py,sha256=IV7B5Rj-FjQKh5Shbv8CenuNekxdpb_chrJMEID4ouU,1169 -pip/_internal/models/format_control.py,sha256=ap8Swa26ocSXBxIuCvaDBRZjxdKUFuwC-bfqXQHWtKw,2250 -pip/_internal/models/index.py,sha256=K59A8-hVhBM20Xkahr4dTwP7OjkJyEqXH11UwHFVgqM,1060 -pip/_internal/models/link.py,sha256=fj3Hg4xrPo8ucOVyJvYrq1AgJjh56D2Z8F1liDoW-TM,6553 -pip/_internal/models/search_scope.py,sha256=JxPlngW2ecVoYrF8dr2b0oYf8XrZ-yAQ1U19uEM8Lgo,3875 -pip/_internal/models/selection_prefs.py,sha256=rPeif2KKjhTPXeMoQYffjqh10oWpXhdkxRDaPT1HO8k,1908 -pip/_internal/models/target_python.py,sha256=d66ljdpZZtAAQsuOytiZ7yq6spCa8GOmz5Vf7uoVZT0,3820 -pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_internal/operations/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/operations/__pycache__/check.cpython-38.pyc,, -pip/_internal/operations/__pycache__/freeze.cpython-38.pyc,, -pip/_internal/operations/__pycache__/prepare.cpython-38.pyc,, -pip/_internal/operations/check.py,sha256=EkjtpXpOCTvt_VG0gRnlSBBj5SGWsoVYzbAMpepI8JU,5224 -pip/_internal/operations/freeze.py,sha256=rKAeXdh1HbK92Z5YtmLyil8IYkcC076lahNJMyxqbVM,9680 -pip/_internal/operations/prepare.py,sha256=z27rAvMEtlpake5OI1-SIzp-EBjjwyf8PEikO0KmJ8w,11728 -pip/_internal/pep425tags.py,sha256=e3VijBWZOCLV1_iqXuCvlCswbJ16Ug4eYhR3Vz5MAmk,13220 -pip/_internal/pyproject.py,sha256=OlCw7pSqST68hUF_eV-YVaqJ4I7z_ROJwvgra-2C_5I,6464 -pip/_internal/req/__init__.py,sha256=Y2SjAuMFsSt3dkiK8kkiQAfv8sHrjl0PAT63FKFT0tM,2364 -pip/_internal/req/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/req/__pycache__/constructors.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_file.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_install.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_set.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_tracker.cpython-38.pyc,, -pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc,, -pip/_internal/req/constructors.py,sha256=tC7fNxKrvF3gbxI2IcA6uQiXJ5sPFQvulHPQnM5Ldgg,11858 -pip/_internal/req/req_file.py,sha256=VNC-G_JYy6JmGipezb9n5hAzZ470mvesSx3DBFtfIVM,14180 -pip/_internal/req/req_install.py,sha256=i21e6wHfTko7mQGziFoXqPbdByZ9Bnrz_bC6ZIJOwl8,40296 -pip/_internal/req/req_set.py,sha256=PaDc5EswLQhxBMFbuKbJ0frZbMNKocmA8OGqIWT-9EY,7860 -pip/_internal/req/req_tracker.py,sha256=wBpDzSDSYwpUfW4K43NrEOCCp1r6stuubfLc65Y95EM,3129 -pip/_internal/req/req_uninstall.py,sha256=rVOk8BRM_L9rsUUr9lmkV6Lm9N1Os7TEIDir6tT1Q7U,23105 -pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_internal/utils/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc,, -pip/_internal/utils/__pycache__/compat.cpython-38.pyc,, -pip/_internal/utils/__pycache__/deprecation.cpython-38.pyc,, -pip/_internal/utils/__pycache__/encoding.cpython-38.pyc,, -pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc,, -pip/_internal/utils/__pycache__/glibc.cpython-38.pyc,, -pip/_internal/utils/__pycache__/hashes.cpython-38.pyc,, -pip/_internal/utils/__pycache__/logging.cpython-38.pyc,, -pip/_internal/utils/__pycache__/marker_files.cpython-38.pyc,, -pip/_internal/utils/__pycache__/misc.cpython-38.pyc,, -pip/_internal/utils/__pycache__/models.cpython-38.pyc,, -pip/_internal/utils/__pycache__/outdated.cpython-38.pyc,, -pip/_internal/utils/__pycache__/packaging.cpython-38.pyc,, -pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc,, -pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc,, -pip/_internal/utils/__pycache__/typing.cpython-38.pyc,, -pip/_internal/utils/__pycache__/ui.cpython-38.pyc,, -pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc,, -pip/_internal/utils/appdirs.py,sha256=r9i0BZLK9KcvrzI5tqlw8ehRTtSehWGERFLy7YppG3g,9398 -pip/_internal/utils/compat.py,sha256=4mi-czTysz5Ocuq-5K6BvISCii6_agyNwkBPNtKgYfM,9596 -pip/_internal/utils/deprecation.py,sha256=zcC388qvHnBLY1GalWEYnHyh3MXHQRe4-fOoyyZeQNQ,3209 -pip/_internal/utils/encoding.py,sha256=tudXCoAPe9fZvNK4cmWQs2frREZ-QuGCwF_SlTyz6cI,1218 -pip/_internal/utils/filesystem.py,sha256=ojaIDvOFOtkpKme5se6X2N8ARmQxu8cxvaaI-NFqVtk,990 -pip/_internal/utils/glibc.py,sha256=di3treHUThyeXCxqgRgp-72nTizWpC8skE7RLbewKv4,4295 -pip/_internal/utils/hashes.py,sha256=lF1VlTk2hOqnbmbiMN6GxJHTNQEDI9RzkBCUqBgSHok,3904 -pip/_internal/utils/logging.py,sha256=k-7sr-yFTLDCgcrmrErlwBp2dYMhq157vT3P-xzrB0U,12883 -pip/_internal/utils/marker_files.py,sha256=B-xFm0JZnrDStnA1jbQgKfDaMdXn53PqpZhtOJ-FWCc,595 -pip/_internal/utils/misc.py,sha256=3tmhB5Zojxswgg1zGdPgAdGvu2sYU6g0BLiAbc2vhZY,38796 -pip/_internal/utils/models.py,sha256=b7vdfIZrobxERktz8xZ7BqYnFLxoJzkWSeuq0JO9JYI,1041 -pip/_internal/utils/outdated.py,sha256=C7TK-XuCmBQ5DUpHBzq2jL-1p7DQft84foQziUyX2Ms,6292 -pip/_internal/utils/packaging.py,sha256=VtiwcAAL7LBi7tGL2je7LeW4bE11KMHGCsJ1NZY5XtM,3035 -pip/_internal/utils/setuptools_build.py,sha256=Jjf0MRzSG60UvDnWwWixg1rWM5dEuQ5sE8kb-5KwYFI,1239 -pip/_internal/utils/temp_dir.py,sha256=0Xq5ZlOd2OOeHwKM6hGy66gnMGAbyhio7DtjLHd7DFg,5339 -pip/_internal/utils/typing.py,sha256=bF73ImJzIaxLLEVwfEaSJzFGqV9LaxkQBvDULIyr1jI,1125 -pip/_internal/utils/ui.py,sha256=I2F3wRhWE9aere-cpCE0g9VPvgJRRLL8OC3FxXdj6_k,13768 -pip/_internal/utils/virtualenv.py,sha256=oSTrUMQUqmuXcDvQZGwV65w-hlvhBAqyQiWRxLf8fN0,891 -pip/_internal/vcs/__init__.py,sha256=9p9dzJZy7PR6TkHhqr-DnJTFIo6JopLgtHjHNrt85h4,597 -pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/git.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc,, -pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc,, -pip/_internal/vcs/bazaar.py,sha256=wI5WdFt_Mmnqcm0c7zn5wM3R44s7s28DNx5Yg7CJlSw,3182 -pip/_internal/vcs/git.py,sha256=pgTaCyWNBBfz6d0AxVnsLhft2i4XRe_hSTI_Xs7nkZg,12814 -pip/_internal/vcs/mercurial.py,sha256=YzJx76Q4Nveqf8s80g-AocnfpKwCoVeHy77c95aTBO4,3335 -pip/_internal/vcs/subversion.py,sha256=RuQJeToLicFp2itahUftlHKjyvDFWuCWuhHfdsP9oGs,11697 -pip/_internal/vcs/versioncontrol.py,sha256=NifBlL90ovO8WNzlt4r6HGlGbPqxNI5fUMfwLC-gMkE,19010 -pip/_internal/wheel.py,sha256=H3bdufsutvlXcLV0t3prIOTvq9m_Uc0JkLDoISZelD8,42309 -pip/_vendor/__init__.py,sha256=iip2nWwH_riYqnDnM0q4BJFrWE-XWjYfxCejJKct0WM,4654 -pip/_vendor/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/__pycache__/appdirs.cpython-38.pyc,, -pip/_vendor/__pycache__/distro.cpython-38.pyc,, -pip/_vendor/__pycache__/ipaddress.cpython-38.pyc,, -pip/_vendor/__pycache__/pyparsing.cpython-38.pyc,, -pip/_vendor/__pycache__/retrying.cpython-38.pyc,, -pip/_vendor/__pycache__/six.cpython-38.pyc,, -pip/_vendor/appdirs.py,sha256=BENKsvcA08IpccD9345-rMrg3aXWFA1q6BFEglnHg6I,24547 -pip/_vendor/cachecontrol/__init__.py,sha256=6cRPchVqkAkeUtYTSW8qCetjSqJo-GxP-n4VMVDbvmc,302 -pip/_vendor/cachecontrol/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-38.pyc,, -pip/_vendor/cachecontrol/__pycache__/adapter.cpython-38.pyc,, -pip/_vendor/cachecontrol/__pycache__/cache.cpython-38.pyc,, -pip/_vendor/cachecontrol/__pycache__/compat.cpython-38.pyc,, -pip/_vendor/cachecontrol/__pycache__/controller.cpython-38.pyc,, -pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-38.pyc,, -pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-38.pyc,, -pip/_vendor/cachecontrol/__pycache__/serialize.cpython-38.pyc,, -pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-38.pyc,, -pip/_vendor/cachecontrol/_cmd.py,sha256=URGE0KrA87QekCG3SGPatlSPT571dZTDjNa-ZXX3pDc,1295 -pip/_vendor/cachecontrol/adapter.py,sha256=eBGAtVNRZgtl_Kj5JV54miqL9YND-D0JZPahwY8kFtY,4863 -pip/_vendor/cachecontrol/cache.py,sha256=1fc4wJP8HYt1ycnJXeEw5pCpeBL2Cqxx6g9Fb0AYDWQ,805 -pip/_vendor/cachecontrol/caches/__init__.py,sha256=-gHNKYvaeD0kOk5M74eOrsSgIKUtC6i6GfbmugGweEo,86 -pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-38.pyc,, -pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-38.pyc,, -pip/_vendor/cachecontrol/caches/file_cache.py,sha256=8vrSzzGcdfEfICago1uSFbkumNJMGLbCdEkXsmUIExw,4177 -pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=HxelMpNCo-dYr2fiJDwM3hhhRmxUYtB5tXm1GpAAT4Y,856 -pip/_vendor/cachecontrol/compat.py,sha256=kHNvMRdt6s_Xwqq_9qJmr9ou3wYMOMUMxPPcwNxT8Mc,695 -pip/_vendor/cachecontrol/controller.py,sha256=U7g-YwizQ2O5NRgK_MZreF1ntM4E49C3PuF3od-Vwz4,13698 -pip/_vendor/cachecontrol/filewrapper.py,sha256=vACKO8Llzu_ZWyjV1Fxn1MA4TGU60N5N3GSrAFdAY2Q,2533 -pip/_vendor/cachecontrol/heuristics.py,sha256=BFGHJ3yQcxvZizfo90LLZ04T_Z5XSCXvFotrp7Us0sc,4070 -pip/_vendor/cachecontrol/serialize.py,sha256=GebE34fgToyWwAsRPguh8hEPN6CqoG-5hRMXRsjVABQ,6954 -pip/_vendor/cachecontrol/wrapper.py,sha256=sfr9YHWx-5TwNz1H5rT6QOo8ggII6v3vbEDjQFwR6wc,671 -pip/_vendor/certifi/__init__.py,sha256=phsMyKTQP7MMe1wAHfhXPbQVxL3wXixOomxzNh5Cwa4,52 -pip/_vendor/certifi/__main__.py,sha256=NaCn6WtWME-zzVWQ2j4zFyl8cY4knDa9CwtHNIeFPhM,53 -pip/_vendor/certifi/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/certifi/__pycache__/__main__.cpython-38.pyc,, -pip/_vendor/certifi/__pycache__/core.cpython-38.pyc,, -pip/_vendor/certifi/cacert.pem,sha256=DddOv7pQyMB8zNNgiXSSFrPVn7EN8qbe7P6h_IYyuek,282085 -pip/_vendor/certifi/core.py,sha256=EuFc2BsToG5O1-qsx4BSjQ1r1-7WRtH87b1WflZOWhI,218 -pip/_vendor/chardet/__init__.py,sha256=YsP5wQlsHJ2auF1RZJfypiSrCA7_bQiRm3ES_NI76-Y,1559 -pip/_vendor/chardet/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/big5freq.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/big5prober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/chardistribution.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/charsetprober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/compat.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/cp949prober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/enums.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/escprober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/escsm.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/eucjpprober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/euckrfreq.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/euckrprober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/euctwfreq.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/euctwprober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/gb2312freq.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/gb2312prober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/hebrewprober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/jisfreq.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/jpcntx.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/langthaimodel.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/latin1prober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/mbcssm.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/sjisprober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/universaldetector.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/utf8prober.cpython-38.pyc,, -pip/_vendor/chardet/__pycache__/version.cpython-38.pyc,, -pip/_vendor/chardet/big5freq.py,sha256=D_zK5GyzoVsRes0HkLJziltFQX0bKCLOrFe9_xDvO_8,31254 -pip/_vendor/chardet/big5prober.py,sha256=kBxHbdetBpPe7xrlb-e990iot64g_eGSLd32lB7_h3M,1757 -pip/_vendor/chardet/chardistribution.py,sha256=3woWS62KrGooKyqz4zQSnjFbJpa6V7g02daAibTwcl8,9411 -pip/_vendor/chardet/charsetgroupprober.py,sha256=6bDu8YIiRuScX4ca9Igb0U69TA2PGXXDej6Cc4_9kO4,3787 -pip/_vendor/chardet/charsetprober.py,sha256=KSmwJErjypyj0bRZmC5F5eM7c8YQgLYIjZXintZNstg,5110 -pip/_vendor/chardet/cli/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 -pip/_vendor/chardet/cli/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-38.pyc,, -pip/_vendor/chardet/cli/chardetect.py,sha256=DI8dlV3FBD0c0XA_y3sQ78z754DUv1J8n34RtDjOXNw,2774 -pip/_vendor/chardet/codingstatemachine.py,sha256=VYp_6cyyki5sHgXDSZnXW4q1oelHc3cu9AyQTX7uug8,3590 -pip/_vendor/chardet/compat.py,sha256=PKTzHkSbtbHDqS9PyujMbX74q1a8mMpeQTDVsQhZMRw,1134 -pip/_vendor/chardet/cp949prober.py,sha256=TZ434QX8zzBsnUvL_8wm4AQVTZ2ZkqEEQL_lNw9f9ow,1855 -pip/_vendor/chardet/enums.py,sha256=Aimwdb9as1dJKZaFNUH2OhWIVBVd6ZkJJ_WK5sNY8cU,1661 -pip/_vendor/chardet/escprober.py,sha256=kkyqVg1Yw3DIOAMJ2bdlyQgUFQhuHAW8dUGskToNWSc,3950 -pip/_vendor/chardet/escsm.py,sha256=RuXlgNvTIDarndvllNCk5WZBIpdCxQ0kcd9EAuxUh84,10510 -pip/_vendor/chardet/eucjpprober.py,sha256=iD8Jdp0ISRjgjiVN7f0e8xGeQJ5GM2oeZ1dA8nbSeUw,3749 -pip/_vendor/chardet/euckrfreq.py,sha256=-7GdmvgWez4-eO4SuXpa7tBiDi5vRXQ8WvdFAzVaSfo,13546 -pip/_vendor/chardet/euckrprober.py,sha256=MqFMTQXxW4HbzIpZ9lKDHB3GN8SP4yiHenTmf8g_PxY,1748 -pip/_vendor/chardet/euctwfreq.py,sha256=No1WyduFOgB5VITUA7PLyC5oJRNzRyMbBxaKI1l16MA,31621 -pip/_vendor/chardet/euctwprober.py,sha256=13p6EP4yRaxqnP4iHtxHOJ6R2zxHq1_m8hTRjzVZ95c,1747 -pip/_vendor/chardet/gb2312freq.py,sha256=JX8lsweKLmnCwmk8UHEQsLgkr_rP_kEbvivC4qPOrlc,20715 -pip/_vendor/chardet/gb2312prober.py,sha256=gGvIWi9WhDjE-xQXHvNIyrnLvEbMAYgyUSZ65HUfylw,1754 -pip/_vendor/chardet/hebrewprober.py,sha256=c3SZ-K7hvyzGY6JRAZxJgwJ_sUS9k0WYkvMY00YBYFo,13838 -pip/_vendor/chardet/jisfreq.py,sha256=vpmJv2Bu0J8gnMVRPHMFefTRvo_ha1mryLig8CBwgOg,25777 -pip/_vendor/chardet/jpcntx.py,sha256=PYlNqRUQT8LM3cT5FmHGP0iiscFlTWED92MALvBungo,19643 -pip/_vendor/chardet/langbulgarianmodel.py,sha256=1HqQS9Pbtnj1xQgxitJMvw8X6kKr5OockNCZWfEQrPE,12839 -pip/_vendor/chardet/langcyrillicmodel.py,sha256=LODajvsetH87yYDDQKA2CULXUH87tI223dhfjh9Zx9c,17948 -pip/_vendor/chardet/langgreekmodel.py,sha256=8YAW7bU8YwSJap0kIJSbPMw1BEqzGjWzqcqf0WgUKAA,12688 -pip/_vendor/chardet/langhebrewmodel.py,sha256=JSnqmE5E62tDLTPTvLpQsg5gOMO4PbdWRvV7Avkc0HA,11345 -pip/_vendor/chardet/langhungarianmodel.py,sha256=RhapYSG5l0ZaO-VV4Fan5sW0WRGQqhwBM61yx3yxyOA,12592 -pip/_vendor/chardet/langthaimodel.py,sha256=8l0173Gu_W6G8mxmQOTEF4ls2YdE7FxWf3QkSxEGXJQ,11290 -pip/_vendor/chardet/langturkishmodel.py,sha256=W22eRNJsqI6uWAfwXSKVWWnCerYqrI8dZQTm_M0lRFk,11102 -pip/_vendor/chardet/latin1prober.py,sha256=S2IoORhFk39FEFOlSFWtgVybRiP6h7BlLldHVclNkU8,5370 -pip/_vendor/chardet/mbcharsetprober.py,sha256=AR95eFH9vuqSfvLQZN-L5ijea25NOBCoXqw8s5O9xLQ,3413 -pip/_vendor/chardet/mbcsgroupprober.py,sha256=h6TRnnYq2OxG1WdD5JOyxcdVpn7dG0q-vB8nWr5mbh4,2012 -pip/_vendor/chardet/mbcssm.py,sha256=SY32wVIF3HzcjY3BaEspy9metbNSKxIIB0RKPn7tjpI,25481 -pip/_vendor/chardet/sbcharsetprober.py,sha256=LDSpCldDCFlYwUkGkwD2oFxLlPWIWXT09akH_2PiY74,5657 -pip/_vendor/chardet/sbcsgroupprober.py,sha256=1IprcCB_k1qfmnxGC6MBbxELlKqD3scW6S8YIwdeyXA,3546 -pip/_vendor/chardet/sjisprober.py,sha256=IIt-lZj0WJqK4rmUZzKZP4GJlE8KUEtFYVuY96ek5MQ,3774 -pip/_vendor/chardet/universaldetector.py,sha256=qL0174lSZE442eB21nnktT9_VcAye07laFWUeUrjttY,12485 -pip/_vendor/chardet/utf8prober.py,sha256=IdD8v3zWOsB8OLiyPi-y_fqwipRFxV9Nc1eKBLSuIEw,2766 -pip/_vendor/chardet/version.py,sha256=sp3B08mrDXB-pf3K9fqJ_zeDHOCLC8RrngQyDFap_7g,242 -pip/_vendor/colorama/__init__.py,sha256=lJdY6COz9uM_pXwuk9oLr0fp8H8q2RrUqN16GKabvq4,239 -pip/_vendor/colorama/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/colorama/__pycache__/ansi.cpython-38.pyc,, -pip/_vendor/colorama/__pycache__/ansitowin32.cpython-38.pyc,, -pip/_vendor/colorama/__pycache__/initialise.cpython-38.pyc,, -pip/_vendor/colorama/__pycache__/win32.cpython-38.pyc,, -pip/_vendor/colorama/__pycache__/winterm.cpython-38.pyc,, -pip/_vendor/colorama/ansi.py,sha256=Fi0un-QLqRm-v7o_nKiOqyC8PapBJK7DLV_q9LKtTO0,2524 -pip/_vendor/colorama/ansitowin32.py,sha256=u8QaqdqS_xYSfNkPM1eRJLHz6JMWPodaJaP0mxgHCDc,10462 -pip/_vendor/colorama/initialise.py,sha256=PprovDNxMTrvoNHFcL2NZjpH2XzDc8BLxLxiErfUl4k,1915 -pip/_vendor/colorama/win32.py,sha256=bJ8Il9jwaBN5BJ8bmN6FoYZ1QYuMKv2j8fGrXh7TJjw,5404 -pip/_vendor/colorama/winterm.py,sha256=2y_2b7Zsv34feAsP67mLOVc-Bgq51mdYGo571VprlrM,6438 -pip/_vendor/distlib/__init__.py,sha256=SkHYPuEQNQF2a2Cr18rfZ-LQyDqwwizn8tJE4seXPgU,587 -pip/_vendor/distlib/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/distlib/__pycache__/compat.cpython-38.pyc,, -pip/_vendor/distlib/__pycache__/database.cpython-38.pyc,, -pip/_vendor/distlib/__pycache__/index.cpython-38.pyc,, -pip/_vendor/distlib/__pycache__/locators.cpython-38.pyc,, -pip/_vendor/distlib/__pycache__/manifest.cpython-38.pyc,, -pip/_vendor/distlib/__pycache__/markers.cpython-38.pyc,, -pip/_vendor/distlib/__pycache__/metadata.cpython-38.pyc,, -pip/_vendor/distlib/__pycache__/resources.cpython-38.pyc,, -pip/_vendor/distlib/__pycache__/scripts.cpython-38.pyc,, -pip/_vendor/distlib/__pycache__/util.cpython-38.pyc,, -pip/_vendor/distlib/__pycache__/version.cpython-38.pyc,, -pip/_vendor/distlib/__pycache__/wheel.cpython-38.pyc,, -pip/_vendor/distlib/_backport/__init__.py,sha256=bqS_dTOH6uW9iGgd0uzfpPjo6vZ4xpPZ7kyfZJ2vNaw,274 -pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/distlib/_backport/__pycache__/misc.cpython-38.pyc,, -pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-38.pyc,, -pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-38.pyc,, -pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-38.pyc,, -pip/_vendor/distlib/_backport/misc.py,sha256=KWecINdbFNOxSOP1fGF680CJnaC6S4fBRgEtaYTw0ig,971 -pip/_vendor/distlib/_backport/shutil.py,sha256=VW1t3uYqUjWZH7jV-6QiimLhnldoV5uIpH4EuiT1jfw,25647 -pip/_vendor/distlib/_backport/sysconfig.cfg,sha256=swZKxq9RY5e9r3PXCrlvQPMsvOdiWZBTHLEbqS8LJLU,2617 -pip/_vendor/distlib/_backport/sysconfig.py,sha256=JdJ9ztRy4Hc-b5-VS74x3nUtdEIVr_OBvMsIb8O2sjc,26964 -pip/_vendor/distlib/_backport/tarfile.py,sha256=Ihp7rXRcjbIKw8COm9wSePV9ARGXbSF9gGXAMn2Q-KU,92628 -pip/_vendor/distlib/compat.py,sha256=xdNZmqFN5HwF30HjRn5M415pcC2kgXRBXn767xS8v-M,41404 -pip/_vendor/distlib/database.py,sha256=-KJH63AJ7hqjLtGCwOTrionhKr2Vsytdwkjyo8UdEco,51029 -pip/_vendor/distlib/index.py,sha256=SXKzpQCERctxYDMp_OLee2f0J0e19ZhGdCIoMlUfUQM,21066 -pip/_vendor/distlib/locators.py,sha256=bqzEWP3Ad8UE3D1rmzW1pgzVTKkY4rDUA_EWIVYli54,51807 -pip/_vendor/distlib/manifest.py,sha256=nQEhYmgoreaBZzyFzwYsXxJARu3fo4EkunU163U16iE,14811 -pip/_vendor/distlib/markers.py,sha256=6Ac3cCfFBERexiESWIOXmg-apIP8l2esafNSX3KMy-8,4387 -pip/_vendor/distlib/metadata.py,sha256=OhbCKmf5lswE8unWBopI1hj7tRpHp4ZbFvU4d6aAEMM,40234 -pip/_vendor/distlib/resources.py,sha256=2FGv0ZHF14KXjLIlL0R991lyQQGcewOS4mJ-5n-JVnc,10766 -pip/_vendor/distlib/scripts.py,sha256=W24OXnZUmgRX_XtDrVZdfc-Frf4X4_cybvhP87iR-QU,16290 -pip/_vendor/distlib/t32.exe,sha256=y8Yu3yao6zZrELYGIisxkhnQLOAOvpiXft8_Y9I8vyU,92672 -pip/_vendor/distlib/t64.exe,sha256=qt1MpKO2NLqU8t1lD1T0frfFm5zwHm3mz7pLvmJ2kMI,102912 -pip/_vendor/distlib/util.py,sha256=TvdqcwncBHaQbNw0jkXRvSZvt1fbdgE8HQW5wJwzvv4,59790 -pip/_vendor/distlib/version.py,sha256=_n7F6juvQGAcn769E_SHa7fOcf5ERlEVymJ_EjPRwGw,23391 -pip/_vendor/distlib/w32.exe,sha256=f98Etq_1giFgIQxrEh-sOAeO8qVtWqpDbGxdUucJ6pw,89088 -pip/_vendor/distlib/w64.exe,sha256=6Hs-Wn0vXBHA6Qd76IlalqYXqrN80DCPpdoeIQzPRms,99840 -pip/_vendor/distlib/wheel.py,sha256=2lviV6L4IvTP5DRkKE0HGpClvdoTJQHZJLfTQ6dfn2A,40437 -pip/_vendor/distro.py,sha256=X2So5kjrRKyMbQJ90Xgy93HU5eFtujCzKaYNeoy1k1c,43251 -pip/_vendor/html5lib/__init__.py,sha256=Ztrn7UvF-wIFAgRBBa0ML-Gu5AffH3BPX_INJx4SaBI,1162 -pip/_vendor/html5lib/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-38.pyc,, -pip/_vendor/html5lib/__pycache__/_inputstream.cpython-38.pyc,, -pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-38.pyc,, -pip/_vendor/html5lib/__pycache__/_utils.cpython-38.pyc,, -pip/_vendor/html5lib/__pycache__/constants.cpython-38.pyc,, -pip/_vendor/html5lib/__pycache__/html5parser.cpython-38.pyc,, -pip/_vendor/html5lib/__pycache__/serializer.cpython-38.pyc,, -pip/_vendor/html5lib/_ihatexml.py,sha256=3LBtJMlzgwM8vpQiU1TvGmEEmNH72sV0yD8yS53y07A,16705 -pip/_vendor/html5lib/_inputstream.py,sha256=bPUWcAfJScK4xkjQQaG_HsI2BvEVbFvI0AsodDYPQj0,32552 -pip/_vendor/html5lib/_tokenizer.py,sha256=YAaOEBD6qc5ISq9Xt9Nif1OFgcybTTfMdwqBkZhpAq4,76580 -pip/_vendor/html5lib/_trie/__init__.py,sha256=8VR1bcgD2OpeS2XExpu5yBhP_Q1K-lwKbBKICBPf1kU,289 -pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-38.pyc,, -pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-38.pyc,, -pip/_vendor/html5lib/_trie/__pycache__/py.cpython-38.pyc,, -pip/_vendor/html5lib/_trie/_base.py,sha256=CaybYyMro8uERQYjby2tTeSUatnWDfWroUN9N7ety5w,1013 -pip/_vendor/html5lib/_trie/datrie.py,sha256=EQpqSfkZRuTbE-DuhW7xMdVDxdZNZ0CfmnYfHA_3zxM,1178 -pip/_vendor/html5lib/_trie/py.py,sha256=wXmQLrZRf4MyWNyg0m3h81m9InhLR7GJ002mIIZh-8o,1775 -pip/_vendor/html5lib/_utils.py,sha256=ismpASeqa2jqEPQjHUj8vReAf7yIoKnvLN5fuOw6nv0,4015 -pip/_vendor/html5lib/constants.py,sha256=4lmZWLtEPRLnl8NzftOoYTJdo6jpeMtP6dqQC0g_bWQ,83518 -pip/_vendor/html5lib/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-38.pyc,, -pip/_vendor/html5lib/filters/__pycache__/base.cpython-38.pyc,, -pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-38.pyc,, -pip/_vendor/html5lib/filters/__pycache__/lint.cpython-38.pyc,, -pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-38.pyc,, -pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-38.pyc,, -pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-38.pyc,, -pip/_vendor/html5lib/filters/alphabeticalattributes.py,sha256=lViZc2JMCclXi_5gduvmdzrRxtO5Xo9ONnbHBVCsykU,919 -pip/_vendor/html5lib/filters/base.py,sha256=z-IU9ZAYjpsVsqmVt7kuWC63jR11hDMr6CVrvuao8W0,286 -pip/_vendor/html5lib/filters/inject_meta_charset.py,sha256=egDXUEHXmAG9504xz0K6ALDgYkvUrC2q15YUVeNlVQg,2945 -pip/_vendor/html5lib/filters/lint.py,sha256=jk6q56xY0ojiYfvpdP-OZSm9eTqcAdRqhCoPItemPYA,3643 -pip/_vendor/html5lib/filters/optionaltags.py,sha256=8lWT75J0aBOHmPgfmqTHSfPpPMp01T84NKu0CRedxcE,10588 -pip/_vendor/html5lib/filters/sanitizer.py,sha256=4ON02KNjuqda1lCw5_JCUZxb0BzWR5M7ON84dtJ7dm0,26248 -pip/_vendor/html5lib/filters/whitespace.py,sha256=8eWqZxd4UC4zlFGW6iyY6f-2uuT8pOCSALc3IZt7_t4,1214 -pip/_vendor/html5lib/html5parser.py,sha256=g5g2ezkusHxhi7b23vK_-d6K6BfIJRbqIQmvQ9z4EgI,118963 -pip/_vendor/html5lib/serializer.py,sha256=yfcfBHse2wDs6ojxn-kieJjLT5s1ipilQJ0gL3-rJis,15758 -pip/_vendor/html5lib/treeadapters/__init__.py,sha256=A0rY5gXIe4bJOiSGRO_j_tFhngRBO8QZPzPtPw5dFzo,679 -pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-38.pyc,, -pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-38.pyc,, -pip/_vendor/html5lib/treeadapters/genshi.py,sha256=CH27pAsDKmu4ZGkAUrwty7u0KauGLCZRLPMzaO3M5vo,1715 -pip/_vendor/html5lib/treeadapters/sax.py,sha256=BKS8woQTnKiqeffHsxChUqL4q2ZR_wb5fc9MJ3zQC8s,1776 -pip/_vendor/html5lib/treebuilders/__init__.py,sha256=AysSJyvPfikCMMsTVvaxwkgDieELD5dfR8FJIAuq7hY,3592 -pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-38.pyc,, -pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-38.pyc,, -pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-38.pyc,, -pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-38.pyc,, -pip/_vendor/html5lib/treebuilders/base.py,sha256=wQGp5yy22TNG8tJ6aREe4UUeTR7A99dEz0BXVaedWb4,14579 -pip/_vendor/html5lib/treebuilders/dom.py,sha256=22whb0C71zXIsai5mamg6qzBEiigcBIvaDy4Asw3at0,8925 -pip/_vendor/html5lib/treebuilders/etree.py,sha256=aqIBOGj_dFYqBURIcTegGNBhAIJOw5iFDHb4jrkYH-8,12764 -pip/_vendor/html5lib/treebuilders/etree_lxml.py,sha256=9V0dXxbJYYq-Skgb5-_OL2NkVYpjioEb4CHajo0e9yI,14122 -pip/_vendor/html5lib/treewalkers/__init__.py,sha256=yhXxHpjlSqfQyUag3v8-vWjMPriFBU8YRAPNpDgBTn8,5714 -pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-38.pyc,, -pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-38.pyc,, -pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-38.pyc,, -pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-38.pyc,, -pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-38.pyc,, -pip/_vendor/html5lib/treewalkers/base.py,sha256=ouiOsuSzvI0KgzdWP8PlxIaSNs9falhbiinAEc_UIJY,7476 -pip/_vendor/html5lib/treewalkers/dom.py,sha256=EHyFR8D8lYNnyDU9lx_IKigVJRyecUGua0mOi7HBukc,1413 -pip/_vendor/html5lib/treewalkers/etree.py,sha256=sz1o6mmE93NQ53qJFDO7HKyDtuwgK-Ay3qSFZPC6u00,4550 -pip/_vendor/html5lib/treewalkers/etree_lxml.py,sha256=sY6wfRshWTllu6n48TPWpKsQRPp-0CQrT0hj_AdzHSU,6309 -pip/_vendor/html5lib/treewalkers/genshi.py,sha256=4D2PECZ5n3ZN3qu3jMl9yY7B81jnQApBQSVlfaIuYbA,2309 -pip/_vendor/idna/__init__.py,sha256=9Nt7xpyet3DmOrPUGooDdAwmHZZu1qUAy2EaJ93kGiQ,58 -pip/_vendor/idna/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/idna/__pycache__/codec.cpython-38.pyc,, -pip/_vendor/idna/__pycache__/compat.cpython-38.pyc,, -pip/_vendor/idna/__pycache__/core.cpython-38.pyc,, -pip/_vendor/idna/__pycache__/idnadata.cpython-38.pyc,, -pip/_vendor/idna/__pycache__/intranges.cpython-38.pyc,, -pip/_vendor/idna/__pycache__/package_data.cpython-38.pyc,, -pip/_vendor/idna/__pycache__/uts46data.cpython-38.pyc,, -pip/_vendor/idna/codec.py,sha256=lvYb7yu7PhAqFaAIAdWcwgaWI2UmgseUua-1c0AsG0A,3299 -pip/_vendor/idna/compat.py,sha256=R-h29D-6mrnJzbXxymrWUW7iZUvy-26TQwZ0ij57i4U,232 -pip/_vendor/idna/core.py,sha256=JDCZZ_PLESqIgEbU8mPyoEufWwoOiIqygA17-QZIe3s,11733 -pip/_vendor/idna/idnadata.py,sha256=HXaPFw6_YAJ0qppACPu0YLAULtRs3QovRM_CCZHGdY0,40899 -pip/_vendor/idna/intranges.py,sha256=TY1lpxZIQWEP6tNqjZkFA5hgoMWOj1OBmnUG8ihT87E,1749 -pip/_vendor/idna/package_data.py,sha256=kIzeKKXEouXLR4srqwf9Q3zv-NffKSOz5aSDOJARPB0,21 -pip/_vendor/idna/uts46data.py,sha256=oLyNZ1pBaiBlj9zFzLFRd_P7J8MkRcgDisjExZR_4MY,198292 -pip/_vendor/ipaddress.py,sha256=2OgbkeAD2rLkcXqbcvof3J5R7lRwjNLoBySyTkBtKnc,79852 -pip/_vendor/lockfile/__init__.py,sha256=Tqpz90DwKYfhPsfzVOJl84TL87pdFE5ePNHdXAxs4Tk,9371 -pip/_vendor/lockfile/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/lockfile/__pycache__/linklockfile.cpython-38.pyc,, -pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-38.pyc,, -pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-38.pyc,, -pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-38.pyc,, -pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-38.pyc,, -pip/_vendor/lockfile/linklockfile.py,sha256=C7OH3H4GdK68u4FQgp8fkP2kO4fyUTSyj3X6blgfobc,2652 -pip/_vendor/lockfile/mkdirlockfile.py,sha256=e3qgIL-etZMLsS-3ft19iW_8IQ360HNkGOqE3yBKsUw,3096 -pip/_vendor/lockfile/pidlockfile.py,sha256=ukH9uk6NFuxyVmG5QiWw4iKq3fT7MjqUguX95avYPIY,6090 -pip/_vendor/lockfile/sqlitelockfile.py,sha256=o2TMkMRY0iwn-iL1XMRRIFStMUkS4i3ajceeYNntKFg,5506 -pip/_vendor/lockfile/symlinklockfile.py,sha256=ABwXXmvTHvCl5viPblShL3PG-gGsLiT1roAMfDRwhi8,2616 -pip/_vendor/msgpack/__init__.py,sha256=TF3o2_Ao3xbsvpOlmVZdthtsb7TkMW9seSJkXlW0dHE,1630 -pip/_vendor/msgpack/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/msgpack/__pycache__/_version.cpython-38.pyc,, -pip/_vendor/msgpack/__pycache__/exceptions.cpython-38.pyc,, -pip/_vendor/msgpack/__pycache__/fallback.cpython-38.pyc,, -pip/_vendor/msgpack/_version.py,sha256=ldul7tIj_IHxvYxbEiEX1QhElrhQsA2ikYSM987iw1U,20 -pip/_vendor/msgpack/exceptions.py,sha256=dCTWei8dpkrMsQDcjQk74ATl9HsIBH0ybt8zOPNqMYc,1081 -pip/_vendor/msgpack/fallback.py,sha256=-FKXOBCF4CUs9QEOqAlssI-IZA0jBRa27VieFCngMC4,37491 -pip/_vendor/packaging/__about__.py,sha256=Wg0-hNgTU2_lBZcGBh5pm1R9yroQ3rv-X0rig8KjA6o,744 -pip/_vendor/packaging/__init__.py,sha256=6enbp5XgRfjBjsI9-bn00HjHf5TH21PDMOKkJW8xw-w,562 -pip/_vendor/packaging/__pycache__/__about__.cpython-38.pyc,, -pip/_vendor/packaging/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/packaging/__pycache__/_compat.cpython-38.pyc,, -pip/_vendor/packaging/__pycache__/_structures.cpython-38.pyc,, -pip/_vendor/packaging/__pycache__/markers.cpython-38.pyc,, -pip/_vendor/packaging/__pycache__/requirements.cpython-38.pyc,, -pip/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc,, -pip/_vendor/packaging/__pycache__/utils.cpython-38.pyc,, -pip/_vendor/packaging/__pycache__/version.cpython-38.pyc,, -pip/_vendor/packaging/_compat.py,sha256=Ugdm-qcneSchW25JrtMIKgUxfEEBcCAz6WrEeXeqz9o,865 -pip/_vendor/packaging/_structures.py,sha256=pVd90XcXRGwpZRB_qdFuVEibhCHpX_bL5zYr9-N0mc8,1416 -pip/_vendor/packaging/markers.py,sha256=-QjvJkhSJBxBogO9J_EpPQudHaaLV3rgVYsBDqn-ZLc,8234 -pip/_vendor/packaging/requirements.py,sha256=grcnFU8x7KD230JaFLXtWl3VClLuOmsOy4c-m55tOWs,4700 -pip/_vendor/packaging/specifiers.py,sha256=0ZzQpcUnvrQ6LjR-mQRLzMr8G6hdRv-mY0VSf_amFtI,27778 -pip/_vendor/packaging/utils.py,sha256=VaTC0Ei7zO2xl9ARiWmz2YFLFt89PuuhLbAlXMyAGms,1520 -pip/_vendor/packaging/version.py,sha256=Npdwnb8OHedj_2L86yiUqscujb7w_i5gmSK1PhOAFzg,11978 -pip/_vendor/pep517/__init__.py,sha256=nOY747zTld3oTdEetBG6DWxEcZXTeOQk0aHvbR-sa5w,84 -pip/_vendor/pep517/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/pep517/__pycache__/_in_process.cpython-38.pyc,, -pip/_vendor/pep517/__pycache__/build.cpython-38.pyc,, -pip/_vendor/pep517/__pycache__/check.cpython-38.pyc,, -pip/_vendor/pep517/__pycache__/colorlog.cpython-38.pyc,, -pip/_vendor/pep517/__pycache__/compat.cpython-38.pyc,, -pip/_vendor/pep517/__pycache__/envbuild.cpython-38.pyc,, -pip/_vendor/pep517/__pycache__/wrappers.cpython-38.pyc,, -pip/_vendor/pep517/_in_process.py,sha256=xMY2kLutkjCti5WqTmKOLRRL3o8Ds_k-fObFyuMv1tk,6061 -pip/_vendor/pep517/build.py,sha256=-n8PT-ugS1TdqoTUY1vatDQjrLtx48K_-Quu2MuQBiA,2699 -pip/_vendor/pep517/check.py,sha256=Lu7nMdYu1JVV58fE3hv-d_avTy5h0yO9LsIzAt82Clk,5885 -pip/_vendor/pep517/colorlog.py,sha256=Tk9AuYm_cLF3BKTBoSTJt9bRryn0aFojIQOwbfVUTxQ,4098 -pip/_vendor/pep517/compat.py,sha256=4SFG4QN-cNj8ebSa0wV0HUtEEQWwmbok2a0uk1gYEOM,631 -pip/_vendor/pep517/envbuild.py,sha256=9-u4KffexPMEm52rTaIjEOxsCAd2DMByxzv5H566QLw,5763 -pip/_vendor/pep517/wrappers.py,sha256=9dZn-q7F5KyQKUJMie2uKwur2FG0CLXz_kLZzkJOhZc,5912 -pip/_vendor/pkg_resources/__init__.py,sha256=ZVHzk7ZiFIIgE2RTJj8F7wwjdMGrAngMWtQo-rGNsm4,107910 -pip/_vendor/pkg_resources/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-38.pyc,, -pip/_vendor/pkg_resources/py31compat.py,sha256=CRk8fkiPRDLsbi5pZcKsHI__Pbmh_94L8mr9Qy9Ab2U,562 -pip/_vendor/progress/__init__.py,sha256=fcbQQXo5np2CoQyhSH5XprkicwLZNLePR3uIahznSO0,4857 -pip/_vendor/progress/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/progress/__pycache__/bar.cpython-38.pyc,, -pip/_vendor/progress/__pycache__/counter.cpython-38.pyc,, -pip/_vendor/progress/__pycache__/spinner.cpython-38.pyc,, -pip/_vendor/progress/bar.py,sha256=QuDuVNcmXgpxtNtxO0Fq72xKigxABaVmxYGBw4J3Z_E,2854 -pip/_vendor/progress/counter.py,sha256=MznyBrvPWrOlGe4MZAlGUb9q3aODe6_aNYeAE_VNoYA,1372 -pip/_vendor/progress/spinner.py,sha256=k8JbDW94T0-WXuXfxZIFhdoNPYp3jfnpXqBnfRv5fGs,1380 -pip/_vendor/pyparsing.py,sha256=sxGUe_YcWBB5ZoHec0m1iJtgcj4iKv_SGfdA_zVCYII,245385 -pip/_vendor/pytoml/__init__.py,sha256=W_SKx36Hsew-Fty36BOpreLm4uF4V_Tgkm_z9rIoOE8,127 -pip/_vendor/pytoml/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/pytoml/__pycache__/core.cpython-38.pyc,, -pip/_vendor/pytoml/__pycache__/parser.cpython-38.pyc,, -pip/_vendor/pytoml/__pycache__/test.cpython-38.pyc,, -pip/_vendor/pytoml/__pycache__/utils.cpython-38.pyc,, -pip/_vendor/pytoml/__pycache__/writer.cpython-38.pyc,, -pip/_vendor/pytoml/core.py,sha256=9CrLLTs1PdWjEwRnYzt_i4dhHcZvGxs_GsMlYAX3iY4,509 -pip/_vendor/pytoml/parser.py,sha256=2tDXkldqPQJhyadXzL2rGhVbjUyBNeXXhaEfncHl2iQ,10326 -pip/_vendor/pytoml/test.py,sha256=2nQs4aX3XQEaaQCx6x_OJTS2Hb0_IiTZRqNOeDmLCzo,1021 -pip/_vendor/pytoml/utils.py,sha256=JCLHx77Hu1R3F-bRgiROIiKyCzLwyebnp5P35cRJxWs,1665 -pip/_vendor/pytoml/writer.py,sha256=WbNNQg3sh_V-s3kt88LkNNbxEq6pPDdhRE-daJzArcI,3198 -pip/_vendor/requests/__init__.py,sha256=ONVsH6kJuPTV9nf-XVoubWsVX3qVtjCyju42kTW6Uug,4074 -pip/_vendor/requests/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/__version__.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/_internal_utils.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/adapters.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/api.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/auth.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/certs.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/compat.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/cookies.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/exceptions.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/help.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/hooks.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/models.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/packages.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/sessions.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/status_codes.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/structures.cpython-38.pyc,, -pip/_vendor/requests/__pycache__/utils.cpython-38.pyc,, -pip/_vendor/requests/__version__.py,sha256=Bm-GFstQaFezsFlnmEMrJDe8JNROz9n2XXYtODdvjjc,436 -pip/_vendor/requests/_internal_utils.py,sha256=Zx3PnEUccyfsB-ie11nZVAW8qClJy0gx1qNME7rgT18,1096 -pip/_vendor/requests/adapters.py,sha256=e-bmKEApNVqFdylxuMJJfiaHdlmS_zhWhIMEzlHvGuc,21548 -pip/_vendor/requests/api.py,sha256=fbUo11QoLOoNgWU6FfvNz8vMj9bE_cMmICXBa7TZHJs,6271 -pip/_vendor/requests/auth.py,sha256=QB2-cSUj1jrvWZfPXttsZpyAacQgtKLVk14vQW9TpSE,10206 -pip/_vendor/requests/certs.py,sha256=nXRVq9DtGmv_1AYbwjTu9UrgAcdJv05ZvkNeaoLOZxY,465 -pip/_vendor/requests/compat.py,sha256=FZX4Q_EMKiMnhZpZ3g_gOsT-j2ca9ij2gehDx1cwYeo,1941 -pip/_vendor/requests/cookies.py,sha256=Y-bKX6TvW3FnYlE6Au0SXtVVWcaNdFvuAwQxw-G0iTI,18430 -pip/_vendor/requests/exceptions.py,sha256=-mLam3TAx80V09EaH3H-ZxR61eAVuLRZ8zgBBSLjK44,3197 -pip/_vendor/requests/help.py,sha256=SJPVcoXeo7KfK4AxJN5eFVQCjr0im87tU2n7ubLsksU,3578 -pip/_vendor/requests/hooks.py,sha256=QReGyy0bRcr5rkwCuObNakbYsc7EkiKeBwG4qHekr2Q,757 -pip/_vendor/requests/models.py,sha256=6s-37iAqXVptq8z7U_LoH_pbIPrCQUm_Z8QuIGE29Q0,34275 -pip/_vendor/requests/packages.py,sha256=njJmVifY4aSctuW3PP5EFRCxjEwMRDO6J_feG2dKWsI,695 -pip/_vendor/requests/sessions.py,sha256=DjbCotDW6xSAaBsjbW-L8l4N0UcwmrxVNgSrZgIjGWM,29332 -pip/_vendor/requests/status_codes.py,sha256=XWlcpBjbCtq9sSqpH9_KKxgnLTf9Z__wCWolq21ySlg,4129 -pip/_vendor/requests/structures.py,sha256=zoP8qly2Jak5e89HwpqjN1z2diztI-_gaqts1raJJBc,2981 -pip/_vendor/requests/utils.py,sha256=LtPJ1db6mJff2TJSJWKi7rBpzjPS3mSOrjC9zRhoD3A,30049 -pip/_vendor/retrying.py,sha256=k3fflf5_Mm0XcIJYhB7Tj34bqCCPhUDkYbx1NvW2FPE,9972 -pip/_vendor/six.py,sha256=h9jch2pS86y4R36pKRS3LOYUCVFNIJMRwjZ4fJDtJ44,32452 -pip/_vendor/urllib3/__init__.py,sha256=dW1kWCz7bYGr-1q7xbDvJ_0_GwfyJtWq4VaLIzMcviA,2721 -pip/_vendor/urllib3/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/urllib3/__pycache__/_collections.cpython-38.pyc,, -pip/_vendor/urllib3/__pycache__/connection.cpython-38.pyc,, -pip/_vendor/urllib3/__pycache__/connectionpool.cpython-38.pyc,, -pip/_vendor/urllib3/__pycache__/exceptions.cpython-38.pyc,, -pip/_vendor/urllib3/__pycache__/fields.cpython-38.pyc,, -pip/_vendor/urllib3/__pycache__/filepost.cpython-38.pyc,, -pip/_vendor/urllib3/__pycache__/poolmanager.cpython-38.pyc,, -pip/_vendor/urllib3/__pycache__/request.cpython-38.pyc,, -pip/_vendor/urllib3/__pycache__/response.cpython-38.pyc,, -pip/_vendor/urllib3/_collections.py,sha256=-CAKsDE-WdubAjlBSZLx7b0e7WKenaNGwWvGLDEF1TM,10746 -pip/_vendor/urllib3/connection.py,sha256=hdUK2hwFNWlKxpm7JbY_YxGYJWbe6s0AYUSt9wguHk0,15001 -pip/_vendor/urllib3/connectionpool.py,sha256=jkmLBXUD8wB0exYjDoEsg_cXVZUv-iDbhC3vAUUH82Q,35307 -pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-38.pyc,, -pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-38.pyc,, -pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-38.pyc,, -pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-38.pyc,, -pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-38.pyc,, -pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-38.pyc,, -pip/_vendor/urllib3/contrib/_appengine_environ.py,sha256=lhYXvB5_oGKSeurX7za3XhcGyERvNjXRQ3eJp2GmQ3M,717 -pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-38.pyc,, -pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-38.pyc,, -pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=6ZRejHBpquHtJaXPDm0cBsEwOBe2l9bTnDvVzd0HwJw,17576 -pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=Umy5u-3Z957GirdapnicXVOpHaM4xdOZABJuJxfaeJA,12162 -pip/_vendor/urllib3/contrib/appengine.py,sha256=VvDpkc5gf9dTXNxXmyG1mPdON_3DrYG_eW4uOqN98oQ,10938 -pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=5ZpMF7N9B6NEjVU-r-xjDOV_-hkNvsDoNc84J2yqauI,4459 -pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=raR9jRVPK485CjBp9emmWfoZIyMA1b3vcYJ2-CLg03A,16468 -pip/_vendor/urllib3/contrib/securetransport.py,sha256=IfPZ2wA3x3NXxHjKr--Q7Xz4A37ZSyWHn_1WvGxvTKQ,32826 -pip/_vendor/urllib3/contrib/socks.py,sha256=ZJ7lEUlErvAgQkd4xo_xvfx-acym2tDtJqyE0It4VRI,7012 -pip/_vendor/urllib3/exceptions.py,sha256=rFeIfBNKC8KJ61ux-MtJyJlEC9G9ggkmCeF751JwVR4,6604 -pip/_vendor/urllib3/fields.py,sha256=0EYvHsgnUflhb-UhMMVjAwiRp1InCe-uy1McDD6nhPU,8575 -pip/_vendor/urllib3/filepost.py,sha256=40CROlpRKVBpFUkD0R6wJf_PpvbcRQRFUu0OOQlFkKM,2436 -pip/_vendor/urllib3/packages/__init__.py,sha256=nlChrGzkjCkmhCX9HrF_qHPUgosfsPQkVIJxiiLhk9g,109 -pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/urllib3/packages/__pycache__/six.cpython-38.pyc,, -pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-38.pyc,, -pip/_vendor/urllib3/packages/backports/makefile.py,sha256=so2z9BiNM8kh38Ve5tomQP_mp2_ubEqzdlCpLZKzzCI,1456 -pip/_vendor/urllib3/packages/rfc3986/__init__.py,sha256=Y2dGb08ZJuqIrAqfmrGMpNi2zjzKVTxfeZ8iF-Db338,1562 -pip/_vendor/urllib3/packages/rfc3986/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/__pycache__/_mixin.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/__pycache__/abnf_regexp.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/__pycache__/api.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/__pycache__/builder.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/__pycache__/compat.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/__pycache__/exceptions.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/__pycache__/iri.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/__pycache__/misc.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/__pycache__/normalizers.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/__pycache__/parseresult.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/__pycache__/uri.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/__pycache__/validators.cpython-38.pyc,, -pip/_vendor/urllib3/packages/rfc3986/_mixin.py,sha256=fnxYtuAQwo6RlGZzsawcICxUhLqQ_Tyob_Kamy-92QU,13214 -pip/_vendor/urllib3/packages/rfc3986/abnf_regexp.py,sha256=0cPq-UrpihByHkDsZd_7p6ruqYh2MuqCqIjc67PFHCs,9081 -pip/_vendor/urllib3/packages/rfc3986/api.py,sha256=5wYJ3IvszICEY5cgeLTtLRWCyc9mJhgZ_4QZVtYoSKI,3887 -pip/_vendor/urllib3/packages/rfc3986/builder.py,sha256=BFbuFFZUcAnGJzvtQ0n7ffHqgG-CBf-Xi_6aU68n-OA,9577 -pip/_vendor/urllib3/packages/rfc3986/compat.py,sha256=jnSGxU4M13w5vuLldgKmXmpxcZBxmUwg8dBzNQEWzYc,1513 -pip/_vendor/urllib3/packages/rfc3986/exceptions.py,sha256=dadexlPfwsYbcbFdbR1lp5WyuF8PMsSmx2gA3nrger4,3775 -pip/_vendor/urllib3/packages/rfc3986/iri.py,sha256=UWHdKI_aOiK_SC3oE_nTrxsgiS8shJQRkmKn_AAxyms,5483 -pip/_vendor/urllib3/packages/rfc3986/misc.py,sha256=MbL7MgqbTef5VddkaaPKkLpe0hPRNCEx0-kKhJfRyk8,4094 -pip/_vendor/urllib3/packages/rfc3986/normalizers.py,sha256=L6DOXDi7vZ_BDoXS8IUl9CW21E-siDJluK2mmImljtY,5259 -pip/_vendor/urllib3/packages/rfc3986/parseresult.py,sha256=cdmsiBExo5o2A2jWI-TtGFeXTPenyXQbGf5Nmv7nh6M,14654 -pip/_vendor/urllib3/packages/rfc3986/uri.py,sha256=r_KhSNmvWfoBGRPBf1dnlwWnCwuM-JHFtGa-6DH_jH4,5227 -pip/_vendor/urllib3/packages/rfc3986/validators.py,sha256=jbJGdqUcoeSD2E_gmuFbrujLsVtEpjhJg7oxpiFeyY4,13854 -pip/_vendor/urllib3/packages/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098 -pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py,sha256=WBVbxQBojNAxfZwNavkox3BgJiMA9BJmm-_fwd0jD_o,688 -pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-38.pyc,, -pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py,sha256=E-9J-kAaUn76WMZ4PpzKUxM4C3yjY7mopOpbPIy3Dso,5700 -pip/_vendor/urllib3/poolmanager.py,sha256=GrUSFRcQbhxPMRlePxOUbXvmsOgGTiNrxQpICmXd30I,17050 -pip/_vendor/urllib3/request.py,sha256=OfelFYzPnxGlU3amEz9uBLjCBOriwgJh4QC_aW9SF3U,5991 -pip/_vendor/urllib3/response.py,sha256=GxiW6sI0NZgdlDL4hzPfKDZmH7OFTiGZosaXu2DMG7k,27171 -pip/_vendor/urllib3/util/__init__.py,sha256=P-VlwgBFaga7i1BTWPNHGK4TN-SES0VoexbeIPIKs_0,1082 -pip/_vendor/urllib3/util/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/urllib3/util/__pycache__/connection.cpython-38.pyc,, -pip/_vendor/urllib3/util/__pycache__/queue.cpython-38.pyc,, -pip/_vendor/urllib3/util/__pycache__/request.cpython-38.pyc,, -pip/_vendor/urllib3/util/__pycache__/response.cpython-38.pyc,, -pip/_vendor/urllib3/util/__pycache__/retry.cpython-38.pyc,, -pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-38.pyc,, -pip/_vendor/urllib3/util/__pycache__/timeout.cpython-38.pyc,, -pip/_vendor/urllib3/util/__pycache__/url.cpython-38.pyc,, -pip/_vendor/urllib3/util/__pycache__/wait.cpython-38.pyc,, -pip/_vendor/urllib3/util/connection.py,sha256=-AyqcRTuNUHuo5ndtsU0Og_nMyCGATC-kYqOUdBHwIQ,4639 -pip/_vendor/urllib3/util/queue.py,sha256=myTX3JDHntglKQNBf3b6dasHH-uF-W59vzGSQiFdAfI,497 -pip/_vendor/urllib3/util/request.py,sha256=_pmOHJWpOHk7w8BDz6WZkmMunNmplEPBmh2-5bl3Do4,3832 -pip/_vendor/urllib3/util/response.py,sha256=028PNXDZhwBtnm2uXvnAHi_l9_AAGrAMH2Igh2AbgWg,2586 -pip/_vendor/urllib3/util/retry.py,sha256=1m-XI9_LORj1FLbwOzgWC6pTt2deycyGl4BWRI9r4Zc,15150 -pip/_vendor/urllib3/util/ssl_.py,sha256=bYkkcBpWIbtFL3WCiX2pgTRjS2Ukdpv0oTtHHK0g8Mw,13798 -pip/_vendor/urllib3/util/timeout.py,sha256=dTF-iEp8DZiPd-8g2X7CVucDoBWJBn221T8ghg-tjkQ,9768 -pip/_vendor/urllib3/util/url.py,sha256=DyEkFjkLo4C82N1elJgpePfccgLb6IHMjBTnPgs9QmU,9827 -pip/_vendor/urllib3/util/wait.py,sha256=p4BZo_Ukp5JF0Dn6jro7cUfqIjnU6WFtuoA6poaV5Jk,5403 -pip/_vendor/webencodings/__init__.py,sha256=qOBJIuPy_4ByYH6W_bNgJF-qYQ2DoU-dKsDu5yRWCXg,10579 -pip/_vendor/webencodings/__pycache__/__init__.cpython-38.pyc,, -pip/_vendor/webencodings/__pycache__/labels.cpython-38.pyc,, -pip/_vendor/webencodings/__pycache__/mklabels.cpython-38.pyc,, -pip/_vendor/webencodings/__pycache__/tests.cpython-38.pyc,, -pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-38.pyc,, -pip/_vendor/webencodings/labels.py,sha256=4AO_KxTddqGtrL9ns7kAPjb0CcN6xsCIxbK37HY9r3E,8979 -pip/_vendor/webencodings/mklabels.py,sha256=GYIeywnpaLnP0GSic8LFWgd0UVvO_l1Nc6YoF-87R_4,1305 -pip/_vendor/webencodings/tests.py,sha256=OtGLyjhNY1fvkW1GvLJ_FV9ZoqC9Anyjr7q3kxTbzNs,6563 -pip/_vendor/webencodings/x_user_defined.py,sha256=yOqWSdmpytGfUgh_Z6JYgDNhoc-BAHyyeeT15Fr42tM,4307 diff --git a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/WHEEL b/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/WHEEL deleted file mode 100644 index 8b701e9..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.33.6) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/entry_points.txt b/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/entry_points.txt deleted file mode 100644 index f5809cb..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/entry_points.txt +++ /dev/null @@ -1,5 +0,0 @@ -[console_scripts] -pip = pip._internal:main -pip3 = pip._internal:main -pip3.7 = pip._internal:main - diff --git a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/top_level.txt b/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/top_level.txt deleted file mode 100644 index a1b589e..0000000 --- a/venv/lib/python3.8/site-packages/pip-19.2.3.dist-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/venv/lib/python3.8/site-packages/pip/__init__.py b/venv/lib/python3.8/site-packages/pip/__init__.py index 0803e00..b2e0514 100644 --- a/venv/lib/python3.8/site-packages/pip/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/__init__.py @@ -1 +1,18 @@ -__version__ = "19.2.3" +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional + + +__version__ = "20.2.4" + + +def main(args=None): + # type: (Optional[List[str]]) -> int + """This is an internal API only meant for use by pip's own console scripts. + + For additional details, see https://github.com/pypa/pip/issues/7498. + """ + from pip._internal.utils.entrypoints import _wrapper + + return _wrapper(args) diff --git a/venv/lib/python3.8/site-packages/pip/__main__.py b/venv/lib/python3.8/site-packages/pip/__main__.py index 0c223f8..7c2505f 100644 --- a/venv/lib/python3.8/site-packages/pip/__main__.py +++ b/venv/lib/python3.8/site-packages/pip/__main__.py @@ -3,6 +3,13 @@ from __future__ import absolute_import import os import sys +# Remove '' and current working directory from the first entry +# of sys.path, if present to avoid using current directory +# in pip commands check, freeze, install, list and show, +# when invoked as python -m pip <command> +if sys.path[0] in ('', os.getcwd()): + sys.path.pop(0) + # If we are running from a wheel, add the wheel to sys.path # This allows the usage python pip-*.whl/pip install pip-*.whl if __package__ == '': @@ -13,7 +20,7 @@ if __package__ == '': path = os.path.dirname(os.path.dirname(__file__)) sys.path.insert(0, path) -from pip._internal import main as _main # isort:skip # noqa +from pip._internal.cli.main import main as _main # isort:skip # noqa if __name__ == '__main__': sys.exit(_main()) diff --git a/venv/lib/python3.8/site-packages/pip/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/__pycache__/__init__.cpython-38.pyc index 9d4b243940cf6b34fb196ba8a0d15aa69d243f1c..c55e9437961daf1cb0646cfa2b7fe3d5a7ad9d82 100644 GIT binary patch literal 663 zcmZuv&2AGh5Vm(WX$Y-^P)}U&4Xp%g6e>|rg+LKM6%eXI56#7L)+TY;wJqD5vQas~ zJMav=0x!Tj?3EL*zyUE%0rkMhGxBGRzxihDqphtW0?U7WW#2GD-y^taDS(IIegr`v zfh$zwDaJ@*M*t^PQm50j&ZZegBAxcchUkg@Cp_(o>@~^<Kj0q9ad-9Q@xd`0KYKiW z&JK?zll{rlJn6C*%7<?7$_8aLuU7rh?P65yOiIx5&l1>0AA|dC2m(W0(D4CuoZ&O{ z5ksYP_4&<0c>;@TqI8fB7|El9ePVRgl3H>d$Xnw`<0YB3#43Bk6LYFbX|y+$B))XY z244(^1ndc<av{{YG$Lf+s`599my#?(u>L-!a}^fNtSC)QZEHCNPO7|bq^Eax?(G(9 zA{U#15e(R=<JL+CjbDe%g8fxlGy$j!se@~+fm82#@eT}#yZJfzg4_Vkejd_=sU>x7 z)0`;kT}cJkN>-(DLHgo-yP`{}m$Xtd&=eL%-zj#fS3%ygynM&!pe@Q|P+bMa3fp#B z&6SQH!DkRqe=~6r<#>{Bbl3hTHMCagxr@)z_5XnQS6n3ME;F{2&cmBBwq{yOzYs3P YtifJwL{rHJaXvmax0z)4N}8p=0Rz^s@Bjb+ literal 158 zcmWIL<>g`kg6Cx$;>3aUV-N=!FakLaKwQiLBvKfn7*ZI688n%y*bFW8jP#8CG#PJk z$H$kY78Pga=f%gbWGG?+Dg+b1boEPe3-k*z3v@H{ic1o6a&(O{OiC+^^AkaWU>qNx dnU`4-AFo$Xd5gm)H$SB`C)EyQ=Vu^h005CfCBXmy diff --git a/venv/lib/python3.8/site-packages/pip/__pycache__/__main__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/__pycache__/__main__.cpython-38.pyc index e75d8617712ba9088939dd1e0a5d8a12434eca4d..8f61de93b8e23ce4492afc1ef601e3c3e8001f17 100644 GIT binary patch delta 331 zcmXYsJx;?w5QX>0aZC~$iYNksl(Y!pEocx0H=v0`lV)YS6MGYTy;?hgZ~_VhveHq- z*Wd<R!AAiJVWUj(r1|vT=*<WHq29gg_E0nDzn}b_mfjhDEiWcO7nVRLNKhcVPKD-V zX`9=Y?rec7j1hDNT@n)mX_&Lug9=x8X8rqm0)bT#j06%^(oY97w@G=T)1+R2?he5% z-)`_x`E@$AbWp^#9YGO3ikj+7*L}`)5H5oVIIp`x8Wp5aJDksD(jr@`986J<wA4PA zs({9k_+cXbG>~dL!Q;DO^OtGmd&=T01!gv@)k3n|giHiVLK0@CfZTuDJhL^ZHB00J m)0-mB)RlkDa#_ITzD2%`@c6hrHXsgm>=7PVPG^Wc((Zq+iC~lf delta 260 zcmey(Jd2qxl$V!_0SKO#ZHUWfn#d=^m^D#b!I>q6Ih(1-EtM&YbpaccWM9a*kTHri zl^H0;k;0J5x{!&HA%!7@C5JPYD~g+uA(bbE6{ssMm3aYgD)+<<R*ZZTUrXC?$Hx~W zCTAz6r^d(MVkt;0$+*Ryl3A3On45ZwBR)PYGY2HWmYG+aT2yk2w;;1XFFrG`Bo(M4 zXL1Cie6$eIeMKPRm#%(EZh<~fg)UHaNn%cpu2F_bX@zlqB1jO7<KuG^GxOr(^$IF) iaoFVMr<CTT+A#t(7YhIh9wrV(4i*kp5k@{H5E}qMIZA2( diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__init__.py b/venv/lib/python3.8/site-packages/pip/_internal/__init__.py index fbadc28..264c2ca 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/__init__.py @@ -1,77 +1,17 @@ -#!/usr/bin/env python -from __future__ import absolute_import +import pip._internal.utils.inject_securetransport # noqa +from pip._internal.utils.typing import MYPY_CHECK_RUNNING -import locale -import logging -import os -import warnings - -import sys - -# 2016-06-17 barry@debian.org: urllib3 1.14 added optional support for socks, -# but if invoked (i.e. imported), it will issue a warning to stderr if socks -# isn't available. requests unconditionally imports urllib3's socks contrib -# module, triggering this warning. The warning breaks DEP-8 tests (because of -# the stderr output) and is just plain annoying in normal usage. I don't want -# to add socks as yet another dependency for pip, nor do I want to allow-stderr -# in the DEP-8 tests, so just suppress the warning. pdb tells me this has to -# be done before the import of pip.vcs. -from pip._vendor.urllib3.exceptions import DependencyWarning -warnings.filterwarnings("ignore", category=DependencyWarning) # noqa - -# We want to inject the use of SecureTransport as early as possible so that any -# references or sessions or what have you are ensured to have it, however we -# only want to do this in the case that we're running on macOS and the linked -# OpenSSL is too old to handle TLSv1.2 -try: - import ssl -except ImportError: - pass -else: - # Checks for OpenSSL 1.0.1 on MacOS - if sys.platform == "darwin" and ssl.OPENSSL_VERSION_NUMBER < 0x1000100f: - try: - from pip._vendor.urllib3.contrib import securetransport - except (ImportError, OSError): - pass - else: - securetransport.inject_into_urllib3() - -from pip._internal.cli.autocompletion import autocomplete -from pip._internal.cli.main_parser import parse_command -from pip._internal.commands import commands_dict -from pip._internal.exceptions import PipError -from pip._internal.utils import deprecation -from pip._vendor.urllib3.exceptions import InsecureRequestWarning - -logger = logging.getLogger(__name__) - -# Hide the InsecureRequestWarning from urllib3 -warnings.filterwarnings("ignore", category=InsecureRequestWarning) +if MYPY_CHECK_RUNNING: + from typing import Optional, List def main(args=None): - if args is None: - args = sys.argv[1:] + # type: (Optional[List[str]]) -> int + """This is preserved for old console scripts that may still be referencing + it. - # Configure our deprecation warnings to be sent through loggers - deprecation.install_warning_logger() + For additional details, see https://github.com/pypa/pip/issues/7498. + """ + from pip._internal.utils.entrypoints import _wrapper - autocomplete() - - try: - cmd_name, cmd_args = parse_command(args) - except PipError as exc: - sys.stderr.write("ERROR: %s" % exc) - sys.stderr.write(os.linesep) - sys.exit(1) - - # Needed for locale.getpreferredencoding(False) to work - # in pip._internal.utils.encoding.auto_decode - try: - locale.setlocale(locale.LC_ALL, '') - except locale.Error as e: - # setlocale can apparently crash if locale are uninitialized - logger.debug("Ignoring error %s when setting locale", e) - command = commands_dict[cmd_name](isolated=("--isolated" in cmd_args)) - return command.main(cmd_args) + return _wrapper(args) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/__init__.cpython-38.pyc index ce213504062728573121d5c08c5eee50f72940b9..6d86fe0c5787197953d2a3d8525443cb63d2d29a 100644 GIT binary patch literal 712 zcmZuv&2H2%5Vn)-ZdkPvLY%nZBS8=!K+qzDkXHN&SP;-dS4fdJo^D(c$FiM;ROJNE z!JSv&QF7(Pi8}|xc#EnYI`WKXtQmjbjJ>zLJtZjF-yg+qO32R;oRt`Zhp6rj8c8Ir z$%5h@)lm~KVoD&k*D#Ljq!}$n&3G}UM2=-5M_=h;BI#R_O@3i5nP+sk^m708eldIc zX!g8#vp1hVn?K2-A$?`MYPG0`<b`s+L>{LSp%-+9>Mo;^6tPJ|KT}GM=`r~d5aOe6 z?<(aOE@Q!gU4vu?tz~U3S=nmW*1%k8mGO@GN_f_Yo;k1Tnk|7@H~<T}RC+aKD9Y#4 zjq@0<5K^iWdQ5^Bs&+S+17MZ+#@*w5rF_*b^RjKY>5bq<8Lph`!124ccX#s5MK<(= z14xUHRu}^o+rEmKd7-oii@oO^vT-?RZ+p|?sk5U{6Ag*5tCQe6u_>PYdC#l10dD)Q zJ5=1+l1rf#)MaZuxcpOp#MhwLyjDx(<f~TS%6GU^9&Q>@eh@3<7HFP=^8#Jviy}Au zkTgQ+fa4N0WU>|6@JBK_&(h)gd8Cy-gwhud%FcqfLOX*@h8S~)E9VvX-r%flc-Ue5 lKL|g~2E+~8rqMIzLP$;TH?8byco3%P0>zYWMG3ta{{zfF#gYI3 literal 1703 zcmZuxOK&7K5VqYtJw20oWs;pu$YTeI1w|qWVt0jv5CWD+1chXkXh~=xTAi^o+Y|Q# z+mpv=lFPzz|HI^n#DUZP0Dgu~NF2}}_ye3MdnQqKp)K3xa#gup-{*c>t(Fmdf1UjH z!`~qNX%@G?5-dK0F5kfjQA9CE2@WteGT|g3c6I{C&Tin^xeyfW>;)do4lgEt;A6xJ zy%KeqPYW*yMuUpADF@|!l+L<{O&ym-ijisGq4cW*#JpaGddEb(WaVC!7LSp5IcR{F z&ud9NsAB}4bH<Z3jtF@FdgEON@A_!^3SxnMi8qs(V8+U2KAYSL?pS$>x01WTT`O1k zTrwZbTe-^LN*00zE7u_V#b6P#cScKW`3eX3Cihqz--AxmI&J)fgEl35Xr=ke)Ncjr zdUPl=-d8M)lROh@8+6lOvYe%qrJeKrNThMv)n439Gr?ff??j4qGjXmx8i~_5jq456 zFp(td^aWEQN~MVes!G&XStm<!&Xn=3=8=#r1Wgj9)F>vR3~Agk9{!U!-w+}bAWu=2 z3kJu<SqjV6W;#A$m;KmhQcY6p0OU8H2a=)6W9ae^7=}>TV_&os>S2m0`kBn53#7=% zF-2GIa~KB=RT!e@_<M4JF9?A3wTqMoKwV;V;lTd;;9VT~lnk8~x&m5_*Q(Sjk5{89 zijB079>IAR&ZTo;$UzR!ps6aOs;cyA)VTsWLG%wGdZkx~_`gGZ*Ph=PO;dO1jxB5q z_tL$Np_)THk7!{?jy>wVz!!yKVKg%&R~UdSZoe`G7?d`4cXxI_Zr_(04eoCmv;em@ zGqnU|`}7%0+mb0|v^?uXoDIsWt1*BNcp5DH8+lec@?2^+65SI~f#|vwr&2|nho@sc zggonZA+`^j!n{5)Wz0OOC}?%zRK$vDl1W|Uampmiwad<8rM>adx&*0AL~rYH`1#hB zE?C@+g$b<-lpXfF!l0?$B#P4&&t@cnfe8)MC}Cp>vXt6kXB~~1E=~yb3li^w=RY5< zt0Z5~<9u~;gVhh8J?x)7$ReY(J&aSuL>lq+5X4x8;aYw!?t%9s=&}t1!alA!KJf^_ z4clsX(IvQvn`9YAYrTTESKij;Fg)rjcn4u92zZKl7@!JpDX6??nUz1Oq7>7x43;62 zweSR9Tqf4~g7f(B!5Z9$<%aoEIL4=T6mv-P+7l3xTu*J<H#;tzp97LdnMibN=gG$Q z-riRD?Z)oj=FWDw{q&nJHg<!B|2wFYrAowyqG<En*|WidnK<pSjxx2$!bwiLZT+vy zwbtSB+N}o;xmrHxrT>~4{6hQqg{6yby<s!{Bgiq_bFXjSDurQLF!TC$U&UNnnu@Bq zL#fNu)|f+nXn6uqEWwUN$<pH1@Sbt;KS?s$=j>C1n0yFBh4_FuG~$;lxaJWIBletG TY#7kQ9`Q*9bdyHPPR;ojavaoQ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/build_env.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/build_env.cpython-38.pyc index 51a8a402f8675259c54c8b16b7deee66c9ca8d03..1eaaf3dd4091404ea70fa7f5095a1420e46de9e7 100644 GIT binary patch delta 2591 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 Z5QEc`<s!+-3dxdLcn_xX<>HQX>OU|KYkB|x delta 2492 zcmai0U2GIp6rMY~J3G7GKlZP??UtWnfd$+0BZ>$OL7+jPL4lwfVchP$w6pB)40op3 z!a`$Of<_7<R}&w6*lK*>NfRDSeDFnIh#@gCF>&I%@j(-O@IeiF&K-Umh&!2+d++(V z=bZ1HvvX(rm)jG^;_;{gzhBONaq_p)^+bs%*EcN85`_}l)hINJl_F7CH~$v)u|`j` zx6<1zRZ7jiN?&t%WqET&WrdWDH&!-RRaSv4>GZSJi=^_*s6rDoIj_*<oLU)xU5YM) z-7>ajE>Kwu`!vnKKEu|+ejQbhDCO+Amv&E?4Jr<h&sHUC)kec`rp9e<)tKXyi5EZ0 zn)V)(vzlx18L?3<CS#V(T83krtrp|uka$B~bMulqNk~cj9w@9HfY|=pHtaU-VcWC^ z&6eYW)xph^&rMBlv8s3|#)1Q+Pq@K1*RKU>jw+9kHMq?H>4n!(f#@pFh&$bVWS2-5 zUX0QByi$qK1o)p6$3pJxKOo~`0@Vfbu42GjCmnTBA&MKgtehe=K!fu-4ee3p$Q()p zClsI|Ni{d@>Yx$qL>47~k8)z=1+)?BMBAj^wMYm^*R@Uzc5&RDIY>1co>$xi)oBF4 zgGCe;<dlk6Tu|L)J=Ix;Zq!q>Yf**E(()_=XX!=aeB~xPS$_>q<{rqWX>3uY@j3Nc z|Ajz1(8;^qodQiPl6tWXR_Yo}E~x0jab>IWs`8rhx<Zw1NJMJvTx1-P9AvGt09^32 z*%Ci%y@hp<o3@OoO<ct#b+r=!LqQP_7xsr_p80Z+;Uyqmux^<xFJia=yFpEUL-o|5 zjeG_0ZV=v&auO}X$cyZlU@bOn^O0?0GCaQ<Ipx43*7TOeo3*OL$|~Q48bQZ&*%GM1 zjKkcT)wD<Ui6MO?+yjzF`3pC>emhWDg*JOQwhSLe6IzY4s>?(rHrl^Z9<XVbwJ1kP z9zgOS96ltziH#nXZeua=?WmxhvV9je<B_a3EW<7EI(Ve0F%nf{s(LpX(uhX#BtcRk zP1T8hSN&Jhvf^a?&+UUCcrREl3^_Ns)$#%p%;g(_voyx&4r<o?ARFRpg3TTVA&+b- zM<Llx^(-^M1mB68FC!=9*bUQ_k$7Rd>P|Y$=6jHR2-(_{O(6+<2sY)QkBh`lw;I$y zc`s_uxRX{3*Grv=7)F}4K;1A-g8>H<t`ISwTo{m1h4@i8@Iru9)A6$@Zw=U%UDkNN zcs{j7_PK9Z)`D&rY}#}U<04wreT!F8{o?OpY8HDK!*UWp+DcvN5NuAW98tKuQT4G6 z*BY$anzFe>=HXb77}Y@c5*k5kih8af2iIOd^G%3n=$>{>3ZM}D!tmbwI(3|o5s^>t zB>m!O`q`z<r)!g}cG}?V%oL0|wB@`fK22B2_{~seh={$}>_DL%oFmuL7vgTQt+nGc zzo0(eh0uiE;$rp+p`t4{nuQ(=-yf1ad<VF}`^4M10nM*Y@kwqU*)4v}^(7_XVb1JE zwFZ!iTz-Fo$50^xq?~|+pU-bC$^x$A@jMVOd<uH2>N@<gxRvkA%^>6PjCol>db8Tc zz;Rv?x$aT%R`;+O<v0;|8OeGeUf3|GRWl4OXK@A3$B|&ZIY%OpJhUxW5|RzTz^0VA z>LeJ@x9J%@tOxZB-v9&qyJ1AvSA7zsc;ju<mxz&bed2IWP8`y85iPF%A6<0x`$u$_ zOWn_td2zXz-}T_$``vK@MEOZ129k%-$UrdQAK-o5kw1zX1|JxDYEAz5P*05Yj2=e~ z06#Nkx%-=TLzWYxdpWn@-_mc@_d$eTK_WrDimN3aVa|Vo_r6DE8Qx5HVfJzO_y?%` zB<P-s+J~TV3r%B<Nz?+md^mE-W#8mGu=acZJg)Ww@w#eOLwwZR(6Gt9f;e2tYE9Fr z@rXE3>ep~cdp&TPi_O62!36KZgFK4OLSx}|p62?jIBYnM1D-^ZLb42qmw^w2A;ZM+ z)T%ay%ob(SJdK<P4A+C!#02Ah3D2TV205BFUWYFfj`b*mcqE&CweCVOeMi%xQw=sk hVCP`*L&XyRi4l0zER6npj~XN;IEe-l+0?Ak`yZ2qAld)` diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/cache.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/cache.cpython-38.pyc index e5ae76987bacd42bae3e3bc00c4b900e0055a6cd..535ef4f106e266d4e29123166d9e761284eb405b 100644 GIT binary patch literal 9144 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 Dh92{E literal 7091 zcmb7JOKcm*8QvF{4^uKF*|B6h$u<e<5Vh&laUU?6Ag=s~n^;aQ2Tlm2+ZA_2Qd;iP zvrEe&sGx}5=G30sOCS}!_)wrlZ@u)^V-GzP#R5I`P`Jk)0~GG}|Fa}TT1rw1J3BKw zkAME>_mAG6nJH=b{p<eke)R9>HSM3&*#EQ8cneSb9~8b;*L>YK0==&D+o&7-HtQz8 zt-6J`8RR;4-PUQW734dGdV%Y?px7zZOI){uBb{=+%=LUQ)0wT$a=j27?NsU&t`~#3 z&U}5ovru2qHBphj!Fr|OSm${Cc;~tLbDb0Q6P?BSB9A>1EOk!SPhy<8drF+%)9cS) z*Zi_S^GNe�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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/configuration.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/configuration.cpython-38.pyc index 68f8062c26294cb3fb220cb762b7cd6959150afa..0b1b187497aa91238bad228e95eb9ae71ef3f390 100644 GIT binary patch delta 1507 zcmZuwO>7%g5Z>7zXYJUI>-_&TaqKwB=Etr?Q7Z~X5T!_nMpPjZqzQ}b-MCKNwflAx z5_e5#3#n)cNSQ-XL12p$a6n~m<-i4jkl@J0Qb8bbL@JefKy4}W+?KWyEA6~_^Z(7v z+nK#G7oH1+0s?*7KUeg`zRTfXq^V5$c=3dpW*e)k%lWj;vS}k@<;_C2$Q;v7t#6dm zYo@i9F657;OB>GdqV-s6f7;GF=42_8UCHE38w2tl81oLu?ErhdBgzGU8SkoZ6q;Y4 zT=po>C}KpNj($g+Da?Z*%!>xhOU5MT)M}5R8Dnn=^IgWcF+pedIYAcYdu9bK<?Zr2 z5}d=W;5MAcw$N=j=|#hX0PlNyTaEx+#I49*@F}kEx&fb~6`k62D1|Fjg_;0#E`uF) z#4|t=sU|Fl6{#Y-vH>f8_L3vJa280WRD7;nRa~V8_95bYoFi|!+T<#(&lPJD-9(C} z@`&An3s3SKephnknh1gcRI6B?JX|zzxOE~CsCVe5Wv?<*Kb~1L^+GXY=tZlr!Jen; z*vmw4r8R{gw=TALbg|or2(l^$0M)j=n?8P{e~Ny)O5}e45u|15ZaFJWY>z{r2m;gy zQUk890ha)~k|7e@_nfACaOH~PN>!Cg2ew3<-<1ilXj>FR;@$^H7~pFA3~|kz<Gri~ zsRt6r`yjOoPYH%d=;d-^&azDhwbp)xy-GFXX0i`Yw)aIt>=<1iKxZ>}seQbUEt0ez zX6A_^wa7NJPQGZdB@${ryw%>1MkKPYd6fs%*D{4w^LtX+aUz1mI~9Sj7!*|qLI47H zL`ekkj;s(5LDAdkcmm*e{HgN?DB;Df1l+){yRM5j1@Fu5F93GoLhqQbM4{O0_-?NW ze!SlM$9=)ozHwMb|L$p}LKZ{b?Cx!VxAC|BR^>Da()f3Oy?LEGpCwX{;I9K39P<3J zcc7^*QLXH?hB4R9c$Wtgw66Gbd|25g!O@*WdrSXR(OSyqR#}FFPI<}1QGgvhJv2hQ z{@G9*Hu1-y3FQ>o=kWH>V0_?F2YP)>&o*M{OZkFnXGMG_*)`1{Hw}jtv|FH|KsoW8 z>BJh{vtuP@+NR~i@>VPpyXzd|&Kj^8^3z22A{}fBGm+MKTkd|_Z9Q+@%e4hG0g;RZ zsT{{Qqn*tUDe>uKPi%~IyZ}4kG}dsLzZ#)isDKN0+>x-DJRFiA+J(dTZE_-Xfd>vZ z0@D+?nJmK_xHfzMF5y?hY3!4F4n|2y8_t76BPcB*e{?ft^;Bi_)F7*9n#=~sip>(K ztGaGwPMEsR7U+t#uC{$##>^7a_3D2(#B#@@oxN|O!Hm|+KIFdFhM)CWJn$OsAK9Ja zJHhxKusKfnkQpB=<I`dvaPkT#e3RKnxG^%`n<dsx5m7-7h5J=i4XRD5Uu{!+@tcv( zF-2`ree56^Xd3&3`<*9JZz>dXxxAHQ6I}E-7vZguYp{iXj&}QaZLEYrZ4qQ#)<&T7 EUw4Iy+W-In delta 1370 zcmZ8gOKcle6rKBK#(s8eCv|XYD<N?{P2zkSpb4!YAVJiYhQ<hmsI6%`F_}p+jWc7t znOIFUPE-OaRU5U+6J=G^h7BJfQB8#q5fVsjfE~+Oz^Y<_gbEV7^0_ZfSzzfN-*<n$ z=e*}HXSSykGx2y-!p|?2&(1%1`cC2}xqW=ZT`rH5&GN8mIc~938h&bVbmih9yC{Nu zM0o;o{;ZM$IOJE<s{ki`67GkFmvM~KFNOghqeqjUqi0A3(4_*=p&;uyevQ_mmnB6i zq^G6afPXCF%J4SdiEY6<{6zdOu>IqSPJk`nY<v~qUB1)wJJk87`~HLv`3K2~jSD!^ zlWJ030`U!X=`5+rRmD?uSc<Somw2!V7*neuPpQeCS_fwwJw<rfqtsMS^+F!0%XlK5 zbRmQm&PX1Ni;2{eJ*7@S(g8OlYr|8vZqBb}i`h!Cw8HJ?u1q9o(G1I3VTQI?tQcC! zF6x?Xl~(!P=7WSy@}HY$<9BdTCy5{_l<@pxqZ<+QDcS^@^CQB4JODQkMl#Y;nDx4{ z4!AGWk;$7Fuc^B%k*6o?1X+IVhW1!0RaKXfsay-=*1%@bqn_YOFdAZCxDkv*MQ&pg zs^PVm+u()Kqo*V*tw?TcDavjFiiw0tm7b9-a$52z{tRUwV{2Tr?n<3Nv1B2PMR7sp z;cAc8_TV|}N5Ry!p&83D+&#UFtZ8N4MI$?B^L#4C2Q!f{JCEG+$M|gOaJ-Sdfd`fs zFv&kk4IT~@(=`}7hmk<BjEim%pLXr?2@Dop)3$;HGnQ>s-7)6GnayKmF2e7p+WUg! zvbZeM&^5<iHrz$iS_oo$g_@Wf$asr9(b6{dEw(vB2;zR4AVFe;LQGa5ik?CeKp+MQ zJW;d+Awd376o01W8Gv8;js4$2g%{G@@Hbyi|3MV+S>_WUNsYI+4umQ=l~sAZ)qo_w z+j{R&;C9;}tn(k*j;fnjG3=)v-vYSGpNu!FmoadJ@3aT8b<unUA=sz!T1O6E@xSl5 z0%7Ke#O!XhNT2dqXE%VuZ+7*n90NN4rYqIdF=1Qt=EBNDwGL|jy{^{*-s3Oy^uZQ4 zd%E!NcCBYfy@VZQ{#8$BclLiBLMLr*cZxP|mJDYOwhyFRve<xcR2XEWDtO?eUBZ7m zFhylHg-N`?mwJa9t^*1i!?PswOTBCG7JtzDEZpKp`bHXakk4fTs%chn+0Zl|?SJvO zD_T7P;wc2Q%<Qtk+*Ni~#9k91)M7#*HX}f=XM!;kB-j}N^ZZu-;OQc|&Hw@hC7x)f zl*VY7MrbqbLkkgz#%U{Up!+cs$6N<Zu;;Nnmt*gXDK`*;aLHa+z?Z|s>tJID1>Tdp lpS>oMvg0x){?<Wc!EjGvB|g^MqOih82hM@aw+H&5<zJg=V_N_K diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/download.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/download.cpython-38.pyc deleted file mode 100644 index 0659707786145c2a4ac1e2367be571c9bfbbb794..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25929 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 ZA4K~7^kd_>=!tFpY5F10^EP=;{cnN7h}{4H diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/exceptions.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/exceptions.cpython-38.pyc index 6a344c87a51b39dcbef8634b50e1f690442ab7d4..37cf1c6e4fb876009b2c5b11ecfa770b9b760226 100644 GIT binary patch delta 5982 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 delta 4220 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/index.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/index.cpython-38.pyc deleted file mode 100644 index 2c8ac19704029ca21fc290676bda8bf912db6755..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37730 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 OZ+1KW<+FRT_WuH*(;vhD diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/legacy_resolve.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/legacy_resolve.cpython-38.pyc deleted file mode 100644 index 6403e828895e105f439f0cf93e7dc22557a38e2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10549 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 O-sJyU*;KwRzxuzJU*CWL diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/locations.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/locations.cpython-38.pyc index e8d9ca7442c835e8b16b04c374dd80e4b378c279..2a46b8ab7465dea3b223e08f800381f3dcb8b755 100644 GIT binary patch literal 4521 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 J^s4jC{{VaU47dOQ delta 1719 zcmaJ?&2Jk;6rY*>^xEER9LKQ}H*INJ;<QdBKB`ixRwbd((z=LJ+FAnFcs9xUW4+97 zN?eU)i4??vqEvg~=&d+VI8Y&R<p8%z9J#Exqy7a*MQV8Cgz|B~qkVes_vU@foA<`| z4?ND9SJG(%!SA=558nHJ;;vc55AGhmA*DO!-OuL-c7}aLF*Vwgom@57nW|28^3{B& zP%U((tJ4_S=5U54BU~-g6iweo)jhU8oTVlpdu?U7FG9op5u#%)!hW@l;WH7c?!A?= z)!_l)=B^^QC?oq|%h<w9#z-t%Z62!5T}LjthU|d_ifgvie0Df*Yt0h1B2r!0mFGs% z;gNL2UWo7(_V4{;@A$v=3hA(W{{Qt5L!lDQd`t?6PPE7o2!C%BSfbexIN2fsqq*t= zou+wOxQ(l2DqTjUnJ`b-eBJY?!~7DCwX5eU%a^WR1~zl?`kU8lORvAW^hWKiE0xN* z%4^}zWY4@3OK03(tXy%Ot{cnCP9uor3yvSe`Xw&_tlo|#&+)>B{9{3fONvR?k7chO zti^J(>$tJx_x$jba_rE3#HL}x<Kstzj&~Gn%8u&?^>(}b+}aE48_##^0u1-c#na}h z9n^f*sCmp@aW;gRp8<lfiZc?yIcyRclWjv~ML=WCTW5CLdA}-qJ+BvsKPi_72~aG- z=YNI~f(9XN)WLlfBM0?0F0*}5MR^rFxUai1U^-Pe0x7{0L&Eh4W5iXS*u;H<8$&6A zi|0mDrYhB_euwmvJV_I+gnuJYKEfQc4X&__K%vG^<(Mmjh-_j|5Vi%1El?yuLAbJu zWA6)|Y-&7N(>V6OgneJr6i7N(yzfAxk9gw!0DJ=Y1ed&rz#G8BH%y9zg48m4H`h-E zX-Fo`Q&VV@aE+%<q7Mc!H6d@4su6Cf&=7g94M{KtE-dlUu{%VZF&N)Op#3z+G$)4H zV6v%Gi;mL_a5<Ww6QZT25J!>1HJUw%xFk;f)M9F62fk^xfFc}WI$1#dbdZ@9?zqI$ zbdn~7lL#^!InbaJbK!k$=~&WlFvkmOb++o?N|(!Sx4iD#tlU^xjb*pqv14twMc#%M zRU6E%2X-Z#)nCDT!n!_lB38X#u-0`SNuw@Uv+LAm{v)_>R4T+Kg+5&moVLFxICem6 zQrA5SUcztm7p+)b>9S58I$DHf*)W|rGmt6tI9q_dO!PCe1Q{1ZbRe4m5^Fahj2H;R z_u5WCnFBx`G$k`mh*&j|Jv%N8UJ~Slu+kmB+lJVbWd*jAj^9|b;h<yoM!@Pd>I}eG z)MMArh{ZI<PAs+TUYr(_Rdc(wotR=WMpMORL<H;UiEBH4F9Pbn0|colBE!r8#X2^K z4$H(TIgj%=1&9h%Ed6B=vIz_4hyY>8U|E>_q3Z_7<~GRNGEo6Fp6CiY53Wnf*-GVX zrL-76G-nE;Ua{8o7e{Y^?!k#gm03A_VqTo8PQZ*W)*Lsm8N3~fqw8Tx`0ZFhZ*)6g z!&DIVVJ-Y+Z0_LbMNxyE=eVm(Of(b!1S}~?N{}>=@U*ob7sD0nljPs`lnsBkW<M0^ z?bPQ#mC{dkx^%s5pAx;|UjQO%qr>6<T2KwLQxj3MqHIWd)=(_a6Db8HNkI`Tc!x}& P76DG4$Fc-NiO}|+x-7iR diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/pep425tags.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/pep425tags.cpython-38.pyc deleted file mode 100644 index d8c8745f39193f99c72417110dad99b126a08359..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8337 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 J@Spkme*;Mc0;d1~ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/pyproject.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/pyproject.cpython-38.pyc index ad861efa1c27c6df534f78b4c8f5902bfeb02c27..ffa82a0355f134130713d4c088597c7900ba90ac 100644 GIT binary patch delta 1399 zcmZ8gTW{P%6!zH8uGjWnvYRUkl~bVU(qvavg;XJ^AXEZgcp&0ZOO@s9Om@8)+uNCO z)D2#xBD^9s@*hb4K&2`YLi_`s;MwXMFYpA<NF<!`CTPWsd}hv>GvCbl{LQPCA6~!n zMYU=w(ApP2dB3kI%5Tz{Z6$C%fRDd8xpVgjDOkZeEr*6{gcY|^_;b_@E!PTd*Dm}L zt%fzXR?N$^9yZ(tQb>b6gS`fw51Vc?Y`Lv)!Cioy3O2t}+(m3*8^$G4!c|<ub=<)7 zef?N<mvIxfU}XiXJFe1R_(R^Vjq<v`%VU}d;sxO-X5ur5nUNn7ERqo=Z8g_;@HE#& z98z$apGF5h4e;mWNfIy;l1Sv%jC1m8v!vzPhtW7&L_dBq4~P8yxI2hL(q-c$83tX> zdR^>C0iiuOj_}UY@nQFXL<e0O>~=?EF^Hpko%>xL2(mTud;5N$@a!*i3oT{K>b;Mv z0GaDF;3C(2O5wU%ygOv_q^W7jgt`}SPbPWsp2r1~K`wuSqM4|1!IrZV^%zyNMeUuV z)g+SV5bW_dVLjqusH`VqHfF1^;s4OB(BCKCXgp%^5YoJnF9xqkctgUgHLZziDqDwn z-rP<Cig(6bknkZ9en5F{uqkysFYn4zqq{ht>kUY6Kewj=TtN1833t`%FiL@a1RsBK z{!-gSN9IH2@%F?zw1u5o#|SB3DN#pPM0MYMj@S?>vI`@v3@fRIo2Ql3IzzbeJ=Faz zdZa|^*UEGBWHU8R%eZ`oCU!Av^_4SqQtc~~T54l`-vF#rY)x#bu)aE}iCSu=c3QL2 z>ao59O7ge0^ZMM+Ds`a!N1Y>S;f{!%sjeI`AkI~N&K`?H=k}EcKUoago2J}8+Zds~ z2o8wEkejdgc32#X&iOCpE-JG(fDd*%Gb<Ng9=^Y^E7{)S1>K!%nm3$Y90Bzacl^i+ zrt)>JR;7O5b-r0=lf!HBr`M^o6$!nX&6`W}b1((T#XiopJ`v2w?wf0i%QB%Xjnoyp z38r1oT=Q_lnn7o8%EepKyd}+yPP0GF73*yX@@HU_wXA79Iw~1RMK)@H)sd>gcd7oP zU)D?$qB=6GIx<xD0P@?bx#@X(iAWgnJf=d3ZAnwy{07W&s~1xW8V%xzGp&e>f>FnV z=Z0g(q{5gi&b@gZUWa&R`s#wHe@&vKiBHQcXD_WA$jE-RoU|elOJY2NR3_!gENN_M z3U=fpD2OR8JX3qYLh(?I_re$_lsrI?%Oy{?Y9QHdwSgL{4Wo`0G{Z0~AVVqoWohnT Dmt|>g delta 778 zcmY*X&2H2%5RRQ}l8v3+rL?e=Qb3hjt=dxBQVAqf6(PZe8$W^^h_-9*ZfLSeouulb z?TH={qT~hO4Uj4!UV#HIU?Dhg;KCDtR51=57Dt}3$KQ;<eB%!nzBCsfx~`+a__6o? z>DD<-`>r<Q1H)zuW_ozExcWG<JPT<|V@7C4Rj*pEE1?q+k06Z`(T6iLq><~nQO&DG zb*~;ZyawPbW*=(aDOP0;_z6ZB1%I01`&!FA`Z`_1(oBX~9EDO(gZ*LyExCr&Zw-dB z@*qz_Ui8q%xjIn!b$um^l9eP#mV-f>wZm|Et$!`wUys`=SoH8bnk-)7^}7Vn(g=ez zlRCg!Nb2$SGogz7H4O!*`$6g}kRNybG!rVAnqV~DL5&kJRoMCqM2eUC#w<;FmM4BP z^jRRpS-^}}D}L(D)uu|fRXVQe6R3v8MOb$X75O(@@Ku<%VWy9cca0^qX1}$V^$s17 zo_0V-gc&>bYb5S5azK=3Jq%H2L`Jl$gJKiy&-i%3{DhBrbskY^3%;8Nf~Vqg@y0p1 z+M?nN6fYS{Gf2BZ$R!S9X~YR12p!Hqn7GZP-s7356fT`Hry$yLi%t6cytUo#?C=4T zl}?{`cK-XxZ?s9~6!R_^ZMwkjlRFg$8OU)BWMgqdm6?=|?|1Vo7u@%SdPQPEnUd8E ztR#V6UGewel30|4gi-u<XHlh?u3ZY1{?g2bNigUMOJyoag;GtZ7b_ImQrYspF@j}x h%f{L_qnPC(-$Z~-)y)*!2tM4v6j5xTrf%Cd`2(HBtQi0R diff --git a/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/wheel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/__pycache__/wheel.cpython-38.pyc deleted file mode 100644 index 63cc4e0750d94d9e58f5310748820ffa3090bfb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27490 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/build_env.py b/venv/lib/python3.8/site-packages/pip/_internal/build_env.py index a060cee..28d1ad6 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/build_env.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/build_env.py @@ -12,14 +12,15 @@ from sysconfig import get_paths from pip._vendor.pkg_resources import Requirement, VersionConflict, WorkingSet from pip import __file__ as pip_location -from pip._internal.utils.misc import call_subprocess -from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.cli.spinners import open_spinner +from pip._internal.utils.subprocess import call_subprocess +from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.ui import open_spinner if MYPY_CHECK_RUNNING: - from typing import Tuple, Set, Iterable, Optional, List - from pip._internal.index import PackageFinder + from types import TracebackType + from typing import Tuple, Set, Iterable, Optional, List, Type + from pip._internal.index.package_finder import PackageFinder logger = logging.getLogger(__name__) @@ -50,11 +51,12 @@ class BuildEnvironment(object): def __init__(self): # type: () -> None - self._temp_dir = TempDirectory(kind="build-env") - self._temp_dir.create() + temp_dir = TempDirectory( + kind=tempdir_kinds.BUILD_ENV, globally_managed=True + ) self._prefixes = OrderedDict(( - (name, _Prefix(os.path.join(self._temp_dir.path, name))) + (name, _Prefix(os.path.join(temp_dir.path, name))) for name in ('normal', 'overlay') )) @@ -73,7 +75,7 @@ class BuildEnvironment(object): get_python_lib(plat_specific=True), ) } - self._site_dir = os.path.join(self._temp_dir.path, 'site') + self._site_dir = os.path.join(temp_dir.path, 'site') if not os.path.exists(self._site_dir): os.mkdir(self._site_dir) with open(os.path.join(self._site_dir, 'sitecustomize.py'), 'w') as fp: @@ -105,6 +107,7 @@ class BuildEnvironment(object): ).format(system_sites=system_sites, lib_dirs=self._lib_dirs)) def __enter__(self): + # type: () -> None self._save_env = { name: os.environ.get(name, None) for name in ('PATH', 'PYTHONNOUSERSITE', 'PYTHONPATH') @@ -123,17 +126,19 @@ class BuildEnvironment(object): 'PYTHONPATH': os.pathsep.join(pythonpath), }) - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__( + self, + exc_type, # type: Optional[Type[BaseException]] + exc_val, # type: Optional[BaseException] + exc_tb # type: Optional[TracebackType] + ): + # type: (...) -> None for varname, old_value in self._save_env.items(): if old_value is None: os.environ.pop(varname, None) else: os.environ[varname] = old_value - def cleanup(self): - # type: () -> None - self._temp_dir.cleanup() - def check_requirements(self, reqs): # type: (Iterable[str]) -> Tuple[Set[Tuple[str, str]], Set[str]] """Return 2 sets: @@ -158,7 +163,7 @@ class BuildEnvironment(object): finder, # type: PackageFinder requirements, # type: Iterable[str] prefix_as_string, # type: str - message # type: Optional[str] + message # type: str ): # type: (...) -> None prefix = self._prefixes[prefix_as_string] @@ -192,6 +197,8 @@ class BuildEnvironment(object): args.extend(['--trusted-host', host]) if finder.allow_all_prereleases: args.append('--pre') + if finder.prefer_binary: + args.append('--prefer-binary') args.append('--') args.extend(requirements) with open_spinner(message) as spinner: @@ -203,16 +210,32 @@ class NoOpBuildEnvironment(BuildEnvironment): """ def __init__(self): + # type: () -> None pass def __enter__(self): + # type: () -> None pass - def __exit__(self, exc_type, exc_val, exc_tb): + def __exit__( + self, + exc_type, # type: Optional[Type[BaseException]] + exc_val, # type: Optional[BaseException] + exc_tb # type: Optional[TracebackType] + ): + # type: (...) -> None pass def cleanup(self): + # type: () -> None pass - def install_requirements(self, finder, requirements, prefix, message): + def install_requirements( + self, + finder, # type: PackageFinder + requirements, # type: Iterable[str] + prefix_as_string, # type: str + message # type: str + ): + # type: (...) -> None raise NotImplementedError() diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cache.py b/venv/lib/python3.8/site-packages/pip/_internal/cache.py index 894624c..07db948 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/cache.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/cache.py @@ -1,27 +1,38 @@ """Cache Management """ -import errno import hashlib +import json import logging import os +from pip._vendor.packaging.tags import interpreter_name, interpreter_version from pip._vendor.packaging.utils import canonicalize_name +from pip._internal.exceptions import InvalidWheelFilename from pip._internal.models.link import Link -from pip._internal.utils.compat import expanduser -from pip._internal.utils.misc import path_to_url -from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.models.wheel import Wheel +from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.wheel import InvalidWheelFilename, Wheel +from pip._internal.utils.urls import path_to_url if MYPY_CHECK_RUNNING: - from typing import Optional, Set, List, Any - from pip._internal.index import FormatControl + from typing import Optional, Set, List, Any, Dict + + from pip._vendor.packaging.tags import Tag + + from pip._internal.models.format_control import FormatControl logger = logging.getLogger(__name__) +def _hash_dict(d): + # type: (Dict[str, str]) -> str + """Return a stable sha224 of a dictionary.""" + s = json.dumps(d, sort_keys=True, separators=(",", ":"), ensure_ascii=True) + return hashlib.sha224(s.encode("ascii")).hexdigest() + + class Cache(object): """An abstract class - provides cache directories for data from links @@ -36,16 +47,19 @@ class Cache(object): def __init__(self, cache_dir, format_control, allowed_formats): # type: (str, FormatControl, Set[str]) -> None super(Cache, self).__init__() - self.cache_dir = expanduser(cache_dir) if cache_dir else None + assert not cache_dir or os.path.isabs(cache_dir) + self.cache_dir = cache_dir or None self.format_control = format_control self.allowed_formats = allowed_formats _valid_formats = {"source", "binary"} assert self.allowed_formats.union(_valid_formats) == _valid_formats - def _get_cache_path_parts(self, link): + def _get_cache_path_parts_legacy(self, link): # type: (Link) -> List[str] """Get parts of part that must be os.path.joined with cache_dir + + Legacy cache key (pip < 20) for compatibility with older caches. """ # We want to generate an url to use as our cache key, we don't want to @@ -69,30 +83,72 @@ class Cache(object): return parts - def _get_candidates(self, link, package_name): - # type: (Link, Optional[str]) -> List[Any] + def _get_cache_path_parts(self, link): + # type: (Link) -> List[str] + """Get parts of part that must be os.path.joined with cache_dir + """ + + # We want to generate an url to use as our cache key, we don't want to + # just re-use the URL because it might have other items in the fragment + # and we don't care about those. + key_parts = {"url": link.url_without_fragment} + if link.hash_name is not None and link.hash is not None: + key_parts[link.hash_name] = link.hash + if link.subdirectory_fragment: + key_parts["subdirectory"] = link.subdirectory_fragment + + # Include interpreter name, major and minor version in cache key + # to cope with ill-behaved sdists that build a different wheel + # depending on the python version their setup.py is being run on, + # and don't encode the difference in compatibility tags. + # https://github.com/pypa/pip/issues/7296 + key_parts["interpreter_name"] = interpreter_name() + key_parts["interpreter_version"] = interpreter_version() + + # Encode our key url with sha224, we'll use this because it has similar + # security properties to sha256, but with a shorter total output (and + # thus less secure). However the differences don't make a lot of + # difference for our use case here. + hashed = _hash_dict(key_parts) + + # We want to nest the directories some to prevent having a ton of top + # level directories where we might run out of sub directories on some + # FS. + parts = [hashed[:2], hashed[2:4], hashed[4:6], hashed[6:]] + + return parts + + def _get_candidates(self, link, canonical_package_name): + # type: (Link, str) -> List[Any] can_not_cache = ( not self.cache_dir or - not package_name or + not canonical_package_name or not link ) if can_not_cache: return [] - canonical_name = canonicalize_name(package_name) formats = self.format_control.get_allowed_formats( - canonical_name + canonical_package_name ) if not self.allowed_formats.intersection(formats): return [] - root = self.get_path_for_link(link) - try: - return os.listdir(root) - except OSError as err: - if err.errno in {errno.ENOENT, errno.ENOTDIR}: - return [] - raise + candidates = [] + path = self.get_path_for_link(link) + if os.path.isdir(path): + for candidate in os.listdir(path): + candidates.append((candidate, path)) + # TODO remove legacy path lookup in pip>=21 + legacy_path = self.get_path_for_link_legacy(link) + if os.path.isdir(legacy_path): + for candidate in os.listdir(legacy_path): + candidates.append((candidate, legacy_path)) + return candidates + + def get_path_for_link_legacy(self, link): + # type: (Link) -> str + raise NotImplementedError() def get_path_for_link(self, link): # type: (Link) -> str @@ -100,24 +156,18 @@ class Cache(object): """ raise NotImplementedError() - def get(self, link, package_name): - # type: (Link, Optional[str]) -> Link + def get( + self, + link, # type: Link + package_name, # type: Optional[str] + supported_tags, # type: List[Tag] + ): + # type: (...) -> Link """Returns a link to a cached item if it exists, otherwise returns the passed link. """ raise NotImplementedError() - def _link_for_candidate(self, link, candidate): - # type: (Link, str) -> Link - root = self.get_path_for_link(link) - path = os.path.join(root, candidate) - - return Link(path_to_url(path)) - - def cleanup(self): - # type: () -> None - pass - class SimpleWheelCache(Cache): """A cache of wheels for future installs. @@ -129,6 +179,12 @@ class SimpleWheelCache(Cache): cache_dir, format_control, {"binary"} ) + def get_path_for_link_legacy(self, link): + # type: (Link) -> str + parts = self._get_cache_path_parts_legacy(link) + assert self.cache_dir + return os.path.join(self.cache_dir, "wheels", *parts) + def get_path_for_link(self, link): # type: (Link) -> str """Return a directory to store cached wheels for link @@ -146,28 +202,53 @@ class SimpleWheelCache(Cache): :param link: The link of the sdist for which this will cache wheels. """ parts = self._get_cache_path_parts(link) - + assert self.cache_dir # Store wheels within the root cache_dir return os.path.join(self.cache_dir, "wheels", *parts) - def get(self, link, package_name): - # type: (Link, Optional[str]) -> Link + def get( + self, + link, # type: Link + package_name, # type: Optional[str] + supported_tags, # type: List[Tag] + ): + # type: (...) -> Link candidates = [] - for wheel_name in self._get_candidates(link, package_name): + if not package_name: + return link + + canonical_package_name = canonicalize_name(package_name) + for wheel_name, wheel_dir in self._get_candidates( + link, canonical_package_name + ): try: wheel = Wheel(wheel_name) except InvalidWheelFilename: continue - if not wheel.supported(): + if canonicalize_name(wheel.name) != canonical_package_name: + logger.debug( + "Ignoring cached wheel %s for %s as it " + "does not match the expected distribution name %s.", + wheel_name, link, package_name, + ) + continue + if not wheel.supported(supported_tags): # Built for a different python/arch/etc continue - candidates.append((wheel.support_index_min(), wheel_name)) + candidates.append( + ( + wheel.support_index_min(supported_tags), + wheel_name, + wheel_dir, + ) + ) if not candidates: return link - return self._link_for_candidate(link, min(candidates)[1]) + _, wheel_name, wheel_dir = min(candidates) + return Link(path_to_url(os.path.join(wheel_dir, wheel_name))) class EphemWheelCache(SimpleWheelCache): @@ -176,16 +257,24 @@ class EphemWheelCache(SimpleWheelCache): def __init__(self, format_control): # type: (FormatControl) -> None - self._temp_dir = TempDirectory(kind="ephem-wheel-cache") - self._temp_dir.create() + self._temp_dir = TempDirectory( + kind=tempdir_kinds.EPHEM_WHEEL_CACHE, + globally_managed=True, + ) super(EphemWheelCache, self).__init__( self._temp_dir.path, format_control ) - def cleanup(self): - # type: () -> None - self._temp_dir.cleanup() + +class CacheEntry(object): + def __init__( + self, + link, # type: Link + persistent, # type: bool + ): + self.link = link + self.persistent = persistent class WheelCache(Cache): @@ -203,6 +292,10 @@ class WheelCache(Cache): self._wheel_cache = SimpleWheelCache(cache_dir, format_control) self._ephem_cache = EphemWheelCache(format_control) + def get_path_for_link_legacy(self, link): + # type: (Link) -> str + return self._wheel_cache.get_path_for_link_legacy(link) + def get_path_for_link(self, link): # type: (Link) -> str return self._wheel_cache.get_path_for_link(link) @@ -211,14 +304,43 @@ class WheelCache(Cache): # type: (Link) -> str return self._ephem_cache.get_path_for_link(link) - def get(self, link, package_name): - # type: (Link, Optional[str]) -> Link - retval = self._wheel_cache.get(link, package_name) - if retval is link: - retval = self._ephem_cache.get(link, package_name) - return retval + def get( + self, + link, # type: Link + package_name, # type: Optional[str] + supported_tags, # type: List[Tag] + ): + # type: (...) -> Link + cache_entry = self.get_cache_entry(link, package_name, supported_tags) + if cache_entry is None: + return link + return cache_entry.link - def cleanup(self): - # type: () -> None - self._wheel_cache.cleanup() - self._ephem_cache.cleanup() + def get_cache_entry( + self, + link, # type: Link + package_name, # type: Optional[str] + supported_tags, # type: List[Tag] + ): + # type: (...) -> Optional[CacheEntry] + """Returns a CacheEntry with a link to a cached item if it exists or + None. The cache entry indicates if the item was found in the persistent + or ephemeral cache. + """ + retval = self._wheel_cache.get( + link=link, + package_name=package_name, + supported_tags=supported_tags, + ) + if retval is not link: + return CacheEntry(retval, persistent=True) + + retval = self._ephem_cache.get( + link=link, + package_name=package_name, + supported_tags=supported_tags, + ) + if retval is not link: + return CacheEntry(retval, persistent=False) + + return None diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-38.pyc index 18c8076bc74763a7befa7ec190c18fc14e3a6e7e..a978686ce7e66f8e76052a2e7374c67ff6dd71b1 100644 GIT binary patch delta 91 zcmaFK*vG^Z%FD~e00f%<cEwNR>2prd&&bbB)i0_nEzQc*FD^>fPf5(nOwCEoFDgkb t)~l$j(l1NRE7Q-(Owuo?EXl~vGuE@vFU~AU)h$R&&Q45EEuOf;5CC~FAb|h? delta 54 zcmeBUddbKW%FD~e00hs=HpETj>65e8FUc*?FUTy=&CDw<NzBR7HOeq4tuW3{1PM;O GYX|_nw-OBi diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-38.pyc index c6cdac84329d32d5c9f1b01651273fa5ea0fbce0..2b18acf4a4ecbef61b307a10e9f8bec0194dbf2d 100644 GIT binary patch delta 2369 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 delta 2396 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 IubIQY0tTiF_W%F@ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-38.pyc index 6d6dd7641a357d3d12d30bf77a0677562206b0f8..01eb324ca788456c444fcd6a1ace061f9afadc36 100644 GIT binary patch literal 6700 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 literal 8266 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 al1xvQ6BKTN$itx+-b*P(wdW_&^#20q0wL7^ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-38.pyc index ef2288417c2b18641c4512b2d5660ac5ba4d4a71..2731b6e3b0d8311b5f5885cb45069a2334da8e87 100644 GIT binary patch delta 7462 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 AdjJ3c delta 6273 zcma)AdsrODk)N4emStHGPa!~$1%$*R7W70CdJ7Ojh=+t8)=Ji9*lKoH>`Og^1Q=x< zTS;^m%a+n{65DbNa^h!fImU^V#CGDmoH!5ra+lm?le^qq;!ASpvlAz|KcsxpRrO#% z$j%+}ZB5Uws;jEItE;Oy`>^`h1+{K}PL4~#zu%mA=IEye6y;a+G4rn&Kepn}cqHR| z-B5O{&|j!3pn@xU{!()a8+lPrtioR*!Te}ttjb@dDy-t1%FB>j5M3Or_E*Q2_?N_% z`j^IP{53JJ-z%jHqpn!3zc#kazf67?MeAZdzYlxc#_CzaxawaH#W44@;$HzJFc04= z;g3)XWv5mDD)<x3htvXWu4Y-x4GUorc<`x!%Cipt8i`fGVyK34SOQBCYm`_Gc%hb1 zmW^npf2~B9K^^#@9vyCw=sJlmhZVB_O4)zC#8$y-Sc7OI*-81EB)AsV!Ft)fNp{~L z(G9Q>HnEMYYHZWEa;FNLVGC>>+iZQ0t0f9-!{2svVvCe-h8Adr9nc0lp&ik!65RzI zQ|>za+a$IdI-v`?A=LwWaAeyhxEFe1AMA$%5^I*&LAV7DfgcXT5x5nOo^|?LBp!ed zkOG_o>fZ`F^x^dGkh~xO^4fqwKl0in7J@KhHbf(E3|-qP(Sa01AqH_su##i#kc8uC zU>9&OP+5l*F=0?n;R!i~yWu1ZA+Hnu48t&ji`NCW!6+i#a0)(%?;c3O?fBjUAA&pZ zy;o|v6Hdd2;Un--IKv9>RN!yWQkK6LQhy5{L!o_e7o5fSez+U%!S?|;2j}s95Izn9 z-?vC5pMZPuvB4*?v%`M~J_Vmfo*(Xm`|*8P$~*uU@Oh9OrqQxo_zW)FLul%V<c`5O zJ~p^0HQdUwQW$s-!)Nia!RI7+6dr*`QC$EYgU9jx0eAwQ#J4ULd>)=+1#kwQhD+!| zA3OtJKwePto`t8-a1bWoIpl%Fz6f7}=jHremT|=-`epbEd=*}R7a?^9Ucyju`uip0 zYw&dxei<V(!yl5!H{hG_E%-KkM^1kjUV-nT!HDF24_-xS8+>2#j!EnXh&{+6IQDG# zA+Ga)M1KUY!RzpM@MHLUbS)~ee}JFB>nQ|(D#4fp|55t-Pw+EzATE)#M1C%jghYM; z|17b8k!F(;`z8D<{2NrGQQEx6;osp`=q8uEU&9;d5{LhQ-@tFtB}1aWga1S=sdD%) zsm7Gxn;4(3!+*>155imUHYzy*zh`S$BU{VXu_m^GZDrfocGk>VSS#DXx>+0B$@&<u zBwHUUf<Ii){3qcZwu^PJ-K;ZYm&g#<dKK^g=q;+ExQwvQ8F&&&Gm@C-a5Spo_Dm+; z$?R}v_cEOa!@a>ol8Gi~#g@m_^gNW+gJvM98^*~5hd@71!~%mn>Q&PPorii31)6uZ zHg^Q}?(gbq?`lIdYx}mnfqjR1T6-ssJD*akmSXa~vZ=w0B^#2Fq%RUTOg$R)tqiXo z99oso2^9UV)%hf6IFKk=Zna3|-iaq&cC~6T0%^DOHXaD^#9)$FBg9GEA~oX2*)?jz z#MSIisEZ_ALwzzs%#7<X)`=g6hD1?EmWe;)mWl7?Y*(4c&fQpJcp5xDUnrXB)1yAi zh6TOr<s>Gexd&>Op$fj5$QmT+3{q~SGlPk^$rDk_msP~B5pU);<ZCW9S9PdP)vju) zc8xbr)XlkHQ#XiL@>i{MlLni?OumU)g^^G^!C8QoF%B#qj4*>|5yxff90wAB2=`|2 zWnyK)p6r=Jzq_DZJtUqeXi&SwmZFtvkKjdj6zw55_EP^$VEy`F)Z{%A&f-k1j5uk# zIh<tZc{mXXqM-vM-6OmuHIB4BsheSOprk6_#-(g#jG6igouj}#C1v83l7o3tyH1@Z zd)CkU^=?MrvpI;3l=^(e04_Xd#|I;v#aP@l@FT>A(j~+Q%w*sPGDK}Ds7J*;rRC~g z@nosqJgv8H$}A0!ORGKDdR*lcJ2S#!DiSzHM!x7STcC0gD_c3kf2+H=RCZ7Cv<W$= zNltJ1pDc0tJvrQi^N%`Ck+C81)%k<B%AS%hU9yCTJ^VfnrRT6Alk0&9F7*)YrR}&c zjXacAC{(7OD?BC6E_k+Z2svpR3XVM5-tW;p*b@5}Hi;J(E-1ma#|-P{QUe(nB`jzr z_;8(gXW@#b$1|)InfA*X7Wwsl&hZZ+_mFtHqC7>dpximwpuY_KW#X?Hf5tu}qslQQ zq$0&);FN}MjjtP3jdiAN%#O8)HkN_;*?w9X)mpHC7+1$NRS8*=j^tKs+04vi&QaT_ z1{r6yQ}$6i<|)U>DVGQTQcX#n>oJcpm`rkJ7=d`gnzAO(!7ww!jC;(4$J#kK1q^p` zJc0QIC)LVsajAw>oeZ<M2REu=^1+}PiHD^8jCAKo^c};QtCu}SirQ&A7Lc4&$BZUV zwQ)tQ6T9ozq?Y5rc|H=ame%T*^E>E!#-7B_bk@cYi?g95-+Y|b){dB6(Ug(JF@1mq z44G#G1|{11jnPC<j~binr@DAGxd>_3RDc-XEIvwRKBy=uh2Ksl9MME5#CSRbSl?iX zR}h<4jOR*jkTcz6lr!iv|E5XgAAPq&+C9^s*(1rH?eP*8q9K)Gcg2ybx@3MUxMsK8 zZ7vOSouXZL*!fv;aQ=Gn%SDS8%HVbG?C#yywXL&tq@z>k133K=!xK&zrl|L9-70s` z^nU(->>xKTq+v1$kdBmi+Ec2Y6R%cm5*ZZ>)FDw-5w5zE#`nHaejd4ZQIw09D>sYG z%0&+HlYd;)RUZ65x(XD$kGiTtn!H|FiY7~|ZmapLCeuy^5mWDrvPWd+d&S+0Tf{FG z-!C4h?rdK{)@dFvs2nHs=pg3hYQkm(R$+ingZ>1M>1JT^==mD0huo(&exJx&+EPFv z>UHq@NWrIxxW(xujYmjfIup;d0B(eIhBU+F0qbN#5ra0yY<u~EupWmfqs`YBiR*m$ z+hmQ-FGX|H+GAkbuk&%T3pd*(<M$J}K;!`;4-&a)Sd(TF@#yfRp&!1dp^M`3(gVfv z)O6y$iT3Hi0Ukz``d+cHW+<Zxu_p0gO@*T=o`|z1QL=28SnfU6Jso5ZlLI=DsYvtM zISq;LBq9%zactqCLWX8JD@XAY@jLGV^#OFIUG&t>$&+$YvGk=)Bx>LF<*nKozC616 zv#9ZAa~H|Z=ib8@&D$Gftbkf0E}t(M)lCWj-a1iH_eWJ-DvIl)J~{O&$15;~5dSc~ z=q%^vZ0A3MoOxoRegpP<yS`4X6!RMvst<_`4W%~}7J-KOcoK<I4U5%F;$p+s56fs= zLh3X4C4BLPM7%^~h_w(a(+b+p5c&`iiZ1>%l5`g1Ji!AoBg9F|Ouxj7%gfb8;%Cdt z7d(rskvtsauo+IoeJ2<<B8fOB<^16Z_lmpJM!ArT0GTr0V>L-ZB$kZIVnfF|H_qF{ zk5;~|?wELKRlB-Y&Q%7lBOR?or1~~$?LdM>tTPyc0B#iH1~)gaSy&jrjb=Deio%~B z{+vjxX+A=F(sPo-fk~I~sKP}eb(|FAq|KrBw7F@PX65Ld$x_c6`VEG28%s(<WSDZh zqG`DA<ntFtCVyURZak>&6Q69{vSB}&c;B3N8M%}vrnF3z8dv#ck+*hZf!(SX<hGDA z+=JV?NSs{zPX9C5c?aec8=3e#5xMjf?biB#8Cy8YYJ8<_ICazOpSH1~;LP!mNYRYM z64ZlXEPf;WjCgHbvHF5|V_mIPc1^Evk65(6Qf(L8*VhQGX}x_jW`~L0O`Fw;CpN6G zwOH=irsFZ~8Z=lS$&zbUtetd=e}$Z#4$GUuaM6~sB|n{7-)t=19l19C4eT}I_W4ks z&(g<V7J)4%tw5aia4MO|@SD8mSQiMsjw}xmSvKL`>Qk3YXCrH#$;O;nR}sEe1h#!F zTUxM`PyBgXnOZrb`TQffKA#>vsSg{z!T3ldnRZ)W0r@57G?%G&h}!0w-b%Y-+6G*F zhpNysN|l*yRGq7gtEzHHiEFngqjoc6Ad`nB&pxU`#+bv*7+3o>OKQ}13@f~`%u#zt z8P~>~;?d?)#gCE4`?m4WpseVr6stDG`j%j-8Y@xG@T-1AtMhbW=|cG-?Fj2e7*DlI zngtm^Rn*EOQb7VPybis4TcN4KV54B-Hzt#`U5|zmX$M3?3{SCH=SV>yyxlslVhrz1 z7-L3w3x=#!uGpP;9n<h~i5D|XyXLkz@q*^Q?$G$FXlTUY^N~FNj)2ya)`ehtb>(@{ zGx7UYpDI?hok#(>Y{!_ugH%><^1kL(<zAlc)?AG5;6NaXXDr^N%`l}F%u0jgnUzZl zsOrDYUn4)}v|;VY^{A&?N*S2XYiS~=k{c=R!2?eZiQl%*wW~Y4!{T~-SzbDmia|QQ z7m?r=QN628e6eGW8#f-al<+L^)UE{%`e!N67O(H}I_SVlmkCctv0E0JJcob^3Cyer zMQKNmR5oZvqDFlzVgz}CU>zQBA$6FG7x;S2b|&L-Jz8%G;Z3iIm=3&YqFZ9DqsYxm z5#dxf@^bNoj)kfDB$0*n%x<fabp`@-rw#=884{BDrGZ+_M7l{jBg~?BW9+4N!Q{m; za3aFZK|RXiC-^NS=_hiS$PtpW)3m4U18mr^s^nXV6~sbX;r-MM5jjRAPUJWdPGp40 zZAdUS<#|GvHLDQE&Q=|6)!b+4^Bj@$M5sjM_aebNJ`Y-T7!?%!A`w{yT~Hda*-GD+ zh&)T=#&d{2N7(a3E)$^)%U=+0?JjY=NX?f-Ugx~Sl%Dv@NYXi2qfIA0E9a~wh7%dV zDAVI<8{VY&H>t<Bh)~$4?K0?pK+UYF2$hj2Ug}%`(>qMIYDmtxF_wVAD5E5-7&|eH z?OAS(c9&D0iAAa#PscpjwoXY&HHSK%P|am?<~nm+C9XPo1Sw)$PqEnBb=r2-;S@jb zYR+&Wu8G3#)>S!EhZOCQD-M@4*EP?XV?9=HymBa(6qch`9By&GJCs3^^F>8>u{hV| zEG0Z^wzPH?WgqG(6$g4u@m7x`dr}MHS>pRW4VhO_M-KY2XV237H??byat)7O`TRw@ F_P^&(hZFz+ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-38.pyc index 45e5e3880bee054950564239aa60a1a8c68be070..de56f12b676d67dd6117a8387e040f050801f884 100644 GIT binary patch delta 814 zcmZ8f&1=*^6rag=ca!XHySAmJHEdgH&~BuDVksz!C&7c*Lr|79lWtS<v7Ka#X%ht7 zlLyN(7s1P}p1j$U=pW!sy$3uC-n=SQCo4kn!F%)GZ|2Q=?>F<S`o5;zSCkT<q91=~ zP4|=;_@a0A#u@|&BEc*BvMCRJ(NlcYRQ-xs8OD-V^=oDg0;h&kdUnJc^~cOHzi!s) zehHP^jCl&lsB{3#aipL!T_<`U4<SR=-~xFDpQ;?KDp0*iHHyg;b9WvIZHPo99e}vp zmj~b$*oPA!W6?-oN!bBRVM`^4%+Zrsn$rd;csTxm$zaAHumv_i4EMov*kiW2dq9V~ z+FoG!&b8$$nYL$#zHbGn<pvvJGwRX+Cz;OV!bXUFE6xQkv@I{v*_>&f$7A&RTt1oe z2H+_Q{<MwF(05i1oOHWet`T9|Kvv*7o*m-YiJFg-U1P@yb_~y5H#$kY83q@cSB=Px zou!UtKeF0RL|(H?%5pLFkOD^dO}?_{qzW!VJVI*RJe0^~?vBP6eeg8bk8*A+bc4K% zoXEy*Cw9X?=g3QL<}^N2q!r!$HPeNsP%}w2YLM^T%v^~PjwMcJY)G+xB2lNPFnoZ| zWRXvex3QdZ`!M4XM;Ye^unjXI<?*Xj=&OjQ7(ajm2tiyyLcdDB@Ds2`zVR0uds$<* z?pw*aqa|Ti^BpUQwIRxCOPW546|yR<>3EzL%mu5{aRP)z8sLQ?f*n8Hadau?EZmOp zB6%lVum3lcN>8qkve-~%$iXV3vN9|&`XpHqx5<$>4Mp-voE3_>D2+cv?Nafzb0JPT qZqUZ%0+$O!Y_%-UYqf?n;o{m8{7sSD(tM4pLK#wJXdzZ&rMW*}NXJY7 delta 783 zcmZ8eF>ljA6ux(M&KD<klHw**K;>2mC@P_-6d^Gn5R3>UP#G-1a(l)E;>10>fd&VV z(j7&&BGisZ3^1}Xva$LPbm14Y3+Gfqh_l}3_ddV-{O-H&wd1O>VHi4+>u~t>DNK!X z@Nv3w%Lz+P2@nHDdgah?j9ISr%&_8A!m3l9)wEX&=bSk}{v3ZVdyBnOq2*ZNyfZJq z>#P)Dr_Rbu-$PD=8LTAVr>8$YfFd41%gl_xPuzGX3_afU#SkWDK@LJ>+?Ej!g@*5+ zPf8OsRu~C@X^ifnRJnsD&_H9A75B@jdH^Z7h8W>*TW9620Hx@O^%##~j2TKH#m{gZ zP4Tw+5Vc`MTb;FQvE7P4qqdUaOP4d~X7GYH<klG+-B?Y+Xf^6aoo+u)yk4)f_I!Qk z^_78_lj2b680-0Tssth*v7}z4CeKT*iw(62MKMzEs+uIkFV%Wi$cmB2W1qV(UuEPZ z&1m5F-9ePZS#4_|4d}DKM#Q|8YyF*wpUF#8!h($0mVgKb3~C<7gz7*sRZP$oq7bm4 zjJF_fI$0G&Ws;9KGxev~ETk)666xFo#s#LPY8?eICTW3xO3A*#3TdH^4ggSMGO}M0 z25CT5w8;8$D_$O1p|`u~+q;7uJM_JNV$WE`?%3@bH^m$BsF@Kjiu^v~`Hy*1LPoeB z4u*c4W~#@7m|qY_<firC5i7Fuy11t;o4P!kiA|*pI&LqBx7s%5n)t0P0u?2?NQ$|z zE>@|1wKS7YcB5`T;N_e*az=Aqd3CNk^Nr`q{}|d3d$d_oEU90WZmCdJs6v<i0I}Vy AGynhq diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/parser.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/parser.cpython-38.pyc index 92951e1b944aeb70df778ceb39e065f76b5a5a20..ced6be7ec64669040dd0ea0e267983ba76c1127b 100644 GIT binary patch delta 1812 zcmZuxUu;uV7{BM<+xw^6x^?YZw{Gh?aLb*#;{M1o5Qal^Q|A~i8ZeBmy+CKzmUGW4 z>spBNU?4g)pCSGUNoS&w2Or4v#TTDUOngvd;=>IO_=52bd;|i1-yJftc$4$H-#Opk zbG|>T2fjWKm~CkAOZZv$zMnH5zZys?<42Px3yXG=FE1@EWRnh0Co`#h*3P91T-Z+k z>E&{=WamrCTy{QLToxw_`N95?q>~l)Q^i#Jt<(wIfg?(SwLw+c8&}ZyI4+0WRHT|z zVQcJ=bcIb>%#F-JTy25-$}mg7usYmx+t;;wrMl;~{A5>JMTP%94GCJFr896*of#Ar zwxAV{BI-3`O{)4TYK>LonpyGDehu9)DWlZ<6_p%XYWXI#_<n>tz7bXjL)y%wcD%qB zQ^Hjj3fa7+@en%TF$7m%ET#DIMd50NqHye@tJ0tMkU-=iM2Tue*bYBw?P^#q_rX3j z40p9z7Ka&q7uyA^`uH{-MZCb<k;pK70;$G?TvO;NGV+?d#^4`)HLz0k-<G?&ER|a* z2<MII;208)fgt%*)^uN$VXQs^cZ~(3rdMRtmmzNsgr7!%vc6Is^`i|Q$DL)sw`O<K z0Fr!=V2HqiKh1q?0=D@}7~yCBVRi(5^<QIY_@-_=v5WL%*XI;-S;6~gr+Sa#s=_`k z_=^y%4>!I*hP<nj@p%}kAJ97JtP^teBfII2-lOmxMC~Maj$l857tiJkdX#6&L~azW z*SF}V(QN44gj>Om_11<#X7b07hv|714h2SA+sMqO1yA`kJj=sZfw8eyh&x5_D#0`X zaUapx^mz~&CvZ7bX$Dg@eh|HeVYKl&+YYg&{j3DXnto%i!$5G9orT5V$je(C96?Rj zDDpzl=3<#2!|ngNnni}d<xmkDvSG@M&#vDJ+Dv<cbkgu<XtFg!<d(ZN<JkxBLui6c zgBfm*O){yfGO64y6f7l`iu)WEy71LB*b|;GSE_$g%UL>n7=EJFt0Y%(mK|5MPiKYY zdr;-@OL#}~B^31fQerX-ux1um54LP)+Vd1g8dA{^OhxM07jQW8xt69w8}3Bfv`Hcp z5R2|?EFkIXj-3|SLZ0VQXNX;1zZAVFV@LP2jVDi`fF*M>>9W!lh383`x@;qo&2&uQ z+3)a4TPAdfgtbyCw`4mQye)VI8e>y+<kwYFnGElRld*B_U9xftuExSaPsPloggs}Y zA}_!nvEIgaNWd$R8Kk~juW$d0^_`<blIJ#ptL6%+45uFDiv&J8R2;$i40LoRSTF4D zZ0UQSSXqPzbHY_@&Nr-VOpJ_uJhhY)9K2`ys58WFz?Yqe&pw=5-Kb3SPp}1Sct*4$ zRLr4|#=x44!%D(2B~O(VY+_4u>xw*^7jsJvPE?+ws5D1p$nC>8z4YSihA6sc2)0zu z1uE@3uoCZkX-nmLtwF`bDMP$MK##;P6I>wJw6&R}d1Rc2oAD@{2czrLx+)2tK`0lX zBQXj$x;~!Th)Ut_5zk9ERmmgfyo{X3Gl^jVQV^1Y{U^(kd{0$3{+#$$JD-N16Wii+ zeQ%DrflSsBOCp<d`UyD|`(bG4UhVfTSR%n7fk|+XfO?!$2XczuGt47inyz(+m=A7t ONA>BZhUS*0xBmq^f{}3m delta 1714 zcmZ8hU2GIp6rM9PJ2Si8F757iw?EtMY+=DELQ8=Fg(z68Ai4`BB~fEx=uUBA|GYCT zur7*G1Hp)a;{%46v^<C=#-NQa>Z`9rUMHI910g1c;DaVYVmxQ6Jajkrn{&^-_ndRT zd(Qc6;_^gns=YlT(eK{;t?3(UzKRVi*&V}PwK3c%H#U@Ou4h*&8%AH-GIwTk-DV}8 zS8|ZT8_LsGh|Z1EaAO25X+dg12}<&!a#*sI!o!fcEAKw_P=3<HM@kX;@qoHDFS=>3 z=pmR<3I6|SBs@0P!cW!7EusY{wZ=4|zF;g$=Rz%Y0a|h^#IuyN2q2Y|g>Xw<1oEfa zoghiLKJ-J*++aHMc4f}?oRVp~W_8{cvsKT`n^niNX@U<z+aZFMHW^b-*2^_Z6AAJ! zGI&Mn+mUB6^%&AD^%9sgT-Hm5Dr?XIJfaYl4f@9A<`6zGlK8ha1z9ZWJ7F8XuaD>W zVgW~Nq6Ey62Mclw7MUqICE*|X<#67OJd{n-Qt$)gVEZoG>IUqDQh@i3^9EfTW_j~` zcr-ao%S}D+jz#F0$kNQx@%!*#+X#tb6T>Lp5AT7!I1-tsXl_Qf!V&yA@)Jzsw{7El zckmI}54nv>*%MFjObr<DRnIx&i3!s9;hJ;$Xr)|p++{MJWxD|x?B-S66CKr--xAM8 zw-5C5GT%{bWZ25Eo8cLT5&SWl>1UGNIDrAGZ0Lp(NgE-<Fye+T!dK({OKaOVgKj~A z9%LsTkB#;8@!=J3F-f{IeiPf>b%0l2V0e+Cz%WUkx)VhbkJAWPByXB1UX3Sl|EgbL zH4b&`h1ap(aR;VwPv;mkvDLYKV1==l=(KM%M7`k%@2r?+vt5TtS!c8Ss)lTYWe|tI zjys?oA%(E<RO0y__Pa7>zVt=Bo!Acr>`rES_JMRx1*zHVDU=gxN_vN~*;5xnSWNDx zZ1_!~1D1x1$@O?AnSc!5O^(E`kkSpR6=aA(9HL9>y4HZk`9;nTrLyn|Hd5C$n-w$I zneNs0v1sC^^tM%15`EouX1sE}CMvW)ftS)bxVH2~`a>B^+|@fi%-6GI!6to}|6CCj zHjrTmY9x4!APt@)-EI7`x0E=<n>8*u$MqH0@kA5zeT6pm?JIVvB-Y}aedFuT(_F9v zUq3;W=y}32maPUB!WF96qg=Y8iof@*TlE(24}2XY>DJO<<{k{a%}U-cW(a(>QnyP& z=lLlHZXy(eC&WSAoXzcC%kxOt4O&@k#t~ds;u6CNg8xe2R~#Xht@2fUz2wZ=a}`fq z30S(BO~9}CUH0V&n`drZ69)#;ue5*~kxY$9q820<nhI5<74q8}qFnQi&bjspN1SAX zn(LL=#p4)><ABdCw7N1|E|Tsqyf!ejaYa%F8P2&Buqc`=F*V{k!$r=~&@mF<#db3d z$1rbx-1Y`9wFsJZ9LtTNlKbe8ug%s))%Gk!yvNJI8*_TBjN}689?=M@R#LcbWl8== zRhPel*R6~w;N9G6jV~%TVQjD)d|Wqp*$SffSlh`EW+*Z^3|vg&7{dh$JdJ-2CI^CU XY5@PEGX1&3$`K`A>}Zd7b)5be!0~Pz diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-38.pyc index e2c65d464783aaf5486fae2fd9a3b2dcb3905187..10ec3ebc54cc92a3614a02a7f0f95f2287634a29 100644 GIT binary patch delta 92 zcmaFG)X&Tl%FD~e00f%<cEwNR`R|;fpOK%Ns$W!DTAG!qUtE-|pOToDnVOTFUsRG> utXEN4rC*ksSEiqnnWSG(S(1^TXRK$TUz}Nzs#}nloSm4ST0B{k(GdW;tRQ{> delta 55 zcmeBYe#OKS%FD~e00hs=HpETj`7dX$Uy@s(Uyxa#o0(T!l9-dDYm{M9T49`@2ojv^ H$LI(E-$D`! diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/autocompletion.py b/venv/lib/python3.8/site-packages/pip/_internal/cli/autocompletion.py index 0a04199..329de60 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/cli/autocompletion.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/cli/autocompletion.py @@ -4,13 +4,19 @@ import optparse import os import sys +from itertools import chain from pip._internal.cli.main_parser import create_main_parser -from pip._internal.commands import commands_dict, get_summaries +from pip._internal.commands import commands_dict, create_command from pip._internal.utils.misc import get_installed_distributions +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Iterable, List, Optional def autocomplete(): + # type: () -> None """Entry Point for completion of main and subcommand options. """ # Don't complete if user hasn't sourced bash_completion file. @@ -23,17 +29,18 @@ def autocomplete(): except IndexError: current = '' - subcommands = [cmd for cmd, summary in get_summaries()] - options = [] - # subcommand - try: - subcommand_name = [w for w in cwords if w in subcommands][0] - except IndexError: - subcommand_name = None - parser = create_main_parser() + subcommands = list(commands_dict) + options = [] + + # subcommand + subcommand_name = None # type: Optional[str] + for word in cwords: + if word in subcommands: + subcommand_name = word + break # subcommand options - if subcommand_name: + if subcommand_name is not None: # special case: 'help' subcommand has no options if subcommand_name == 'help': sys.exit(1) @@ -54,7 +61,7 @@ def autocomplete(): print(dist) sys.exit(1) - subcommand = commands_dict[subcommand_name]() + subcommand = create_command(subcommand_name) for opt in subcommand.parser.option_list_all: if opt.help != optparse.SUPPRESS_HELP: @@ -73,8 +80,8 @@ def autocomplete(): # get completion files and directories if ``completion_type`` is # ``<file>``, ``<dir>`` or ``<path>`` if completion_type: - options = auto_complete_paths(current, completion_type) - options = ((opt, 0) for opt in options) + paths = auto_complete_paths(current, completion_type) + options = [(path, 0) for path in paths] for option in options: opt_label = option[0] # append '=' to options which require args @@ -86,22 +93,25 @@ def autocomplete(): opts = [i.option_list for i in parser.option_groups] opts.append(parser.option_list) - opts = (o for it in opts for o in it) + flattened_opts = chain.from_iterable(opts) if current.startswith('-'): - for opt in opts: + for opt in flattened_opts: if opt.help != optparse.SUPPRESS_HELP: subcommands += opt._long_opts + opt._short_opts else: # get completion type given cwords and all available options - completion_type = get_path_completion_type(cwords, cword, opts) + completion_type = get_path_completion_type(cwords, cword, + flattened_opts) if completion_type: - subcommands = auto_complete_paths(current, completion_type) + subcommands = list(auto_complete_paths(current, + completion_type)) print(' '.join([x for x in subcommands if x.startswith(current)])) sys.exit(1) def get_path_completion_type(cwords, cword, opts): + # type: (List[str], int, Iterable[Any]) -> Optional[str] """Get the type of path completion (``file``, ``dir``, ``path`` or None) :param cwords: same as the environmental variable ``COMP_WORDS`` @@ -110,7 +120,7 @@ def get_path_completion_type(cwords, cword, opts): :return: path completion type (``file``, ``dir``, ``path`` or None) """ if cword < 2 or not cwords[cword - 2].startswith('-'): - return + return None for opt in opts: if opt.help == optparse.SUPPRESS_HELP: continue @@ -120,9 +130,11 @@ def get_path_completion_type(cwords, cword, opts): x in ('path', 'file', 'dir') for x in opt.metavar.split('/')): return opt.metavar + return None def auto_complete_paths(current, completion_type): + # type: (str, str) -> Iterable[str] """If ``completion_type`` is ``file`` or ``path``, list all regular files and directories starting with ``current``; otherwise only list directories starting with ``current``. diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/base_command.py b/venv/lib/python3.8/site-packages/pip/_internal/cli/base_command.py index 90830be..197400a 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/cli/base_command.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/cli/base_command.py @@ -1,4 +1,5 @@ """Base Command class, and related routines""" + from __future__ import absolute_import, print_function import logging @@ -10,65 +11,75 @@ import sys import traceback from pip._internal.cli import cmdoptions -from pip._internal.cli.cmdoptions import make_search_scope +from pip._internal.cli.command_context import CommandContextMixIn from pip._internal.cli.parser import ( - ConfigOptionParser, UpdatingDefaultsHelpFormatter, + ConfigOptionParser, + UpdatingDefaultsHelpFormatter, ) from pip._internal.cli.status_codes import ( - ERROR, PREVIOUS_BUILD_DIR_ERROR, SUCCESS, UNKNOWN_ERROR, + ERROR, + PREVIOUS_BUILD_DIR_ERROR, + UNKNOWN_ERROR, VIRTUALENV_NOT_FOUND, ) -from pip._internal.download import PipSession from pip._internal.exceptions import ( - BadCommand, CommandError, InstallationError, PreviousBuildDirError, + BadCommand, + CommandError, + InstallationError, + NetworkConnectionError, + PreviousBuildDirError, + SubProcessError, UninstallationError, ) -from pip._internal.index import PackageFinder -from pip._internal.models.selection_prefs import SelectionPreferences -from pip._internal.models.target_python import TargetPython -from pip._internal.req.constructors import ( - install_req_from_editable, install_req_from_line, -) -from pip._internal.req.req_file import parse_requirements from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.filesystem import check_path_owner from pip._internal.utils.logging import BrokenStdoutLoggingError, setup_logging from pip._internal.utils.misc import get_prog, normalize_path -from pip._internal.utils.outdated import pip_version_check +from pip._internal.utils.temp_dir import ( + global_tempdir_manager, + tempdir_registry, +) from pip._internal.utils.typing import MYPY_CHECK_RUNNING from pip._internal.utils.virtualenv import running_under_virtualenv if MYPY_CHECK_RUNNING: - from typing import Optional, List, Tuple, Any + from typing import List, Optional, Tuple, Any from optparse import Values - from pip._internal.cache import WheelCache - from pip._internal.req.req_set import RequirementSet + + from pip._internal.utils.temp_dir import ( + TempDirectoryTypeRegistry as TempDirRegistry + ) __all__ = ['Command'] logger = logging.getLogger(__name__) -class Command(object): - name = None # type: Optional[str] - usage = None # type: Optional[str] +class Command(CommandContextMixIn): + usage = None # type: str ignore_require_venv = False # type: bool - def __init__(self, isolated=False): - # type: (bool) -> None + def __init__(self, name, summary, isolated=False): + # type: (str, str, bool) -> None + super(Command, self).__init__() parser_kw = { 'usage': self.usage, - 'prog': '%s %s' % (get_prog(), self.name), + 'prog': '{} {}'.format(get_prog(), name), 'formatter': UpdatingDefaultsHelpFormatter(), 'add_help_option': False, - 'name': self.name, + 'name': name, 'description': self.__doc__, 'isolated': isolated, } + self.name = name + self.summary = summary self.parser = ConfigOptionParser(**parser_kw) + self.tempdir_registry = None # type: Optional[TempDirRegistry] + # Commands should add options to this option group - optgroup_name = '%s Options' % self.name.capitalize() + optgroup_name = '{} Options'.format(self.name.capitalize()) self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) # Add the general options @@ -78,69 +89,49 @@ class Command(object): ) self.parser.add_option_group(gen_opts) + self.add_options() + + def add_options(self): + # type: () -> None + pass + + def handle_pip_version_check(self, options): + # type: (Values) -> None + """ + This is a no-op so that commands by default do not do the pip version + check. + """ + # Make sure we do the pip version check if the index_group options + # are present. + assert not hasattr(options, 'no_index') + def run(self, options, args): - # type: (Values, List[Any]) -> Any + # type: (Values, List[Any]) -> int raise NotImplementedError - @classmethod - def _get_index_urls(cls, options): - """Return a list of index urls from user-provided options.""" - index_urls = [] - if not getattr(options, "no_index", False): - url = getattr(options, "index_url", None) - if url: - index_urls.append(url) - urls = getattr(options, "extra_index_urls", None) - if urls: - index_urls.extend(urls) - # Return None rather than an empty list - return index_urls or None - - def _build_session(self, options, retries=None, timeout=None): - # type: (Values, Optional[int], Optional[int]) -> PipSession - session = PipSession( - cache=( - normalize_path(os.path.join(options.cache_dir, "http")) - if options.cache_dir else None - ), - retries=retries if retries is not None else options.retries, - insecure_hosts=options.trusted_hosts, - index_urls=self._get_index_urls(options), - ) - - # Handle custom ca-bundles from the user - if options.cert: - session.verify = options.cert - - # Handle SSL client certificate - if options.client_cert: - session.cert = options.client_cert - - # Handle timeouts - if options.timeout or timeout: - session.timeout = ( - timeout if timeout is not None else options.timeout - ) - - # Handle configured proxies - if options.proxy: - session.proxies = { - "http": options.proxy, - "https": options.proxy, - } - - # Determine if we can prompt the user for authentication or not - session.auth.prompting = not options.no_input - - return session - def parse_args(self, args): - # type: (List[str]) -> Tuple + # type: (List[str]) -> Tuple[Any, Any] # factored out for testability return self.parser.parse_args(args) def main(self, args): # type: (List[str]) -> int + try: + with self.main_context(): + return self._main(args) + finally: + logging.shutdown() + + def _main(self, args): + # type: (List[str]) -> int + # We must initialize this before the tempdir manager, otherwise the + # configuration would not be accessible by the time we clean up the + # tempdir manager. + self.tempdir_registry = self.enter_context(tempdir_registry()) + # Intentionally set as early as possible so globally-managed temporary + # directories are available to the rest of the code. + self.enter_context(global_tempdir_manager()) + options, args = self.parse_args(args) # Set verbosity so that it can be used elsewhere. @@ -152,19 +143,34 @@ class Command(object): user_log_file=options.log, ) - if sys.version_info[:2] == (2, 7): + if ( + sys.version_info[:2] == (2, 7) and + not options.no_python_version_warning + ): message = ( - "A future version of pip will drop support for Python 2.7. " - "More details about Python 2 support in pip, can be found at " + "pip 21.0 will drop support for Python 2.7 in January 2021. " + "More details about Python 2 support in pip can be found at " "https://pip.pypa.io/en/latest/development/release-process/#python-2-support" # noqa ) if platform.python_implementation() == "CPython": message = ( - "Python 2.7 will reach the end of its life on January " + "Python 2.7 reached the end of its life on January " "1st, 2020. Please upgrade your Python as Python 2.7 " - "won't be maintained after that date. " + "is no longer maintained. " ) + message - deprecated(message, replacement=None, gone_in=None) + deprecated(message, replacement=None, gone_in="21.0") + + if ( + sys.version_info[:2] == (3, 5) and + not options.no_python_version_warning + ): + message = ( + "Python 3.5 reached the end of its life on September " + "13th, 2020. Please upgrade your Python as Python 3.5 " + "is no longer maintained. pip 21.0 will drop support " + "for Python 3.5 in January 2021." + ) + deprecated(message, replacement=None, gone_in="21.0") # TODO: Try to get these passing down from the command? # without resorting to os.environ to hold these. @@ -184,18 +190,51 @@ class Command(object): ) sys.exit(VIRTUALENV_NOT_FOUND) + if options.cache_dir: + options.cache_dir = normalize_path(options.cache_dir) + if not check_path_owner(options.cache_dir): + logger.warning( + "The directory '%s' or its parent directory is not owned " + "or is not writable by the current user. The cache " + "has been disabled. Check the permissions and owner of " + "that directory. If executing pip with sudo, you may want " + "sudo's -H flag.", + options.cache_dir, + ) + options.cache_dir = None + + if getattr(options, "build_dir", None): + deprecated( + reason=( + "The -b/--build/--build-dir/--build-directory " + "option is deprecated." + ), + replacement=( + "use the TMPDIR/TEMP/TMP environment variable, " + "possibly combined with --no-clean" + ), + gone_in="20.3", + issue=8333, + ) + + if 'resolver' in options.unstable_features: + logger.critical( + "--unstable-feature=resolver is no longer supported, and " + "has been replaced with --use-feature=2020-resolver instead." + ) + sys.exit(ERROR) + try: status = self.run(options, args) - # FIXME: all commands should return an exit status - # and when it is done, isinstance is not needed anymore - if isinstance(status, int): - return status + assert isinstance(status, int) + return status except PreviousBuildDirError as exc: logger.critical(str(exc)) logger.debug('Exception information:', exc_info=True) return PREVIOUS_BUILD_DIR_ERROR - except (InstallationError, UninstallationError, BadCommand) as exc: + except (InstallationError, UninstallationError, BadCommand, + SubProcessError, NetworkConnectionError) as exc: logger.critical(str(exc)) logger.debug('Exception information:', exc_info=True) @@ -223,124 +262,4 @@ class Command(object): return UNKNOWN_ERROR finally: - allow_version_check = ( - # Does this command have the index_group options? - hasattr(options, "no_index") and - # Is this command allowed to perform this check? - not (options.disable_pip_version_check or options.no_index) - ) - # Check if we're using the latest version of pip available - if allow_version_check: - session = self._build_session( - options, - retries=0, - timeout=min(5, options.timeout) - ) - with session: - pip_version_check(session, options) - - # Shutdown the logging module - logging.shutdown() - - return SUCCESS - - -class RequirementCommand(Command): - - @staticmethod - def populate_requirement_set(requirement_set, # type: RequirementSet - args, # type: List[str] - options, # type: Values - finder, # type: PackageFinder - session, # type: PipSession - name, # type: str - wheel_cache # type: Optional[WheelCache] - ): - # type: (...) -> None - """ - Marshal cmd line args into a requirement set. - """ - # NOTE: As a side-effect, options.require_hashes and - # requirement_set.require_hashes may be updated - - for filename in options.constraints: - for req_to_add in parse_requirements( - filename, - constraint=True, finder=finder, options=options, - session=session, wheel_cache=wheel_cache): - req_to_add.is_direct = True - requirement_set.add_requirement(req_to_add) - - for req in args: - req_to_add = install_req_from_line( - req, None, isolated=options.isolated_mode, - use_pep517=options.use_pep517, - wheel_cache=wheel_cache - ) - req_to_add.is_direct = True - requirement_set.add_requirement(req_to_add) - - for req in options.editables: - req_to_add = install_req_from_editable( - req, - isolated=options.isolated_mode, - use_pep517=options.use_pep517, - wheel_cache=wheel_cache - ) - req_to_add.is_direct = True - requirement_set.add_requirement(req_to_add) - - for filename in options.requirements: - for req_to_add in parse_requirements( - filename, - finder=finder, options=options, session=session, - wheel_cache=wheel_cache, - use_pep517=options.use_pep517): - req_to_add.is_direct = True - requirement_set.add_requirement(req_to_add) - # If --require-hashes was a line in a requirements file, tell - # RequirementSet about it: - requirement_set.require_hashes = options.require_hashes - - if not (args or options.editables or options.requirements): - opts = {'name': name} - if options.find_links: - raise CommandError( - 'You must give at least one requirement to %(name)s ' - '(maybe you meant "pip %(name)s %(links)s"?)' % - dict(opts, links=' '.join(options.find_links))) - else: - raise CommandError( - 'You must give at least one requirement to %(name)s ' - '(see "pip help %(name)s")' % opts) - - def _build_package_finder( - self, - options, # type: Values - session, # type: PipSession - target_python=None, # type: Optional[TargetPython] - ignore_requires_python=None, # type: Optional[bool] - ): - # type: (...) -> PackageFinder - """ - Create a package finder appropriate to this requirement command. - - :param ignore_requires_python: Whether to ignore incompatible - "Requires-Python" values in links. Defaults to False. - """ - search_scope = make_search_scope(options) - selection_prefs = SelectionPreferences( - allow_yanked=True, - format_control=options.format_control, - allow_all_prereleases=options.pre, - prefer_binary=options.prefer_binary, - ignore_requires_python=ignore_requires_python, - ) - - return PackageFinder.create( - search_scope=search_scope, - selection_prefs=selection_prefs, - trusted_hosts=options.trusted_hosts, - session=session, - target_python=target_python, - ) + self.handle_pip_version_check(options) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/cmdoptions.py b/venv/lib/python3.8/site-packages/pip/_internal/cli/cmdoptions.py index c5c6c22..ed42c5f 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/cli/cmdoptions.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/cli/cmdoptions.py @@ -5,11 +5,14 @@ The principle here is to define options once, but *not* instantiate them globally. One reason being that options with action='append' can carry state between parses. pip parses general options twice internally, and shouldn't pass on state. To be consistent, all options will follow this design. - """ + +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False + from __future__ import absolute_import -import logging +import os import textwrap import warnings from distutils.util import strtobool @@ -17,26 +20,23 @@ from functools import partial from optparse import SUPPRESS_HELP, Option, OptionGroup from textwrap import dedent +from pip._internal.cli.progress_bars import BAR_TYPES from pip._internal.exceptions import CommandError from pip._internal.locations import USER_CACHE_DIR, get_src_prefix from pip._internal.models.format_control import FormatControl from pip._internal.models.index import PyPI -from pip._internal.models.search_scope import SearchScope from pip._internal.models.target_python import TargetPython from pip._internal.utils.hashes import STRONG_HASHES -from pip._internal.utils.misc import redact_password_from_url from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.ui import BAR_TYPES if MYPY_CHECK_RUNNING: from typing import Any, Callable, Dict, Optional, Tuple from optparse import OptionParser, Values from pip._internal.cli.parser import ConfigOptionParser -logger = logging.getLogger(__name__) - def raise_option_error(parser, option, msg): + # type: (OptionParser, Option, str) -> None """ Raise an option parsing error using parser.error(). @@ -75,14 +75,15 @@ def check_install_build_global(options, check_options=None): check_options = options def getname(n): + # type: (str) -> Optional[Any] return getattr(check_options, n, None) names = ["build_options", "global_options", "install_options"] if any(map(getname, names)): control = options.format_control control.disallow_binaries() warnings.warn( - 'Disabling all use of wheels due to the use of --build-options ' - '/ --global-options / --install-options.', stacklevel=2, + 'Disabling all use of wheels due to the use of --build-option ' + '/ --global-option / --install-option.', stacklevel=2, ) @@ -126,6 +127,17 @@ def check_dist_restriction(options, check_target=False): ) +def _path_option_check(option, opt, value): + # type: (Option, str, str) -> str + return os.path.expanduser(value) + + +class PipOption(Option): + TYPES = Option.TYPES + ("path",) + TYPE_CHECKER = Option.TYPE_CHECKER.copy() + TYPE_CHECKER["path"] = _path_option_check + + ########### # options # ########### @@ -213,10 +225,11 @@ progress_bar = partial( ) # type: Callable[..., Option] log = partial( - Option, + PipOption, "--log", "--log-file", "--local-log", dest="log", metavar="path", + type="path", help="Path to a verbose appending log." ) # type: Callable[..., Option] @@ -227,7 +240,7 @@ no_input = partial( dest='no_input', action='store_true', default=False, - help=SUPPRESS_HELP + help="Disable prompting for input." ) # type: Callable[..., Option] proxy = partial( @@ -259,16 +272,6 @@ timeout = partial( help='Set the socket timeout (default %default seconds).', ) # type: Callable[..., Option] -skip_requirements_regex = partial( - Option, - # A regex to be used to skip requirements - '--skip-requirements-regex', - dest='skip_requirements_regex', - type='str', - default='', - help=SUPPRESS_HELP, -) # type: Callable[..., Option] - def exists_action(): # type: () -> Option @@ -287,19 +290,19 @@ def exists_action(): cert = partial( - Option, + PipOption, '--cert', dest='cert', - type='str', + type='path', metavar='path', help="Path to alternate CA bundle.", ) # type: Callable[..., Option] client_cert = partial( - Option, + PipOption, '--client-cert', dest='client_cert', - type='str', + type='path', default=None, metavar='path', help="Path to SSL client certificate, a single file containing the " @@ -320,6 +323,7 @@ index_url = partial( def extra_index_url(): + # type: () -> Option return Option( '--extra-index-url', dest='extra_index_urls', @@ -350,36 +354,14 @@ def find_links(): action='append', default=[], metavar='url', - help="If a url or path to an html file, then parse for links to " - "archives. If a local path or file:// url that's a directory, " - "then look for archives in the directory listing.", + help="If a URL or path to an html file, then parse for links to " + "archives such as sdist (.tar.gz) or wheel (.whl) files. " + "If a local path or file:// URL that's a directory, " + "then look for archives in the directory listing. " + "Links to VCS project URLs are not supported.", ) -def make_search_scope(options, suppress_no_index=False): - # type: (Values, bool) -> SearchScope - """ - :param suppress_no_index: Whether to ignore the --no-index option - when constructing the SearchScope object. - """ - index_urls = [options.index_url] + options.extra_index_urls - if options.no_index and not suppress_no_index: - logger.debug( - 'Ignoring indexes: %s', - ','.join(redact_password_from_url(url) for url in index_urls), - ) - index_urls = [] - - # Make sure find_links is a list before passing to create(). - find_links = options.find_links or [] - - search_scope = SearchScope.create( - find_links=find_links, index_urls=index_urls, - ) - - return search_scope - - def trusted_host(): # type: () -> Option return Option( @@ -388,8 +370,8 @@ def trusted_host(): action="append", metavar="HOSTNAME", default=[], - help="Mark this host as trusted, even though it does not have valid " - "or any HTTPS.", + help="Mark this host or host:port pair as trusted, even though it " + "does not have valid or any HTTPS.", ) @@ -432,12 +414,21 @@ def editable(): ) +def _handle_src(option, opt_str, value, parser): + # type: (Option, str, str, OptionParser) -> None + value = os.path.abspath(value) + setattr(parser.values, option.dest, value) + + src = partial( - Option, + PipOption, '--src', '--source', '--source-dir', '--source-directory', dest='src_dir', + type='path', metavar='dir', default=get_src_prefix(), + action='callback', + callback=_handle_src, help='Directory to check out editable projects into. ' 'The default in a virtualenv is "<venv path>/src". ' 'The default for global installs is "<current dir>/src".' @@ -473,12 +464,12 @@ def no_binary(): "--no-binary", dest="format_control", action="callback", callback=_handle_no_binary, type="str", default=format_control, - help="Do not use binary packages. Can be supplied multiple times, and " - "each time adds to the existing value. Accepts either :all: to " - "disable all binary packages, :none: to empty the set, or one or " - "more package names with commas between them. Note that some " - "packages are tricky to compile and may fail to install when " - "this option is used on them.", + help='Do not use binary packages. Can be supplied multiple times, and ' + 'each time adds to the existing value. Accepts either ":all:" to ' + 'disable all binary packages, ":none:" to empty the set (notice ' + 'the colons), or one or more package names with commas between ' + 'them (no colons). Note that some packages are tricky to compile ' + 'and may fail to install when this option is used on them.', ) @@ -489,12 +480,12 @@ def only_binary(): "--only-binary", dest="format_control", action="callback", callback=_handle_only_binary, type="str", default=format_control, - help="Do not use source packages. Can be supplied multiple times, and " - "each time adds to the existing value. Accepts either :all: to " - "disable all source packages, :none: to empty the set, or one or " - "more package names with commas between them. Packages without " - "binary distributions will fail to install when this option is " - "used on them.", + help='Do not use source packages. Can be supplied multiple times, and ' + 'each time adds to the existing value. Accepts either ":all:" to ' + 'disable all source packages, ":none:" to empty the set, or one ' + 'or more package names with commas between them. Packages ' + 'without binary distributions will fail to install when this ' + 'option is used on them.', ) @@ -636,11 +627,12 @@ def prefer_binary(): cache_dir = partial( - Option, + PipOption, "--cache-dir", dest="cache_dir", default=USER_CACHE_DIR, metavar="dir", + type='path', help="Store the cache data in <dir>." ) # type: Callable[..., Option] @@ -691,12 +683,24 @@ no_deps = partial( help="Don't install package dependencies.", ) # type: Callable[..., Option] + +def _handle_build_dir(option, opt, value, parser): + # type: (Option, str, str, OptionParser) -> None + if value: + value = os.path.abspath(value) + setattr(parser.values, option.dest, value) + + build_dir = partial( - Option, + PipOption, '-b', '--build', '--build-dir', '--build-directory', dest='build_dir', + type='path', metavar='dir', - help='Directory to unpack packages into and build in. Note that ' + action='callback', + callback=_handle_build_dir, + help='(DEPRECATED) ' + 'Directory to unpack packages into and build in. Note that ' 'an initial build still takes place in a temporary directory. ' 'The location of temporary directories can be controlled by setting ' 'the TMPDIR environment variable (TEMP on Windows) appropriately. ' @@ -818,16 +822,6 @@ disable_pip_version_check = partial( ) # type: Callable[..., Option] -# Deprecated, Remove later -always_unzip = partial( - Option, - '-Z', '--always-unzip', - dest='always_unzip', - action='store_true', - help=SUPPRESS_HELP, -) # type: Callable[..., Option] - - def _handle_merge_hash(option, opt_str, value, parser): # type: (Option, str, str, OptionParser) -> None """Given a value spelled "algo:digest", append the digest to a list @@ -837,12 +831,12 @@ def _handle_merge_hash(option, opt_str, value, parser): try: algo, digest = value.split(':', 1) except ValueError: - parser.error('Arguments to %s must be a hash name ' - 'followed by a value, like --hash=sha256:abcde...' % - opt_str) + parser.error('Arguments to {} must be a hash name ' # noqa + 'followed by a value, like --hash=sha256:' + 'abcde...'.format(opt_str)) if algo not in STRONG_HASHES: - parser.error('Allowed hash algorithms for %s are %s.' % - (opt_str, ', '.join(STRONG_HASHES))) + parser.error('Allowed hash algorithms for {} are {}.'.format( # noqa + opt_str, ', '.join(STRONG_HASHES))) parser.values.hashes.setdefault(algo, []).append(digest) @@ -873,9 +867,10 @@ require_hashes = partial( list_path = partial( - Option, + PipOption, '--path', dest='path', + type='path', action='append', help='Restrict to the specified installation path for listing ' 'packages (can be used multiple times).' @@ -890,6 +885,52 @@ def check_list_path_option(options): ) +no_python_version_warning = partial( + Option, + '--no-python-version-warning', + dest='no_python_version_warning', + action='store_true', + default=False, + help='Silence deprecation warnings for upcoming unsupported Pythons.', +) # type: Callable[..., Option] + + +unstable_feature = partial( + Option, + '--unstable-feature', + dest='unstable_features', + metavar='feature', + action='append', + default=[], + choices=['resolver'], + help=SUPPRESS_HELP, # TODO: drop this in pip 20.3 +) # type: Callable[..., Option] + +use_new_feature = partial( + Option, + '--use-feature', + dest='features_enabled', + metavar='feature', + action='append', + default=[], + choices=['2020-resolver', 'fast-deps'], + help='Enable new functionality, that may be backward incompatible.', +) # type: Callable[..., Option] + +use_deprecated_feature = partial( + Option, + '--use-deprecated', + dest='deprecated_features_enabled', + metavar='feature', + action='append', + default=[], + choices=[], + help=( + 'Enable deprecated functionality, that will be removed in the future.' + ), +) # type: Callable[..., Option] + + ########## # groups # ########## @@ -908,7 +949,6 @@ general_group = { proxy, retries, timeout, - skip_requirements_regex, exists_action, trusted_host, cert, @@ -917,6 +957,10 @@ general_group = { no_cache, disable_pip_version_check, no_color, + no_python_version_warning, + unstable_feature, + use_new_feature, + use_deprecated_feature, ] } # type: Dict[str, Any] diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/main_parser.py b/venv/lib/python3.8/site-packages/pip/_internal/cli/main_parser.py index 6d0b719..08c82c1 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/cli/main_parser.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/cli/main_parser.py @@ -6,11 +6,10 @@ import sys from pip._internal.cli import cmdoptions from pip._internal.cli.parser import ( - ConfigOptionParser, UpdatingDefaultsHelpFormatter, -) -from pip._internal.commands import ( - commands_dict, get_similar_commands, get_summaries, + ConfigOptionParser, + UpdatingDefaultsHelpFormatter, ) +from pip._internal.commands import commands_dict, get_similar_commands from pip._internal.exceptions import CommandError from pip._internal.utils.misc import get_pip_version, get_prog from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -48,8 +47,10 @@ def create_main_parser(): parser.main = True # type: ignore # create command listing for description - command_summaries = get_summaries() - description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries] + description = [''] + [ + '{name:27} {command_info.summary}'.format(**locals()) + for name, command_info in commands_dict.items() + ] parser.description = '\n'.join(description) return parser @@ -85,9 +86,9 @@ def parse_command(args): if cmd_name not in commands_dict: guess = get_similar_commands(cmd_name) - msg = ['unknown command "%s"' % cmd_name] + msg = ['unknown command "{}"'.format(cmd_name)] if guess: - msg.append('maybe you meant "%s"' % guess) + msg.append('maybe you meant "{}"'.format(guess)) raise CommandError(' - '.join(msg)) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/cli/parser.py b/venv/lib/python3.8/site-packages/pip/_internal/cli/parser.py index e1eaac4..04e00b7 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/cli/parser.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/cli/parser.py @@ -1,4 +1,8 @@ """Base option parser setup""" + +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + from __future__ import absolute_import import logging @@ -27,14 +31,14 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter): optparse.IndentedHelpFormatter.__init__(self, *args, **kwargs) def format_option_strings(self, option): - return self._format_option_strings(option, ' <%s>', ', ') + return self._format_option_strings(option) - def _format_option_strings(self, option, mvarfmt=' <%s>', optsep=', '): + def _format_option_strings(self, option, mvarfmt=' <{}>', optsep=', '): """ Return a comma-separated list of option strings and metavars. :param option: tuple of (short opt, long opt), e.g: ('-f', '--format') - :param mvarfmt: metavar format string - evaluated as mvarfmt % metavar + :param mvarfmt: metavar format string :param optsep: separator """ opts = [] @@ -48,7 +52,7 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter): if option.takes_value(): metavar = option.metavar or option.dest.lower() - opts.append(mvarfmt % metavar.lower()) + opts.append(mvarfmt.format(metavar.lower())) return ''.join(opts) @@ -62,7 +66,8 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter): Ensure there is only one newline between usage and the first heading if there is no description. """ - msg = '\nUsage: %s\n' % self.indent_lines(textwrap.dedent(usage), " ") + msg = '\nUsage: {}\n'.format( + self.indent_lines(textwrap.dedent(usage), " ")) return msg def format_description(self, description): @@ -78,7 +83,7 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter): description = description.rstrip() # dedent, then reindent description = self.indent_lines(textwrap.dedent(description), " ") - description = '%s:\n%s\n' % (label, description) + description = '{}:\n{}\n'.format(label, description) return description else: return '' @@ -146,7 +151,7 @@ class ConfigOptionParser(CustomOptionParser): try: return option.check_value(key, val) except optparse.OptionValueError as exc: - print("An error occurred during configuration: %s" % exc) + print("An error occurred during configuration: {}".format(exc)) sys.exit(3) def _get_ordered_configuration_items(self): @@ -245,7 +250,7 @@ class ConfigOptionParser(CustomOptionParser): def error(self, msg): self.print_usage(sys.stderr) - self.exit(UNKNOWN_ERROR, "%s\n" % msg) + self.exit(UNKNOWN_ERROR, "{}\n".format(msg)) def invalid_config_error_message(action, key, val): diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__init__.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/__init__.py index 9e0ab86..6825fa6 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/__init__.py @@ -1,59 +1,111 @@ """ Package containing all pip commands """ + +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False +# There is currently a bug in python/typeshed mentioned at +# https://github.com/python/typeshed/issues/3906 which causes the +# return type of difflib.get_close_matches to be reported +# as List[Sequence[str]] whereas it should have been List[str] + from __future__ import absolute_import -from pip._internal.commands.completion import CompletionCommand -from pip._internal.commands.configuration import ConfigurationCommand -from pip._internal.commands.debug import DebugCommand -from pip._internal.commands.download import DownloadCommand -from pip._internal.commands.freeze import FreezeCommand -from pip._internal.commands.hash import HashCommand -from pip._internal.commands.help import HelpCommand -from pip._internal.commands.list import ListCommand -from pip._internal.commands.check import CheckCommand -from pip._internal.commands.search import SearchCommand -from pip._internal.commands.show import ShowCommand -from pip._internal.commands.install import InstallCommand -from pip._internal.commands.uninstall import UninstallCommand -from pip._internal.commands.wheel import WheelCommand +import importlib +from collections import OrderedDict, namedtuple from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: - from typing import List, Type + from typing import Any from pip._internal.cli.base_command import Command -commands_order = [ - InstallCommand, - DownloadCommand, - UninstallCommand, - FreezeCommand, - ListCommand, - ShowCommand, - CheckCommand, - ConfigurationCommand, - SearchCommand, - WheelCommand, - HashCommand, - CompletionCommand, - DebugCommand, - HelpCommand, -] # type: List[Type[Command]] -commands_dict = {c.name: c for c in commands_order} +CommandInfo = namedtuple('CommandInfo', 'module_path, class_name, summary') + +# The ordering matters for help display. +# Also, even though the module path starts with the same +# "pip._internal.commands" prefix in each case, we include the full path +# because it makes testing easier (specifically when modifying commands_dict +# in test setup / teardown by adding info for a FakeCommand class defined +# in a test-related module). +# Finally, we need to pass an iterable of pairs here rather than a dict +# so that the ordering won't be lost when using Python 2.7. +commands_dict = OrderedDict([ + ('install', CommandInfo( + 'pip._internal.commands.install', 'InstallCommand', + 'Install packages.', + )), + ('download', CommandInfo( + 'pip._internal.commands.download', 'DownloadCommand', + 'Download packages.', + )), + ('uninstall', CommandInfo( + 'pip._internal.commands.uninstall', 'UninstallCommand', + 'Uninstall packages.', + )), + ('freeze', CommandInfo( + 'pip._internal.commands.freeze', 'FreezeCommand', + 'Output installed packages in requirements format.', + )), + ('list', CommandInfo( + 'pip._internal.commands.list', 'ListCommand', + 'List installed packages.', + )), + ('show', CommandInfo( + 'pip._internal.commands.show', 'ShowCommand', + 'Show information about installed packages.', + )), + ('check', CommandInfo( + 'pip._internal.commands.check', 'CheckCommand', + 'Verify installed packages have compatible dependencies.', + )), + ('config', CommandInfo( + 'pip._internal.commands.configuration', 'ConfigurationCommand', + 'Manage local and global configuration.', + )), + ('search', CommandInfo( + 'pip._internal.commands.search', 'SearchCommand', + 'Search PyPI for packages.', + )), + ('cache', CommandInfo( + 'pip._internal.commands.cache', 'CacheCommand', + "Inspect and manage pip's wheel cache.", + )), + ('wheel', CommandInfo( + 'pip._internal.commands.wheel', 'WheelCommand', + 'Build wheels from your requirements.', + )), + ('hash', CommandInfo( + 'pip._internal.commands.hash', 'HashCommand', + 'Compute hashes of package archives.', + )), + ('completion', CommandInfo( + 'pip._internal.commands.completion', 'CompletionCommand', + 'A helper command used for command completion.', + )), + ('debug', CommandInfo( + 'pip._internal.commands.debug', 'DebugCommand', + 'Show information useful for debugging.', + )), + ('help', CommandInfo( + 'pip._internal.commands.help', 'HelpCommand', + 'Show help for commands.', + )), +]) # type: OrderedDict[str, CommandInfo] -def get_summaries(ordered=True): - """Yields sorted (command name, command summary) tuples.""" +def create_command(name, **kwargs): + # type: (str, **Any) -> Command + """ + Create an instance of the Command class with the given name. + """ + module_path, class_name, summary = commands_dict[name] + module = importlib.import_module(module_path) + command_class = getattr(module, class_name) + command = command_class(name=name, summary=summary, **kwargs) - if ordered: - cmditems = _sort_commands(commands_dict, commands_order) - else: - cmditems = commands_dict.items() - - for name, command_class in cmditems: - yield (name, command_class.summary) + return command def get_similar_commands(name): @@ -68,14 +120,3 @@ def get_similar_commands(name): return close_commands[0] else: return False - - -def _sort_commands(cmddict, order): - def keyfn(key): - try: - return order.index(key[1]) - except ValueError: - # unordered items should come last - return 0xff - - return sorted(cmddict.items(), key=keyfn) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-38.pyc index 1e8b8003707dda78abbd91d0adff6b5b0827b5b6..45a364d0f9d0e819844a1955df98349736de18ca 100644 GIT binary patch literal 3000 zcmd5;Npssa6ecNZu@*0h+r(L!W>p$XO|v#h(<E{nyJ;LxJ!vPJ&TuF`NMa3=DnQ1S zMmo9YUVG^wIrh>YkU!A>fNM|v3q54|0FoZ3weF=xAU?c@4{rm&7qwbh!>9i4t!>V0 z+Mg2ae-;ruz&~HpH4U`3209p2_l>rp%YKgL+Btli)b#W1ykBS+)Oem2{ZhN6Yox?B zQC^@kez{#%vLdbc)piwS1t`JHuF<ZMJd{ZdDo};mZmw&<ETTD>hXsWWAvz3;@PR@f zB02&`VM(E5h>pVvIH}MnM5n=mGYWl#=q#Lr^9o%+bP+B=U7^c}K87o>tWX0{6Fz~f z3Vn*`8eE4P3f)9>3vR<_3f)0;7w*C53f)Ka1w4R<3Oz#9f)#iyQEzTnZ_mOiJo!m$ z&%qk3<9i-*TU!0g(fRVG<8C`WV!2@uIbPreJ<Flg8h8U7@_i=&Uj9p_qOOZMr^7=U zN5uC0LCB(wx*;mh84yNb#d9N34ji9A6b~pt^+V5IZoafzYmZw`?XO>KY^-lQ!O`5q zV2H0`D`6Lvw6h*`!;$5O5L03goTz`ra;d|)Ejh1PJVs;KP!zp@M`+>b6q?wuy&xhi zaA+elwvo!k?0TY@(vKEWYz-2Rc|(*S+zDvt!07Z8vP?nDt)!|M-Jxt?AKy%j@k^|e z0X)dMJq<DcB2&&N5ATia<1BO;AtN$6IfXD0i`uGE%c!nCkE1~xS*bY$_84)<V&sR| zW5g#x#I0_~d?#uMlX^TF9iOs{6pG4M*k(%{mEeE{kcs!hovBPxC@NdnW=xkQK&HeJ zFAOZF6CP-ML*(5)akob&rkJUuqS}&58U3wq2=ltb15CC0&MR5@K9-x;p~M0*AOVoT z^$3<n0ry1L>y6G$TTF>#hLgiUEVlN;Z1D@voIq|b8oCa(a5q^!8g{UoaHo@TElwQf z_NS&f5sTWEQp?zv5@>A>H`iq%_p&Sl<zO(T2TDpYQ1X?royQ$AAa110#GNngM%OQL zYo|{Lnk<!(S)r-SN-C<~$|)K1xks@_A)&#FW1(*i!<fBSh*&p$hxez}jTDN?8nzkh zS?pku6HFuT6K;jw%zsP9(t9P7Sawl~5}BgWnW>4)RK$YhOw_YwmLFPuLI;Fp2ci{o z+)y&y$SqGuRYJ)m3=fb_+?yI6B^A{bsg$j7;XfMySLnu6t)V9L@LZMwLOZ4h2!$9R zY%|^?idRnBZ!K@Qc!};kCG6$#{}liH4mOcC)|RyIauZ{co0yUQ+87&e^hrL-jq~H& zt}!W$3tiM1o1p({jP+lPpY=&`T*M2-7_F8qd|He+m=`BVHeKKnnVhIktkksRXt#E} zsIP{5n5@8(Cw)T^;KgD}B#P;|UpGZ9jW)MI-ZeAH9Ynp3s3l!HxjaO%M<OSRSiQt9 zqCcXrz2mSR7nOaN3)aQn<-#s0t#o#_jI9(zF<tdHja@^vze%$n`lQK*as0j4<jie? z6L^HWcpqZD{Wu&o(Un(Cw5vH7M*T3j*0|l|UPP9&i>HZY*xb9hnweWo8^^rJwi|<? zm~~YM?Nr#orMdb<%FpU${4E;n29CX#$s7)t_-{$&o7kw2B+b_+x{mpJZM@MY+E^cJ zQSP<*M#D^EW?5rwfWD+{Y4Vc*Ow3|_bgY#Yw#<R$#8J46{xLio8cfy>-roxtWDHTr ziH+9>9t?bSqn;N<@VZ^}oyqk@o`ySwvAXP=+hoY=IhB$`I-5+-{8#Z!n(K1HqFjM{ zzDFIF#es(?;Z<xjqiU3lS;N#z2D^*6z95RW4WVn>qHNpUIEopuZDyd1UB*UK+>lcA z0gnRCWU!cwmN@qQsSrmV<&9`Kz%9q*#t?-R6eRffX9x8f9S4Judclg4SMDk0wMvpQ zZ=ZLvj+k<>bT28o`!cBfcWlfGx~0#fbEaO^tGRO7&`sUY4BdEVn*XETAB6{{+CTgb BwUht= literal 2552 zcmaJ@OK%%D5GJ{+N92_(JBs6n>?qGhZ6c@X<I*4qU?)x5)ClT4>P6GVdP&(ElUjwl zs$)Yw#Xx)Mseiye=GNb{*A^&p?WI63?F=nha$0o_QZvI@?##z;hJI2k76?4QfB(yO zf947K6_w$q1j-#4@eN7{CobWXGf5S58AaKWma<*j$hOR=teZ7*M&?xB%^Nu@PpN`i zFmg_gDaUn;oR>vaa!W=&CC63SEgQKYC)A`nY2-0^T2<VNksWzPO}SG>F3PiN+MPCX zNzSNQch<<`a!ys<s*%fbUM;u_MxK!8RL!kXB5L|Kh<j3=R~Ot1>Y{tmte=*b)MfWF ztj~&qs0v3+ifK_1SurIRL`m2pFUlJw_X@A@Gy6nbSthTk`yOB5XZiF#b+7UnKD$rc zI-lcJ_<f(xuaf$?-OGhXez4_lh*}V}5<hH(t&N&5Wvv~y!K9Sm;&I_ELSCooxW67p zvXcleRP9J7V47HpR9lK9j9MU}I~XfVQL7nlbhLlc?ktP-&c?uRd^y@~$;jseQ}Lb_ zVpj|dWB2`db66F!J)}Mi<7A*ZOPeCt8tBDU;p<@d_0`R2d$3-5(25gCcVH<$0SMl) zInOqQ81k9?YVFaQw{-vR(wE-XPgYhQtbAT)sg0qe_T!zl00?ruEd$`?@xwr}VJyLj zD=>wmOP)J>v`b%*F8!Ikv{%U+MA~loO2DS9aU-RHJ_EjH`s>bOqS}jaI@fz)Ucb5d zap%=Xk&i|*ys(uB-SXvP&^y3I4{TxLd5!i?TDZl-Ac3X!?Q0lE7N#s=5SX3?@$rd> zF<J{o03-esrY_Otgd{X!uh|}L<r8{f9TLo7nLMw2%l6ow)n#4lh23ON2_-M9oC4F> z?k8)ZkUXx%z#GA9S9`J5Fwtv$s@38Sa7gdeYe@%K6*pGunY85LJ6=DTwAhzCOe8HG ztC8kHr<pJjDo%6#t?V>s76ec8f#POWPeCfj8+n2B<9GnFo-wN%BJqwk2}Qh!0GM86 z+0<cq=1_eRY$wn{q>j%Q(K6kLD7r@}Aa}q3DLCgYNvs3=kN|?L%XFj5IGrJ@gj+Cx z0rkx8?9$QE8F*@bCyA~Hk=7ze8X6gem51>KGKz(#{3O^E@jXN<$HQh*hU@wgxTP5x zZ40fdDBD|NC$3v2_oLO)(d&Hx-$kHe5C~N$eSHl7XRuZ5z(g3rP+~UCGhGKgKzjF| zJ{0&H<L7@MO^R^r=l58GV9-MXiCaH0NZ4LEfg@%J-JYDrmyx8q<sZobyo5L%(r18` z4IJDm=qnUBM#&oCu+2Ac1Hfk1%3Ivv?cXp#31z|-7q8O7Q(tz(U9BVihNc!^0Y4eT zjHA5Gp=ZF}Y<+>>#Q+Fpv`kBEcm5;?8@FT>_%goTF#fu6^r`F-x%C37R+<C4Aw~6v zpzE7BnL@sS5`Iq4!Snz|jI1Hl$r;N^oj$IAkmfv(M}g<11<z}Cl8zRhrxD}yJd}Fl zxXc^<^FyK6i#6h&UK;5))SfkdJFSjz<=C-x23^jLa_Kd3jh!T&AK}$BeO>3!XKsYg zCbW8uxR3UL?ypb%pNE7ltg%o>rUa!DZ0Rv{85L}7t__Ve9~nvvH;FEy$HItodL3Hh zKPf5RsQ-0lo&J5J$I)%nIc(z<q|4|sdvd2v63V!d?6l$P))VNE?J1L>Xsn@sMJU6@ zx(|(`#~h7!k)Fp1OVu<sQ__ZxLv6v(*Az<rmWp^sirZLf@k5ww%Ymji@(;R&4YlN0 R3~Fk`-yilw$tpPc(m%D7ucZJ0 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/check.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/check.cpython-38.pyc index 027afb9b3e8f04fb97b19b5521cd95707811d1d4..993fa68133de3e412193c266c2f8bbf8ee216e33 100644 GIT binary patch delta 938 zcmZuw+iKK67@o;_vuWKPwY5mm7FiEjp%sc~LDtfW?JB!eX;7B!&d{dKVLOvlw`8fX zy%H3cc;TH2K81oW;a%RqTd%~6>OV`7UYKM)=Ku2j$4uUs->kv)fdLc2RXqMuf35Wf zr|_%Z)yszj5yjJd-O+u+F)#vK^>V)HnEk!x<$cSsFrw(=03G~<oio&8`=HXjf<NR8 z`NPg|Uuk$F{-`sG(J~@AVjdx4QmHFDV+7YwG5<s4t`u>mmqXug1f(cs>QdFJKCEVX zZM|Gxs?~bkg*%|Io-;S1^)QZFaRm18+Qy@edU<83{GeW4uT<_=mcdzBb$OJ@cY`)a zw8srEro8uc^5PWap~%4mITFE+Oe9AkGEt6@qY@QL(RzQD(=}W)bD%84;-Ax(_yV@m z4|wcwypxM$f)hP4k{ppHP*=fd@5bI_qTNH!<~w>KC;9~1kvc}Ai5;+0Pvwr;$#*R9 zgty>nC1#TEYT!xsDv8S9CK@b-y^E9@0+rIm7)4MGK~RxeIk+;*r{Q7gP3cM6lcq0e zOoP&x3XtjhlyNr<m@X(;fC7+ymu9e&{*vbKKzdEKS0;e`y;<50eOhAeINotfoHa|N z5xCTAhAg7oe$hTC?bBet<hh%rRy*1bgE@Pl#9`vsTaD&!V~g^%BhOYvFg_1}WD{GG zfdR23ZX_Y?*iZ#C{Erc=1gwP>&>j@Z+qAiR@~LeW2bH3h{*>)oYRn-8I}dT0NO1}# zg=qndz~Z8P1A-}XpDT{1zOs0>>A5zK8d1#a&5%%jGL7`TGIJ<q)t_2+uI0Aux*J54 z1r5)RBiG}$@A77Ug4yK%UPtYg8*DKHf@HZZ8m)#~P$v_|Dbu{Zk!dF)adMdWn=&J8 wMXd(ol;y=y>X&+|rGAH^ugtjZha~psA_j|(0vM8o3%H<IFkMqpU~kEP0gln)8vp<R delta 708 zcmY*WO=}ZD7@p7F%_c3iDmFz+#E1rI`X%B)MNA<V31X>-MTIppN!KL1$!xZ0*x*6W zg)kz5m*(P8^bhziyexQ@{sj->JF$m2%lk0%?)yCN*Z0DaySTrw;37D`4!=JCz$c3r z@q@{YYg-Z>Thg9lE91b>GFm*g$=asuz6igjW*jS9}}TGZ?Lp_u%<z1uX-`9t7w zA1p2dNaSIGJR-111@V}m9*4X2Pu{bI1;VyI!gV|2%>&u&=pVS^n(Ass<Fj_i+MCU> zozm1UqL*asq}<$g(X*9tZb*-rz^R=&X-<$Lnlg+An}gNVg8#SvV_B!HwWoCKj`QQf zj0>v3Eu?OmpIX3e4IZUDexF)kOnnq=4-M%eB;iwxkw9h)`Wx}<Cm6~bU1~(77b@z= zu%zT536$)~a2S_bQ4)%3g)0V8iUMTzp;U1Yg_+fj+HI*a7KE)x@6$5Q^oZ_YM}MK! zD;FU4_uY+QufNd``s+a$5B+X;ef!{M@@gmYjZ>G|)$7X;7jFX~?BW7(3}S`}CWs*G zkHd{;88ba#XU~t8YG$;jTdS%hY*ZZmiB+Gl(C^8NC$Zm_nH?vvR`psHK~|Yc=3vD< zIY1sPHVbkfAAE$7nZM#@wrMR0+j@(i(<Odcclepdru*3(vRqpZAI_RrtHzl#U?k_# b%(9wXnRBNXiKHv<nMubEfI|v+iMjMIItZT$ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/completion.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/completion.cpython-38.pyc index fde6dfece68042cb95469ac59b3f1d2225a7bbf8..c0f9992d108e2ff277ef3c5627560216379db849 100644 GIT binary patch delta 1485 zcmah}%WoS+7~k2)?0WqQNu)eTgGESN6R=B*P*JO>)Qy^mCaG*vl%;63^-P>KYwt2U z4$Z>~kRCXYLo`>AoEx0E09Pdb1*GMIxN_nO66KpsTBQiYjOO>vd@s#>kNIT$(}}`b zK5r{9%71<DW^zY`DfIc#+|_l37=hKvI2oi6h2X&MWSuNhXqIil*$i@>ypvC5R#4~^ zog(Zr&JeLlmgGqO3(a}%wn7S|_(&l|Y8+_JFi{&ydFbe~3;SkctyWuTG|DKkT9msH z3tO-sUS7Yu?$#C;YHz#swUw2nmD|A8@AxqXitl+rkH$N<?3q&JN2T3(lLkS*)C@aO zK)D}wOELEt-;JBhk9hw-wW!f0wl^&>x*%RbbECVp)#bbHyQ}qEjrU%Dzu$kcbl(=o zXiR*JRwpjcR|(y!c6&ikDwoQ3>2&nP&*-)MuDp3aWqQlvdG)-wq5eAljLlh-iZ=U< zN$;BnS_k11FXAV?d_{#!+<+Co1V9xB5yepnax|hkI?;&!NO25e5DXL(69Q_9nz1N; zGzwz~Oe|P6X@4JJPiZS{BoH3CmhOl}GT_4o`z$dJF*?<d2?Krs_{FDub)b<U=|L>v zS(FhWu47p!J5yp8Pl#Xe5Xy?*@kOMIOXll!$Wu&%jjt6p4oZKts+(blR@rv1*Y>M1 zYgUQZ^=Z%y8K-gO;r32-i*~oFf&ZWyZS&2rd!=%<8vC5S8hOnRycUhcSLW<~lJy92 z!$_t#z9t`b89-4nQWX`Q&Ob5!pR>7huJ*J{VAt`wq;ke{Q<Gj#2L@`wf;ehQydxH^ z^L2;o1A{9AyocHv(T>%&$*lv0=!fVS^$nikcH7)DQmJvM9w4OfY(wF>c79MGcwiE9 zP~6jxLHqbbCcd@8IT@?6ny8gatN`0Ib|)|a$HcxKK<&!{pT8&SnKwseJEYB`CitYx zSwVc6nau6>?H#=oveHU<Nc@nQS&;4$i_?evBj!a3CX~=FPc&$^1aE|_<8fw49V22s z2#Pn~YAm?26Yea$v$VRxbP$SZ``qT3)G|*~kmw$3#STt;FLv@NeUcyc0;vA;4I1lp z>%fnv02Iwa!^lQDDj@waOnnsTkj%nkT@wR)Oj{|N;yb(28u44*kWrV>4|_gPSuAW) zy01!*aXSMtSS$zd2CP{2fCX-K)f!8=<&ng8-HjgafhU*A9%E$*Ga|~C1<#J`!_UEc zvD*v@jnk(m<M78+TnG(iT`#EgxF5uojt@~!!#4SEV!j>u-4>Gtl;G2Ytfa((@I@Yr zDU+9D7bTP=$V<aRZl?GI(%f6uJ0a->bY8Y~JPnXjEo7-VlulKbRMibNqh{6L@XX)7 C6LiD? delta 1333 zcmah}&2Jnv6t_K}J2RWK0k-X?R70YrnM6q&h@haV5={}PKvOnCErVdRT2D5!?CwnM znG{wVMUbFMhz~`+_OLm&TtHmgzXFNFs1o7?h!a<kD9_VP8$beE{@H%-+3)H1p8fH$ zkB*MLRW4fy+D{u_zjw{v9XpP%?#`X5X}(EyYEYAwZYqB16+|s+?;vW2+P30bl&m7p z*}Ze}irEU&AYpN<f6<zDlPGa(GkiVlbUf}h<8IOk(<tt_JZ-QPG))#IsmK4rGVD>S zaY(fAN%19~9baB~<8p9irG8=co!NIcr^KK5g!mc1=6J4WxuYgtCyV2?85xDg3u)uL z_>?>?z9B#U-SD<j`-kE6Z|^BxZ0?^HE1I{gNJ60TC4dn5m?EE0>?@S`Dph=qs=j^$ ztzoKBeaG|-Nz@MV%^OHXehH{4iLbO*Pvq7k2Kw_axj;)2GD%Cf(WByfZEi~i4<?Lp z>8=Biq7)C%HffUq9*{3EMg!DVHkE<WRw<^0DpZwjsqwiEIw^%5fz$%2eL(8aGDycj zIzE!3wl>u1p@FhTFro;;JS-A@5^Lf!y^eM9gT8<bF=oshF>;M(5Gs?Q<z^5>y(kR= z@w~BgLCsYjcGhyW!CE{g?_XyVU~~)Tr66c_8k`5gE%f{OQ)xFj1?4aw^&t11&ipg$ zOW6m{#tkVHca7Q>I}GQZgTW;rJVA7#VuA=B^*?m|fA&Vdy8N)lU?pi?*pIfkpGJAR zJ{rp~a|V!#b#v<C)l?m7DH`en+*T+ML)FySMiH){J-n%<W?C9(g-*LkDrg(h(W|6Z z+a5YH1;g?{-79RdxM#+5lW?&|a<Xum*|21C{{W7|D!0ydBA&{cIJYV`N-vzr)uLue zu0MDf#i{<$m+SSF`it({aprb2p1KLJ>ejf`SKXMom%K6YOKBS0qHI+OQ^le+Dc-c6 z+^R?)Mx4k8$Jr6N(~GCb^Kvl<`?{wd##KaE1gEg9cNyfo3V?`-C$NQ8>_A4;`_Q!t z(Xn&C|HQu;hm)R_i{GsIEw$I^hPlBr$OZc_e=KVCVipE0yp}~UZ-l*#BJXSwoaE(E z$u!}=2!aE29Rn?sVHFj48W!9EFd?9#6Q^2eJUh37U@c2CxIAD)er0S{LQQ;Pd*VC0 vdPzPp=1G{6AWQmyr$+>sXS*@YI^j7C7W{Dl2UswPgB_x3q(p4;t3Le~3hP2} diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-38.pyc index 6d16af1ca9c40139afedd4a29a6c269729cf5a89..9a18a740496429b637c8cd06b8af6215df78bce9 100644 GIT binary patch delta 4028 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 delta 3096 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 RzcysdEbY-#RQ*~)|39z}*!}<j diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/debug.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/debug.cpython-38.pyc index e4951ec56a3dcb4cd0c13016fbcbed6318d2b477..abc45dec6154642d69bae6137304055a3d52c000 100644 GIT binary patch literal 6439 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 delta 1813 zcmZuxUvC>l5Wn3!pU;lZNgO9`8k3p=6(?F3m6if(E0rMifx=564=3QbdN<CMy|dZ9 zOGxVChgRwnNabFT5K<~3p}ryU1^PMm1AzDnyp)-ZLsO}D+S%FJncdmn{Q3RDqm#|g zeZOwO_xH{pU-kS)%`Vl}qqD)(7M0WuU1BkdIii|+p=bDtsHOF=Zg^MBrH!y*_^R;J zX4o{mC+5?IaKZ33v6!~Pmf`DSDQ$;sV)2&z4bGht%jrtEl6Jz5*>8vw>1wzN`}VsB zC;8fA5_Xx-nh&h-6*kWnU|wg7tOfI_8x~t)?FSZXbML+#_87fo1<U34q+32Ea=JB= zX`DxSJPfF|uV;JOxtXXuAlluGMZwj8;;UyL@-B=G7-|JbZXFOt4(P<1kjL~fLHFQ% z`su!V_udD+yY~WHyJ9pPa;cpp+Zt*2@J6`J$>Oxnb!7+dd1A>WIPc%9=ks)Yew>WY zC7H@&A<kXczF2(s&L~D<*|yL69lYFlMdfn&iTzW!2$H~)O_=075MAAlRh;Ki+iFiq zbX1~_tRh(k5>O-6OG!EwJmpy)=gBCGz$I=RIVA1!eW$zH1p|eLTeME<#3dees7K^l zdAIQw>6Ewqfc`_uAN<Xv0!rE&a)YSSjTyYdWQS*R0XJ;{+%ZpgxV$}5{LnSbu%M=^ zqcM7;<T_gTc`Wh7@m{_?%CrNqQo6j^T<_}!@{vf=B<D=qusZHM8rRhJXcxn)g7W9) zr7zwB;Q+=9pFLZt_kiJ6NSGB;Mnap>&|!91VNU3>N?3hpZ4u_O>I2Af=CK+iSnZ+Z zSYaK4UN0{%UYzO*<F||9{z|=PzBk5lH0)iOz3AHhnOopc4^sgX4_?_T6yGXD4+K49 zI!v-*|FZ!(=Ar{U4h*ik2qd?1GO_N{J9I)O^he0MiFL=mXXiJZgUZClL<E6*P-O&G z^#8P!cxvG3iYmrj%CoT2UKAx+l1GvD1}TfcQzh+EFP<vxR(BdW+EH9=X$PX9H2r2* zz71ASh^|G^K*UN#(JWa&EYAbkgrPhj7HLrzGG>4IBgAB5l%{dU`bYN-j&Mg+<nf6c zFw_o^!_q2$X>s45ko)kWya_1R{v0fAkT-*QlSI0@8_Ns;Gg&S1Qn?C5S0S$ypj%#E z{(8EGVvM}R;tgzx5X#q(Ttb4C_xugomPPg@h*S@VMIAz)Ic|gC--MqMYPruGyFpy) z(fx%N-Ug<@972kf1d!IFC@uNQ`qUJlt`sUBa$QvgKq2>_{)X8|@<{S;iv(sUlO2Ph zybf1ue+Kb@3vmRqarQFo$~F=V;m0scfqKMo9O8h>4sBG;UhpdVu+=T{0?v;lHV%0W zh^}H^Lg-e@tDO$9%U?U4QgnRcl>432qyp>LrwEu{gVxiBB+0qVV$m=1M5z9eHTD#J z;$<3Xq6Q`;`sB;D^Sv?NUPJq(7ZrB5ITsST!PL_3Om7bKWCN8wNYQaDp=tQItU+_Q zX<DrO5Oqv*!6ql4#~o2R7G{GX!l%6}>4+7AU&F#sXMi-IwZTtKz*kMw4GW+ykOr;W KUd8jh)Bgde-Lb*| diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/download.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/download.cpython-38.pyc index 7264525867f12b80d9743be1d5bb3c7f91cfe9ba..396634d6cb23036b97fb357eed10de169056f636 100644 GIT binary patch literal 4093 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 LK`r1!tyB9ie@wqA literal 4699 zcmbVQOOM>f5$0=14(GKGJytJ=Q7p^rct^2g!HFX*oXBwO#1I@ydC_nPF1u%jBfi{C z?s^v7(+cn<iWI<SWB2G=kVAe(en0~`<zVEViyb6RRg<%tSvfvr2sXRAs~=Te^;Px! zve$DI_<g?nr{8_Pp(uYxV)17H@jATxFHjJLsIii$o~mM9i#1P^U)|H;tH(yt@>;Ub zh|R?EELm^GcGC9RvTnvs((yX7ZpGcC=k;XWj{C{L8_0S)UP)HHRatl9wPf8}m-SA3 zCOPY!P0o4eB;AeACmY^|s!;9d0=;;wdY68xkRItjP)MIzhq`x}Xm^#(!9QT{%BCs? z!4A*jvY>vH<QXgOK${aLB+H8^OF2+$@6iv-h|z?m#qBIff|Ouu65OYL5wI~W{CrkS zvJ_hF_bAM^OBvMH7skEIXdW=x++S$EON&zr++#s_U-GSl6B^$4^Prgc*<K25ns8{! zOGbSXG0{&mmIQIMPbCk`)4NBL{0-P?SY&J#qJWD(y&?E3P@#&a5(SP*g=5k@gXmt1 z7@qmDGEzy4m=A2vA{Mb9D4zYXVkll4l-3r5H()Dq7LY~}!8@v=I4=C=9c~T+1Y^qG z5zCU-9ND?$zB_yOZTERlotqUC%G@X=^drhQ-I7P?*kw;t?DCw3(I}#f51YZix_#Hp zSvCd1+>*s7?eAn^5TEpbQl#V&J;jhQm_Nx1>hi2)A$0>5PNH38lMCcg?glZ>TwdmA z0^B8yl(;n%!@at&L69tpDZl!nyElo#39i2z5h|w&QkMpN=I#YEw}1(yC^I(z)-0wj zO?M-frD#dmy+cn{qNEm9*z>i6OLNt_?lo9r?7rXF<OlAph3!1i*S7n9qx>zY-mMe< z;jo_l>6y0J(qy%4|Ib9Xc0+!06mUq}?*Cr&R=jj@XyV_<-kcYn{f!gm{k5k|ZWw~f zPJS(@A&?E=<#(W`PztqD4z;OPsg?Ez0IW)x>IZtI9~njK$UIh#v8|@8CCXl++DnwP zM0J*^?h@5oqWVkJV2N5;qE?rvwIynOi8`}Hot;xtgQ!F!Ix*0<i*wWS=-Ur%RROs- zDjns9+J&Muy$CwFbgUg1_&vHz+LdvvNln$1jucS<4V*js+7{V2x3&o7#r|sjjnV*t za|^t2|NK);H8hFt+{h)8>BxKKsnZ0E03W#po!i4rLm0S<uo7AXy8#mxp`)OT3t>!X zoHIQ5%`2h>E=(Eg10`(VkJ6~{ePIKh```>*I02D0*daqa6rB)2zF+~Y#YK0)t+;6K zlu=CN4y`ov3C+3akK=47h;cHE4x$YmJ0LQfiB6WrvpLbr868nJCw0z3p+lRnVL%wu zAQk;)F@F;935CVc#~J0^-vRN~aALWB1OY{=R5&FEtf%?SmtGY;=wBeUj0-a?87NC! zKpB?;)5&&MWzecO?~hql=At8^q9IHOQk*ie9;NUpnsIgKW=j~H#v@@s%;Q44zsDds zP=r%Yfa?8B6>T5H3qT0}Gv&+IZxl&>1K<_#h!;T|Z@oNurTpmoS%8i5g(E5`ON01E zScg`AV{RM6e8$eh3g3m7zX^q+u4$&$SHJPm3{_L)qiXN~^)J(QpcS6~7_Gj#zcIJ8 zCWZ~?b`s7bB(BwicNN~-@bU`Gi>Q_AD`N#pwa||AN|jz?OaVD6b!r`Bzg5^!Zy#d4 zT{v|ez2~Td{EyW~FC6Gaw^9#P>0v!UBE2$*_E0})0e3%-p&WFT1Dtb(eNwFA_fX}Z z6l+K81Xi7{)E)>ctQ2Psl}CR)u!^%dsxr~PAL@_(d|(&npyfO<AF2m!Sbd{vSBQEo zSWTH;Aj&bMVa3JDp5m$&yln!KO)tTFxq`_5&^mC6E0u#IAdRz0o1kRR!22zrK)$I< zoQK_mPSrX3cGX5*kj~Ln(j~nIO4Xiz=MCi$BtGa?-N!2X8SMU9(yzL>cNp7$ta7hv zA6+|EROQ#oP30HLd&+OVwpL;0F}QPYQy13U?JN#{0uCs8OLo5hw|f%^sq+lTy?%{f zcOm*m5YjRIf~fnXGvaQV6)vV$#NB~#4MV|$Bo}xVb1_*71IQF03D}!Z8gmz16@oTR zVHzIn#1OPynWf3W06a+~x5edHnY6jt2s(p>g@^9jBNuX?uq<$9Og{FaVgktr$zF74 zS?MN_JnRLqS!}w_-L1FWQ5=ki3?mt2fhM6bEvPW=gX?Xo>>4&(>@s|W1xSOC#a577 zll%7P9wj@T!;ZmeZ0P_R`GA9%e7?CqD6%aMpu<PAErhkruCM{UWC|<H5qdmhui-?U zdIi)I6+J{G)Sb^G*xyQ-k6A#dj{sZH@k|Ux8RTC+qYWMa(2OCCg@l&o6edkWNZ!OC zpZSnN;{gLaj52Yq;c5_*H~F?$Y1*6FC=qszmXv&{x=YD`2Af6qz6&p3g902``M^0q zLstH%eQ4ZO*sIVCX|$0B2?aH4!|w?lmXz&v@dMxx&aF7&1;ACl{VC3d*C7)?XaD+X zU}0rCtaBZ{4VC$*{fl?YFa!%8m2o^<NCDkzeDgW>b6liNNmQVT@j6bOt8W8fcLk^q z6dHvXf!GVkY+zC(EV#*Fg>6F{>tcaMz&gm%Z=y-#I1G~`akgn}vPQo-*k^H+w5GN^ zS7|nwNeMH~#$$*N)?UC;uwK?iR)k7sV}X_^Hu5YlA!Ok>pIn@LP78Jic`Pi@2-)jc zm{`08h3MC}sQJ;0-ux{6BqLN<AU0mDgfY#cRGjAvIy|v(FablFOiu>cG6$JJhnqe2 z60Y+@EMCR}jhFoh3j}!4ZDPH2EcRn;YM(%b7@QX5C&*wo8)CwlI~XOWjYS6=kT&;w z7^0}AZfcIUqIRL|t2TxweEw}hU|K<{WqfJaz@r)%#J(~$_^HNMrrvN$eyD$8I2hdU zslVD6CbTR+buaY))9gDq=U29Fs$JbypVRi&zs6cO9n6~0{vm5}d{lfHW4-J9AC^Jf z^jJP9JoJ5eprTcBxbFe-lyEm@b<AcH)KITU20|Lgz>WS@7dNqn&LlInGf?4Zub_{P zp&6E;b)T0#kkP>|MrDDQUZ0^83kz)!Z4XV~TLt_ao+J^&Fpg?}dFHA1;Z6YP)MOb9 zoz}bjG}Dutf9)ctSYkR3!Wnv?yyc_u3WV^5Eo2Y}WWL6SbI3%KKfO}~7W5f$WqCNX z58<6-vGg!;N*ah9a0!-{J>vyUm~_sK<%w!0h)AJC00{`<lsGjH%#ceTM@JTI_(S6z r>E<i~n*A0FOsE&mPoAU%L;F^3BiopOa|Dg9W~;W=RhJ)W^7?-P#Y=Rw diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-38.pyc index 0adc909acafedf9233a06f68997681d0b1fd04ed..3d6bcb1af0c349be196c9ade08a6a47661b9db31 100644 GIT binary patch delta 1492 zcmZux&u<$=6yDiguh({*ICdN-p=q5S8n$ihLJuGm0g?%&Kn-e?NL>jn8^1}s?t0gq znQd#6-~&C-Ly*E=IXE|vI7H&sLofX&(EbfboDiZyz#AtGDPmUh_U-$%GvD`Sjw(M_ z@*DYlR>5KY^~Bjd$S;zkgDanJD3I}|x&^yH6i^`RPj`!U5%nBQKprOBx?Q40_8t1B z{F!dqE|231{%p5mSBP>$foUi{QlLo9uQYoO)OE!w9sJlZ)9V|J#@hP&!7rDG7D<Y? z?tFU3X?(EO_{h1v(QMvq-bl2b*GsaTil`^T(C2m*JT92G6$zT89<(X-G1J&|{fKhZ z^pDZql6yEiRQz}sCw~<MRcr!^tpc$%P;DJFI|XGOQjZkd00YwaPJ@Yy%*5Z4$8lAi z8(Qk~0(~gns@Hj+*SG-67@NjoErR03ka`AZ11EoiVpr)X9RdVY&_Lf&ASLVXr^ySC z2^q+aJrc~b9t0Mqpdg`x(s186O__o6*gOlR{nW8_M1(rh4wXZ48dZTgjG7<murNvq z<B%K@cx7Kd^`C=9^q)VqrAH=Qkjp((C40E}YIC5jut9!hh0&k-+V`YT#vQR)DJoLT z$FHTnocUsJpkA$78vEBfA3sZNl1zNfSWX+;A?vy#-ZW~rksVI`?H?3&8S|gF>g}*g z>#QF|9k0$=s}649QNI;3L3!<Ae^9?qgZp*g+p72aq8$d;Yj4)MC+JGgZQXTuD36~R zOO+(&0ytq$cwxY+Seb93P~zW=TOaDg{9FCgFbtv|Kd2Ap-)EE#Xd~=)-2iH5vRj(W zJQ*gwb2!IrejPtf+iUu6YL|4Tf$V4Y3{l)xc8zbyd&*}sdudVX%#6yrX;3R;9_|HV z7E#oiRwl_YdN1-A?b1N7g?QDx7<bIYH>y}XAz7=!(o)l~%b8q2l4-fEHg&*bOturd zAdN=U16NRXDSm1$4~x>iAjLT;&dUhB=Zbcc_ju@IAUNF++q5d(aw}NB&l3ZCH;e=x z9fm+M109yhEa^|5K$z$*+u_ONF>_8U#6^cbdtDZ~j>67wvuhGS=k9}Xr0#nG9dmjt zuE=T{i-J#386P=CjgK-57bOS!@5aO=DU!kT%Pe4c(=y{<GqqtV;z(|i^TQnn&pLIx zoL!ZFmrR`bkL)5Qf5r+ZWdCt_dznNxbX8Z)`q*yGCt1hYjzq+$<1l#@uvHXE39pu# z;{^yq;QF;O<`Vz-Y4)9^^Z#-B9-ewvL>%z|%9#=Wk+o8iH#=U=EfF)mnX3*ZTgk%9 zsgdw}UK9PE7wj;(K6Xh)nTU4JWt_4}`DvU4OvwPbo&VcsVy+^mkx$>2Hw~A}PpGCk QK~A2jV?~`%b*X9p0BDSL00000 delta 1319 zcmY*Z&2Jk;6rY*>^x971#P!x~(<CTSFf<8;Rze81l>+2YQ3)ZSxN4WhGj`Tldp9$) zB(b*i&`1@B6h(98;9QV;tHgl=`~^r{xKQn(f)nB&;7}oznN6I88NH{S_hx?Yr}weX z+^25&lXBSsa{cwy(|eoy<!PAizy8Hs0Xw*eOY3@bd=20-9@_<YjMxvg<^)C`gU0y& zAFE;+E?&>HIEXWc5uU_6ib9q-IAELxUnZPn#@0F^VN2nkUfR)ty)Ax*_4%fWji&Vo zv>`UJwQDzRY~#W%Xcis;9W)&o&k=vaZ)T_^9}a5HY`zv^8g*vxL@^JdKD#@(EMCIP zK?A**Alv+%l@+$bmKn!{QaUEzwcsfVia|ljxD@t_R2*=af`_P!QkbI05P}qRwXTjK zMp(mo2Vg_7+p|U<@h5U0s2egncpOjQ3ZBGMd*;ZGtN2WAtx2nKXdUX@7@7y*-~`{r zXXULrJ~y<ueE@3!pWoAuF)rX~>AiStD-0bxqnI5a2r&3zNBa>@OiKQAN~x++HF3lE zy1Kvy=+bOMqbJ^)_|5p#EoKHwVwsh)yqwvd7xV+}d7@!1irePWbuH5w3EP?O(+<nf z#?}*<6+EvM`iyzr6Y%2N3h%`$vg}JipK(77m)=~zl5D>f`N}AMH|HvJMq;0r!mv~T zPKt5s!!-o$m*`*9G$A_N@_SJGfD$qwt5L7#_wn+GPHWU7>b)(cBxO|!`%ZjsH9v>l zN~)(u3cHgS?m73(!91_FL25pR?}5A3`xZabtqtAO!pP0jy~#fVS3#-|rw#xFw`KBV zTWPl%PFAF3GYKf^kv^xcc;9}d=&+3-_9*F)ZPB(b7N=$43_6Xo)D+*^^(jS&UQk9e ziLuWKofkjZiyx_WqOMYPrBntoJ@)x}<{lv)M`DNYSvg=)C=syNi)63nk*roo{C*Ns zOH>MOt6|ecg=8JII(=20#@Z3>`P^$ol6Dl*D=Oku<texGlzJOmc?tC}=o5NLxpTFo z?r1dW-;^IrnE({~g>wsfUKRZxvy9*vtf4{W|Fw}%8b$GIVflgH_j_`>6XthFX0b%p zj_zc|FzR@6_KDwPc?Zxn6{>vHJS`H2o_C7KYtl;<o4ghCQB;F!L*3A!j+B(%$bF4U z=6GH^;Rz)Y!bIxP4RO!8Bc3}8hAEGku#0oh5;u$WTdk-klTPz0&5!U;1wKiG{jSV< V5|V4`=fKpcl#q=|@OYz=_8(S5L!<xz diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/hash.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/hash.cpython-38.pyc index 772bedab05479bf9bbae06140d85a9bf97a447df..008bf8cd2602478de4958bc4bcdd07d516063b56 100644 GIT binary patch delta 1303 zcmZ8gPj4GV6yKTsYkO@cO`E1kXkADFtJIe0r9!13nW#k+QzfLLi_mK88QYugzs$^r z#-s!(J;0%dXpdatBNuK6i7&u+816`Xg&<MhY*JzIM(?*X^JeC~_j~(JnsTnORj*ey zkoG^n`8VyO#wz;x==%EyamA}3jcCM-s&UP$#jfX;Yb&b94X+V5y=J+#qq%tAn@1X* zXWzqlCps4|cnhVi5}l7Pco)E?A1~62Q{*k()ku}po@=B=twY_rL|jsTu6fG@Z))wv zUu7gnHjjQ?oyXE#-`MzUL)x2Lz25rf=FuNl53sB;8W4Xl&XXrxx?i(UP(RH@mWwu$ z=RSS(;E~_Ex8D22-`MK+Kkna!UF%^G<&?wBxF2#cP+n#Q!{S3w{x$&BJVZ1P6XfXx zdj`=xlNiK=C@r#T5gR5paUk4^tlbOvxR=IpkdVoXVh8<j&;pq(U&~lJYJHhzB1{wh zRqOUJjOd+Kr_=d-fWXNsQF9lx2g=_A*w?nTZA1{kL>HJCLMP_2L9Am_;3=9SV!yDF zI%OS05bE?4E3Q>I{RzHN{DMEi-#jb+#_zTr=?r4xLl9h615(Z)9A<+bW&ucRn6fw! z1<}_wfE-Sv;ZGV{1=C5;9j7tvvb{Xt4!fKUx+F+K8Vyn=DDOPon{;<+vfGWq$K7mC zjML<1=T?_PHEv|V;7Kr|y!c(e@>tgX^USZn%X|qy!xq9CMz4l}oR|2-awZpN812m5 z9O&xSnV9f(Kugx{6dxFCD@)G|VG*=%?CZi-c!&=Tr0ukXQ+#JEqf5n)#v2C>xWp;| zvhI(ebbdPYRb`lZv2C&yWwOtzCXIlNI8%3|kp*I05_1Z#sZE{b$#t0UMF0&OsDTW~ z%Rz?9O><sac+#BB$ASy}wo~-X&Ze1j;7Bfnqa<b2XLKhI;j1`hm*F|~rUF%p8BlIn z9pF4DSA7f4Yy;dnE~^)Rn$rWti?s5L1cJ)Sm_8*TltMsq*T8a`jUBMTINYVuP$WpR zY^MLac^!`50xjKWx{IpFMT>~3{q~Bi`u;E%IfU#p)jzBYAnn4mA7W+}U)U{6{bI~6 zzO^rxQJoUMoP}A(4--LI5=5O`gc0wEy(~;dOeG{8pg#*3r>v%y)|pLpiL8vMxSx(j zl(Dx;V|2Pul$3$ZBvDdV*2%g3PMne)8c?+xR|Xe5P$vhwXs#SCRL?~&uIh7Z{{r_+ BIw}AF delta 1145 zcmYjQ&2QX96rVR9+hgxXLK>wsBw<U_mIyVK+8#KxfQ0xELP7+3u|zFvXLi?#*WS+9 zX&Wu<A(48b(#i*}$+0K+JNhTgfh$L@C=x1f+@S7^-t)W<&-=ZPG0W#m-G`k{NO1ji z_{XEUH}7u1FY}Kcd<jGl;by@&jKXm%YBjQ#wa1;P14KHfUAc4y(ehVB_=2Ah!KHWX zMDK_|geN3g5%dSL)0+Qzor7_|*xUPVuU>_#GcYYB6A|}EReqrRHt^zdE(HBC9wdoC zkcbM196=){oX8a{@`M}t&&dFUC;Ss0alu7^A%o|HktoElp=o`c=+WoJc%0<o=tbDW zh0>&|4a{1NXxIo{>YwPw?C4r!D`n5Br0x}i-X!TCBtzLtRDYBnO1=AI9~OXGoGqj! zB>fGtl9Vtd$8?`gVM<>BkSW=B_L%@dg;OH#5^)Rf)GysLSi_?I>Nh_8)DHx=&h;z0 zN3ZL8%eiwoG_I~DQYnsi8y?4Lo|bW3fA3rlJX9$cS^dn}{?su{%WPm+qK4YggC{S+ z1aaKY60PI-B{{!;yBtq$PtwV)G}mR4Ww-8(?p06k7Kv5Xe>?AgrdIH_4J5sejKB(b zKnaDno4=;#9zR-LDC_S3p!!bzkGoN8c6D?8XH4_d7cga0r{tC&(=!I-aZix?ceV~| z^(%I5W(UrASuq?+WmuXI3e$;g@#A6;57JETxawW&;}?@MEpn}{pro4L*d!@OYSYRM z+p>O+s`3x<pjVL*V9*6dJ>YK=A^i2x(gJjE7u|PSwQ_f7EKkPLxRu6k8(&vAGU}PR zln(Pk$ymw9Rf^w3nIAS)Qa5e5&P9RyGRxw40nB@7RTfdxxMn)KC~;suLsYnFyWQCO z6!qA{f8F0^J|2u$O+->k6O80jkq)IUu?RQN@+NKnViHwgo!#dBECg<1Zlmcgl5QR} zZ9@ocSOaDCJC{rt$AhY@Fr8T0=*s#UKdV>$hjs36dUmLkSI_;eM-8N4D9dk~CMjE7 q^?_w}BAXi*qQ7kfzdtTSmB~-+YiYXCrX2gg5ltJGp-n?)dHX*FfD3W} diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/help.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/help.cpython-38.pyc index 8436a69bada63ab72a21b8bffff3f2bdaaa8f08b..a7f140c72a70b2b55f38035ea307edd9a014943a 100644 GIT binary patch delta 858 zcmYjOUuzRV5Z~Rq+`r_~BB2<y7>X?hY3`vQ6-rQow4w&FR@=NB=j}GV_WrSZDNTB3 z!S-2*_XU!#A&8&AXW`!c3O@8f+>L$64D;KWf%(nM&UgK{VeXlx0k|~(ezX6K&1LA1 zA8oWTz$IS`^qvj@(dj;q72gQTy)p#cSN%$0_Dl%20oJg71+Y$}OQ~1I#x7`<$4R@> zgvG7b2X7AS&d&4BOZ)9!xBH^I&9m|=k0tz7-aGz)Fjq967sP|7+*o7$vtGfaE6`K0 z!fDm<_3FiF$!N@EHKtL&vE@cV;DosS&Xwj!#6}voj^O#i0Yi*@5Wq|dP$mabR)Szu zNfCy1kSQNPcv}XEd}7c|2!tjj1ss4~un$rtl}=Q8mX=cG5?*8~mL^K7Okp2pTB_3H zRGX++<~el=r;wLwxHQpIZ3-{pXPC;OEYnl{*qD^3Gittz(xs4()szbJW&>tp&rOP| zONo;Z`zBk|`XsTL7kIuyc`{!^b#$KP&rr=c&sIiKW4+O=<Tk38#m=-Wppt(=OUhwH z11HJ9qK7L+Av5A17HSkHUKFxIc4(i``HEj?b>}WGzILpmC?FOc4hF}b#i(mxC-jK# zMl>O;bv7JXrzAYJeD9+b50j%P+-PlD%uC36?6@aRpRoMC^x#R2ld*do0IJCdRbUkw zNP`;pWVnc`+&9o@VTbr}=l=~`bP#r%YMx3hr8HoiDgPlYJznM%RE#zUf|u$XOm0kE zT7xnYI?HyO3;BXP8WwkAFK*dhm=GE|eru3;K5Hez*bDnq;Z=ol6R0B4`1iyPWrPaG g8Pi<P*$AR>p=|{b9{8j!PRJHHRQOgiMY4FMf3wia5&!@I delta 719 zcmYjPOK;Oa5Z+xsV<n*yRoVbS5fCX6N-EJ@kfI2sAmCC7l?uoK*JRz))Gv1Js6@7k zNDmyiL>4!Ml7GM-;E(vg4RPnliP@AxW;C-8&wMlAj(-_H3Z=tR$v_~#C*NNW=A{~b zIKR7Fd5ow+)eA&bTbfBjooWZDrO&_iua89Vx)3-#0OQT9hO3)Hl`2Dxs#Lo`kf%dl zAsgUEJ(o{xH=I_C`bruh3&!={DDXVXr~T<x_6%3fJI_bb8h8QrI@q4T{{)U=N?hdO zRPsnFV>B%$gyJenl^4k0mQf^~8mx<v&`4I%D|CQfqC`ogQ;mg*oG3G#s#Hpp3L4{7 zOH}qI(H07o6Sabt0}N?EV4)@263_5QoIq$5%}}Z*`dfWbSgwG9l)BF_G}Iz_=|2Z< zQfCxphonUsJo`X4jRwCpmFn$!%gDZw>NUZH2}-%~)Tj2@BgO*8WVpzFl4h-t%iMO4 zb1euXC-8YLTWrkPWmeXd8n?F~^lxt`^1_|a3EPg(Bg=K$_fER;*=}Ho%j}DE=l%x7 z@f+X}-XMe&aTyy#$2u{vjLW19t3jq$p1?fzF5kbyVt*e7^+)QQ%f98=xe{}0Z08z} zVL<GCe$^TK0kchJzl$AMC$>LfRVcwkS8Hxt993|lab6S~s0vDit-e5|+%V1KIEn$u rWa1afZ$kGS)A6&<@=<pcwg$SYA&_&u=LIx&?Y?+@E@~8kAgJ^Y{u-UY diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/install.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/install.cpython-38.pyc index 3c79b4eedf2700173ea586c77bddbe1f104ef58d..948c8247ccdfb5aa7887c5d0b711d496f611c0b0 100644 GIT binary patch literal 17324 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 literal 13040 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/list.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/list.cpython-38.pyc index a8e6e53e097c487765a941d56ca08b1068337953..6e4f44d2632ee75f76dbd67fa3c961644ebdbe00 100644 GIT binary patch literal 8833 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 Q7Uj{PqR;$X>DU+l2b*Xn-~a#s literal 8981 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 ZAfLiGvX<g+9@bN{=f7io(_io}{tvkl4}kyx diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/search.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/search.cpython-38.pyc index 3c8a9d030da2be1d7c05159fbfc37d64a1008a75..d1fbc9ed20756c0671eea45b4268ea47cb605638 100644 GIT binary patch delta 2513 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 CS7y2Z delta 2172 zcmZ8i>u(iB6rY*hySw+<+foY3qqookx3&cpV{8bP04jo59tPN`>*db2?Csv&%gkOL z&0?bvNlX;XeDI5jZA?t~q>10vKfuKAlW2?@4gUgS@SN@CVRtfT=A3z)-+9d0FL(U3 zZQ`wRxj^9i`_i}XhU*CV1DPj36POw3@=x;FL|AMOxC4}M!t>#0U%fc(v*j)R))ndw zze;$8_uU}8&+of#xHVqo{Wpj^!iV?(Uw4DL+xQ?~50dSiog(!O>Lco@`*c`6&xY2Q z4#w?vBjSgJh((=hbN1@&5%mh&{$BG*EI2oM0yzT{pSYA0mvQPEoVg}9+#EMui|1VX zCYht$;`R;4b-2UxpgPYBya;3ACNYUy1Q;cC)Hva2OZpAbyr8}?YD<exoywRRVyMl< zqSk3N7aH@voI2g4J?%Ik5(j!8^bAcx5}K0hti@8AvQH@`DQOuklT*&P!ObMs0%Y9! z#L8CeWry3iV}+qd0gZEfk*SI)Hsp0qc00Zhc(-;uFNlJ~^VA3C!IuqfN<W;_W<$(N z%@!`-p*rt*&9EV*=iMRq_U}&Go!y<FGZ{oOX@ueAa~Jk@uRI?&P^gA-Bhz9d+&hA} z2Z0beKrPA$qu5N!{;}-Ep;a&R0yFgp!eZ|GoT$PfHDm2qD#JvVJ0ge@Px!JMCQ{@< zCeSf;TWrO3JMJVw97!>ZT<&7m7gu$@bF~wA7lK4;6R8-(W7{8*QQT{YZZrWCiFgS> zbD)=~!%SMB1y)jjS@kWLzXx&CX&@<Uk!waumLUQw^wzW*w<ng)5Jp}gC&)?i6}TD4 zv#Sm_j@Owsqek1;w(LR*0x$*{Xo-HfOIN(}-5}(i^rZv?1Zol%t`txC;*u|BMSSII z=8d|O*(wmNcm}uRgNXZAysik<5B8>=Q@HSd^Rk2cKrTx_2*jX76?HZ<NXwctxg_?0 zROh-9l21H~^L4>|6bm0*eX$$Bc*&10Ww8{yVL7``mwUO;^uy5eo=}PL7U<S2tDb_1 z#5kf$p@B<HRw_ExY!wszyKkHZ9Y+kS%55+h-B33&V5>r>CzRrVsu!l0&`j+-d@<U9 z&_3QRX7I8#PS^pm!_ehsAjGmD##v(}mZjsrC2PPKq!lJ`XVbu4y{`!4qv*Q;IaR+G z_R)=MxcKIh#Y?=LQeN3W2FV7pY^T-=y=L(~kX6%MYR|DDl3H`d5V@9L{4jBr^J#ts zA8jr*7OdM;Oeb`?kmlf2At_!bw@$-ap;b!l1t#v}e%_BfKHq3>#t%H?lk#k8U#G1K zTr-+2txN4}V=3bXSGhC2v^-1Bkc-nMN%|HFaN;B-*v^6MEcC24tXD@$vxl;1900TL z(aE}@jnI$8Az-yJ?<bJUY-*2q4fr)q)`fjxAd_a??(Fx~FC~8og8+rL)DdyZZzdkT zfjSe%@Gja}b6mUu;uds?e*+6%)8m+GA`p)_0_1KE2}VTI!aZ8Mi@{pVk4=ut+GK4^ zF4|+Vwrfn*7uEf8cetvJcH@e`J9Y7LEEa-j9^P7#StO3C+m%gYVLT7XugxHui**%@ z^f(wIg7aN0DWU>r#f;LGiKU{*a<3mP@tSeiZAaeafF~ES%AyB)#n9*8!|Yu3)Z+xV z!balDM3)jMt)MA8t<5lqd~IfG*QD+^Xm3E5uV;S)sy^@AwrdEB6JZZ5NM9&Y&>ZMh zR)N<IRrY~pJWZ=qjH|nS)6-`VzXzmFSKYWq1IG4a)WCocnt7(qjvud&s&}fJteqef z=hXYvozzudS4VSrm8*WP9#DJxYa>{MvvRD5pz=?_UnKEG)Ci||d^rl^23KeM533*h zx6rcswSVLUdQ<1Y^kbRV#Y=epZ6x>~%HE$qn^yz$7-}{fg$3>GYsb7B`upKA61hYD UHn4uM3WoO@D;U)YXLF(c9~G47wg3PC diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/show.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/show.cpython-38.pyc index de3e6294831103940dc113f1c682454b0a151055..b585ce25be9daf9d650f32ef0ec94e31b62c94e6 100644 GIT binary patch literal 6478 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 C@?cc} literal 5825 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 KF*kS4y74ckoxNcI diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-38.pyc index 7462f646a4350e3d37ac3cfeb67c6fb0b5589c24..ea18121d0c4a8f7e088d2a8e6c62ab50e60d4232 100644 GIT binary patch delta 1604 zcmZWp%}*Og6rb50uh+%~V;oEnC5Dg+m&88wLs1(=NQS0W6I6j{l~t?N#xsV6{V+4L z2<RfDk}Iv~UO2+3>7|$4+H>zYw3og152)1kRH>nF3^XK})%)$6_ujnSd0&53j;b@u z#bO@8sz3k9{-c1<?`m^-WneQ4Bz`=c`TPrtsOk0l1J;0FvPu}iKIaYkWvkrd^WKnO zu__p`3O@o}pLfL{wuXDUf>-rNtPzavAzGyUj}h%>8J68A)>S&NgzBZkqYthPEiob7 zFldFo?*#OLyX6LToMxAnTdnz}rNd`8v3B@x^+tN#4TN+&&*p5y?(opJyABtOs(s{g z=CeR16?}6KPM04%{PdyS`e?rOiM_bIu<-H1J&+ooIbOsBaOA!#Wc%`^6|Vu!0*NUA zhAd2xrBQ6@RI>=xDS3>n49!pj-UiLW4a~H(9Gw5x`30P(-{TLlwzHg!>(yjXziYKI zxVu=2&jGc7#2i43*3cTJm}=?^D@ggL*@G;;(3mtw^R$l^Xz?J^lWNC0?N{fXKGP@g zl_BuLD+;O#)EDX`8Oyx02p1L1>->QDH4y&OX|9GoYx3<VT63F%x0}=nT;{byE}3X- zZSOQUS+Lpk+(*sswp<N^w;Q*c!j<e+*J-aiD@-KcW~N5cK8I2}>`F+RxB;HUBmmNq zUosP|u~!4qxMbYcmErkPRcHY9Lh&mwF*-&uKEcVfF|k*UjhILh8*BPLzJoT(F<#5e zp)cRx%}OKA#yEzw9Oxi<bJvvF*aST!>p<Hz)EU0`%K62O*_ep$q)GL)TnEYgKKcgl z<FB#oqa-Hl2F)B`2roG<oS-?>0Jq9f5!|X+4^U&BKwh-nT%6-i;@olR1YxxCL=LJt zNd7h^@nTZVzBT=o3V9=Ne70Mg7L3&<yKc9(%Disvl4`P^tY_cdE2l#%Oxl!noXC^5 zIO_$jDkLqsBJ>;y74C<Wr9`>pDuBGCz*L}O$g=>c(FwWl$kgz{w&Mxj*As5`Dn89c z7gfqflsvb|_@hv`dvZH9+R%Bf<SG^QJRgS_zpjjk!&d}Xy<iPOj|p3b_6t8V%0vfw zYIa<Ysh>;pFFMj1{NEJ%RIUmpdqsE#wX?%fe{dT(aUTF_c`ey9$L2MxVe;G{1}<X) zyn)H7c1kk9of@P7GJ?!gLnk<|?NnZ?HXa2F^=$H+d22b%L;{MIPk?v+o&wbdm!PJ$ z0|3K7LIu>sBu|Jr)RQjMN7KA*cOn^aX4_oN2P@gi-J5>{QrfWHKr$XUUZd@~4K<Zi zBw>beH9^zy*KJ^a$w+`1Wr7>Y&$;odDtFf4%ckIpo5`QKDMQr(&nMOV_+Brcqc0mq z()C0`Zg<^ag~KREsR>=#O9C&dt#PjFSANt*FI~PDi<+`B??8b?9=oeXhZqGYXz<{R Nrvy<q3mQ=Z{XeOfozwsT delta 1323 zcmZ8g&2Jnv6t`zQpSzp1Nty(LU=tG5ZIX=y=>erGkRWjYAyHZaD-~-xcADAD&Tec^ zXsU@Kkx1pTK$#1tk{o*j^&jBM5sA|rIFti_05>GGJdcuS)v?|izvt)odww53PW>~n zc&AqL5qy8|{rqKKLFg|n41WZKcY);g<HgO%4-j*icZ`_Fts}EF!u(HBqw@IAwR{aX zrg3p4N~8+nm<qm2w?wx?<0#?zDPEchhrQ~(d8Ux7`6c7Ze9K~_Wj{h&m|4s|c3Tc} zn0t&`?juA{%L5?q+1th!xKem&a)y)tU~Yc+aQx1>T<-<pPH>;gW{8LIG?WK43M4-R zrjWuJIx^ZuhBM<^j8TT#W}D<SGW8n#^(&drDy+(CeXBgRPHZ-!t)6X=S-dy`UWE21 z#x&Dt4X3bV+T%iKtiq)<N+LyRzHhC*V-`g6c&i|RxGxK1=c}i<@F)%AKuSuVqJQ68 zQJvmOFX}Cyy>0o;?bY<bTirk_^MN%#CMLn}D?oA{7{X&XU$bY|U%GhyMz_-m64pFN z4$pI}&2><kHh|<Gz%q1#GJJ}^`!)Z`o;{q%?2IUq*=_R(-$1()8E#weqq|E7j<Pcc z5@j-@Z-Qp}z}8mc_6s*|@2+P=exn>_Dp#k9kv^V8NBC>3JZ5EN$7Xh4C!3u3rwBZ~ zQF^KXQgsO~)R?max$heXZsv+7nR_yFiZI%JvWc#vPtYy&IbujRLf&!a@JIRg&b4a` zSCgQ_8?t^?a$cW<T-CRE+^e7K=Nb)M5N(q`cdj3f79;dt8pVuCE@jkBgafH4YLV>5 zf#QsIx{Qkj&<UM90W*Pwt(gU^AS?=%aP`*S3*wYZq31`8YmK+Z#l5bK)P7-yP>M)3 zJTaq>U)M}m?q#7%S6qhqkW_W)MJJ1e{C9W!@bZO%_5!snxe|4Kw`8;WswvWB1vYXW z7{XOdu!{|BATqE`8(+e{mh}41CpPp5DJ6ek42Wf5dteiNhaea134S;++&zBTK7i2h z^J8!MuuMc@r4nYUaAXSYCHBiU6stOz+F1vO9A=&lh59O-3LS4b3su-i&0I`8z&43d z9WPHlZj2T_rCX^=1qTlX7!@;6#3tS2Nj~b|oS81AC{bJ_LEPjILf%tQI4P|B7k>)d z`EUOG-Li@=n5HU<WwR5>u&h`KI22<Yu*w(<_XbowjrmPI#!`=V)qn-bEtmN}kS0Dv diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-38.pyc index acfb10ff10c3fceed08ae074cf995f24faa0854c..57758ff043a9af37b972bf9b69f162e2e20e87c0 100644 GIT binary patch literal 5118 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 literal 4881 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 MW7?c<I`z_j0b>i9uK)l5 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/check.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/check.py index 801cecc..b557ca6 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/check.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/check.py @@ -1,28 +1,37 @@ import logging from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import ERROR, SUCCESS from pip._internal.operations.check import ( - check_package_set, create_package_set_from_installed, + check_package_set, + create_package_set_from_installed, ) +from pip._internal.utils.misc import write_output +from pip._internal.utils.typing import MYPY_CHECK_RUNNING logger = logging.getLogger(__name__) +if MYPY_CHECK_RUNNING: + from typing import List, Any + from optparse import Values + class CheckCommand(Command): """Verify installed packages have compatible dependencies.""" - name = 'check' + usage = """ %prog [options]""" - summary = 'Verify installed packages have compatible dependencies.' def run(self, options, args): + # type: (Values, List[Any]) -> int + package_set, parsing_probs = create_package_set_from_installed() missing, conflicting = check_package_set(package_set) for project_name in missing: version = package_set[project_name].version for dependency in missing[project_name]: - logger.info( + write_output( "%s %s requires %s, which is not installed.", project_name, version, dependency[0], ) @@ -30,12 +39,13 @@ class CheckCommand(Command): for project_name in conflicting: version = package_set[project_name].version for dep_name, dep_version, req in conflicting[project_name]: - logger.info( + write_output( "%s %s has requirement %s, but you have %s %s.", project_name, version, req, dep_name, dep_version, ) if missing or conflicting or parsing_probs: - return 1 + return ERROR else: - logger.info("No broken requirements found.") + write_output("No broken requirements found.") + return SUCCESS diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/completion.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/completion.py index 2fcdd39..9b99f51 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/completion.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/completion.py @@ -4,32 +4,38 @@ import sys import textwrap from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import SUCCESS from pip._internal.utils.misc import get_prog +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List + from optparse import Values BASE_COMPLETION = """ -# pip %(shell)s completion start%(script)s# pip %(shell)s completion end +# pip {shell} completion start{script}# pip {shell} completion end """ COMPLETION_SCRIPTS = { 'bash': """ _pip_completion() - { - COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \\ + {{ + COMPREPLY=( $( COMP_WORDS="${{COMP_WORDS[*]}}" \\ COMP_CWORD=$COMP_CWORD \\ - PIP_AUTO_COMPLETE=1 $1 ) ) - } - complete -o default -F _pip_completion %(prog)s + PIP_AUTO_COMPLETE=1 $1 2>/dev/null ) ) + }} + complete -o default -F _pip_completion {prog} """, 'zsh': """ - function _pip_completion { + function _pip_completion {{ local words cword read -Ac words read -cn cword reply=( $( COMP_WORDS="$words[*]" \\ COMP_CWORD=$(( cword-1 )) \\ - PIP_AUTO_COMPLETE=1 $words[1] ) ) - } - compctl -K _pip_completion %(prog)s + PIP_AUTO_COMPLETE=1 $words[1] 2>/dev/null )) + }} + compctl -K _pip_completion {prog} """, 'fish': """ function __fish_complete_pip @@ -40,55 +46,53 @@ COMPLETION_SCRIPTS = { set -lx PIP_AUTO_COMPLETE 1 string split \\ -- (eval $COMP_WORDS[1]) end - complete -fa "(__fish_complete_pip)" -c %(prog)s + complete -fa "(__fish_complete_pip)" -c {prog} """, } class CompletionCommand(Command): """A helper command to be used for command completion.""" - name = 'completion' - summary = 'A helper command used for command completion.' + ignore_require_venv = True - def __init__(self, *args, **kw): - super(CompletionCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option( + def add_options(self): + # type: () -> None + self.cmd_opts.add_option( '--bash', '-b', action='store_const', const='bash', dest='shell', help='Emit completion code for bash') - cmd_opts.add_option( + self.cmd_opts.add_option( '--zsh', '-z', action='store_const', const='zsh', dest='shell', help='Emit completion code for zsh') - cmd_opts.add_option( + self.cmd_opts.add_option( '--fish', '-f', action='store_const', const='fish', dest='shell', help='Emit completion code for fish') - self.parser.insert_option_group(0, cmd_opts) + self.parser.insert_option_group(0, self.cmd_opts) def run(self, options, args): + # type: (Values, List[str]) -> int """Prints the completion code of the given shell""" shells = COMPLETION_SCRIPTS.keys() shell_options = ['--' + shell for shell in sorted(shells)] if options.shell in shells: script = textwrap.dedent( - COMPLETION_SCRIPTS.get(options.shell, '') % { - 'prog': get_prog(), - } + COMPLETION_SCRIPTS.get(options.shell, '').format( + prog=get_prog()) ) - print(BASE_COMPLETION % {'script': script, 'shell': options.shell}) + print(BASE_COMPLETION.format(script=script, shell=options.shell)) + return SUCCESS else: sys.stderr.write( - 'ERROR: You must pass %s\n' % ' or '.join(shell_options) + 'ERROR: You must pass {}\n' .format(' or '.join(shell_options)) ) + return SUCCESS diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/configuration.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/configuration.py index 1ec77d2..f9b3ab7 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/configuration.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/configuration.py @@ -5,34 +5,44 @@ import subprocess from pip._internal.cli.base_command import Command from pip._internal.cli.status_codes import ERROR, SUCCESS from pip._internal.configuration import ( - Configuration, get_configuration_files, kinds, + Configuration, + get_configuration_files, + kinds, ) from pip._internal.exceptions import PipError -from pip._internal.utils.deprecation import deprecated -from pip._internal.utils.misc import get_prog -from pip._internal.utils.virtualenv import running_under_virtualenv +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import get_prog, write_output +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Any, Optional + from optparse import Values + + from pip._internal.configuration import Kind logger = logging.getLogger(__name__) class ConfigurationCommand(Command): - """Manage local and global configuration. + """ + Manage local and global configuration. - Subcommands: + Subcommands: - list: List the active configuration (or from the file specified) - edit: Edit the configuration file in an editor - get: Get the value associated with name - set: Set the name=value - unset: Unset the value associated with name + - list: List the active configuration (or from the file specified) + - edit: Edit the configuration file in an editor + - get: Get the value associated with name + - set: Set the name=value + - unset: Unset the value associated with name + - debug: List the configuration files and values defined under them - If none of --user, --global and --site are passed, a virtual - environment configuration file is used if one is active and the file - exists. Otherwise, all modifications happen on the to the user file by - default. + If none of --user, --global and --site are passed, a virtual + environment configuration file is used if one is active and the file + exists. Otherwise, all modifications happen on the to the user file by + default. """ - name = 'config' + ignore_require_venv = True usage = """ %prog [<file-option>] list %prog [<file-option>] [--editor <editor-path>] edit @@ -40,15 +50,11 @@ class ConfigurationCommand(Command): %prog [<file-option>] get name %prog [<file-option>] set name value %prog [<file-option>] unset name + %prog [<file-option>] debug """ - summary = "Manage local and global configuration." - - def __init__(self, *args, **kwargs): - super(ConfigurationCommand, self).__init__(*args, **kwargs) - - self.configuration = None - + def add_options(self): + # type: () -> None self.cmd_opts.add_option( '--editor', dest='editor', @@ -84,32 +90,24 @@ class ConfigurationCommand(Command): help='Use the current environment configuration file only' ) - self.cmd_opts.add_option( - '--venv', - dest='venv_file', - action='store_true', - default=False, - help=( - '[Deprecated] Use the current environment configuration ' - 'file in a virtual environment only' - ) - ) - self.parser.insert_option_group(0, self.cmd_opts) def run(self, options, args): + # type: (Values, List[str]) -> int handlers = { "list": self.list_values, "edit": self.open_in_editor, "get": self.get_name, "set": self.set_name_value, - "unset": self.unset_name + "unset": self.unset_name, + "debug": self.list_config_values, } # Determine action if not args or args[0] not in handlers: - logger.error("Need an action ({}) to perform.".format( - ", ".join(sorted(handlers))) + logger.error( + "Need an action (%s) to perform.", + ", ".join(sorted(handlers)), ) return ERROR @@ -141,21 +139,7 @@ class ConfigurationCommand(Command): return SUCCESS def _determine_file(self, options, need_value): - # Convert legacy venv_file option to site_file or error - if options.venv_file and not options.site_file: - if running_under_virtualenv(): - options.site_file = True - deprecated( - "The --venv option has been deprecated.", - replacement="--site", - gone_in="19.3", - ) - else: - raise PipError( - "Legacy --venv option requires a virtual environment. " - "Use --site instead." - ) - + # type: (Values, bool) -> Optional[Kind] file_options = [key for key, value in ( (kinds.USER, options.user_file), (kinds.GLOBAL, options.global_file), @@ -182,30 +166,70 @@ class ConfigurationCommand(Command): ) def list_values(self, options, args): + # type: (Values, List[str]) -> None self._get_n_args(args, "list", n=0) for key, value in sorted(self.configuration.items()): - logger.info("%s=%r", key, value) + write_output("%s=%r", key, value) def get_name(self, options, args): + # type: (Values, List[str]) -> None key = self._get_n_args(args, "get [name]", n=1) value = self.configuration.get_value(key) - logger.info("%s", value) + write_output("%s", value) def set_name_value(self, options, args): + # type: (Values, List[str]) -> None key, value = self._get_n_args(args, "set [name] [value]", n=2) self.configuration.set_value(key, value) self._save_configuration() def unset_name(self, options, args): + # type: (Values, List[str]) -> None key = self._get_n_args(args, "unset [name]", n=1) self.configuration.unset_value(key) self._save_configuration() + def list_config_values(self, options, args): + # type: (Values, List[str]) -> None + """List config key-value pairs across different config files""" + self._get_n_args(args, "debug", n=0) + + self.print_env_var_values() + # Iterate over config files and print if they exist, and the + # key-value pairs present in them if they do + for variant, files in sorted(self.configuration.iter_config_files()): + write_output("%s:", variant) + for fname in files: + with indent_log(): + file_exists = os.path.exists(fname) + write_output("%s, exists: %r", + fname, file_exists) + if file_exists: + self.print_config_file_values(variant) + + def print_config_file_values(self, variant): + # type: (Kind) -> None + """Get key-value pairs from the file of a variant""" + for name, value in self.configuration.\ + get_values_in_config(variant).items(): + with indent_log(): + write_output("%s: %s", name, value) + + def print_env_var_values(self): + # type: () -> None + """Get key-values pairs present as environment variables""" + write_output("%s:", 'env_var') + with indent_log(): + for key, value in sorted(self.configuration.get_environ_vars()): + env_var = 'PIP_{}'.format(key.upper()) + write_output("%s=%r", env_var, value) + def open_in_editor(self, options, args): + # type: (Values, List[str]) -> None editor = self._determine_editor(options) fname = self.configuration.get_file_to_edit() @@ -221,6 +245,7 @@ class ConfigurationCommand(Command): ) def _get_n_args(self, args, example, n): + # type: (List[str], str, int) -> Any """Helper to make sure the command got the right number of arguments """ if len(args) != n: @@ -236,18 +261,19 @@ class ConfigurationCommand(Command): return args def _save_configuration(self): + # type: () -> None # We successfully ran a modifying command. Need to save the # configuration. try: self.configuration.save() except Exception: - logger.error( - "Unable to save configuration. Please report this as a bug.", - exc_info=1 + logger.exception( + "Unable to save configuration. Please report this as a bug." ) raise PipError("Internal Error.") def _determine_editor(self, options): + # type: (Values) -> str if options.editor is not None: return options.editor elif "VISUAL" in os.environ: diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/debug.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/debug.py index eb4f8c4..ff369d7 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/debug.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/debug.py @@ -2,8 +2,14 @@ from __future__ import absolute_import import locale import logging +import os import sys +import pip._vendor +from pip._vendor import pkg_resources +from pip._vendor.certifi import where + +from pip import __file__ as pip_location from pip._internal.cli import cmdoptions from pip._internal.cli.base_command import Command from pip._internal.cli.cmdoptions import make_target_python @@ -11,18 +17,19 @@ from pip._internal.cli.status_codes import SUCCESS from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import get_pip_version from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.wheel import format_tag if MYPY_CHECK_RUNNING: - from typing import Any, List + from types import ModuleType + from typing import List, Optional, Dict from optparse import Values + from pip._internal.configuration import Configuration logger = logging.getLogger(__name__) def show_value(name, value): - # type: (str, str) -> None - logger.info('{}: {}'.format(name, value)) + # type: (str, Optional[str]) -> None + logger.info('%s: %s', name, value) def show_sys_implementation(): @@ -38,6 +45,88 @@ def show_sys_implementation(): show_value('name', implementation_name) +def create_vendor_txt_map(): + # type: () -> Dict[str, str] + vendor_txt_path = os.path.join( + os.path.dirname(pip_location), + '_vendor', + 'vendor.txt' + ) + + with open(vendor_txt_path) as f: + # Purge non version specifying lines. + # Also, remove any space prefix or suffixes (including comments). + lines = [line.strip().split(' ', 1)[0] + for line in f.readlines() if '==' in line] + + # Transform into "module" -> version dict. + return dict(line.split('==', 1) for line in lines) # type: ignore + + +def get_module_from_module_name(module_name): + # type: (str) -> ModuleType + # Module name can be uppercase in vendor.txt for some reason... + module_name = module_name.lower() + # PATCH: setuptools is actually only pkg_resources. + if module_name == 'setuptools': + module_name = 'pkg_resources' + + __import__( + 'pip._vendor.{}'.format(module_name), + globals(), + locals(), + level=0 + ) + return getattr(pip._vendor, module_name) + + +def get_vendor_version_from_module(module_name): + # type: (str) -> Optional[str] + module = get_module_from_module_name(module_name) + version = getattr(module, '__version__', None) + + if not version: + # Try to find version in debundled module info + # The type for module.__file__ is Optional[str] in + # Python 2, and str in Python 3. The type: ignore is + # added to account for Python 2, instead of a cast + # and should be removed once we drop Python 2 support + pkg_set = pkg_resources.WorkingSet( + [os.path.dirname(module.__file__)] # type: ignore + ) + package = pkg_set.find(pkg_resources.Requirement.parse(module_name)) + version = getattr(package, 'version', None) + + return version + + +def show_actual_vendor_versions(vendor_txt_versions): + # type: (Dict[str, str]) -> None + """Log the actual version and print extra info if there is + a conflict or if the actual version could not be imported. + """ + for module_name, expected_version in vendor_txt_versions.items(): + extra_message = '' + actual_version = get_vendor_version_from_module(module_name) + if not actual_version: + extra_message = ' (Unable to locate actual module version, using'\ + ' vendor.txt specified version)' + actual_version = expected_version + elif actual_version != expected_version: + extra_message = ' (CONFLICT: vendor.txt suggests version should'\ + ' be {})'.format(expected_version) + logger.info('%s==%s%s', module_name, actual_version, extra_message) + + +def show_vendor_versions(): + # type: () -> None + logger.info('vendored library versions:') + + vendor_txt_versions = create_vendor_txt_map() + with indent_log(): + show_actual_vendor_versions(vendor_txt_versions) + + def show_tags(options): # type: (Values) -> None tag_limit = 10 @@ -62,7 +151,7 @@ def show_tags(options): with indent_log(): for tag in tags: - logger.info(format_tag(tag)) + logger.info(str(tag)) if tags_limited: msg = ( @@ -72,26 +161,44 @@ def show_tags(options): logger.info(msg) +def ca_bundle_info(config): + # type: (Configuration) -> str + levels = set() + for key, _ in config.items(): + levels.add(key.split('.')[0]) + + if not levels: + return "Not specified" + + levels_that_override_global = ['install', 'wheel', 'download'] + global_overriding_level = [ + level for level in levels if level in levels_that_override_global + ] + if not global_overriding_level: + return 'global' + + if 'global' in levels: + levels.remove('global') + return ", ".join(levels) + + class DebugCommand(Command): """ Display debug information. """ - name = 'debug' usage = """ %prog <options>""" - summary = 'Show information useful for debugging.' ignore_require_venv = True - def __init__(self, *args, **kw): - super(DebugCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - cmdoptions.add_target_python_options(cmd_opts) - self.parser.insert_option_group(0, cmd_opts) + def add_options(self): + # type: () -> None + cmdoptions.add_target_python_options(self.cmd_opts) + self.parser.insert_option_group(0, self.cmd_opts) + self.parser.config.load() def run(self, options, args): - # type: (Values, List[Any]) -> int + # type: (Values, List[str]) -> int logger.warning( "This command is only meant for debugging. " "Do not use this with automation for parsing and getting these " @@ -109,6 +216,14 @@ class DebugCommand(Command): show_value('sys.platform', sys.platform) show_sys_implementation() + show_value("'cert' config value", ca_bundle_info(self.parser.config)) + show_value("REQUESTS_CA_BUNDLE", os.environ.get('REQUESTS_CA_BUNDLE')) + show_value("CURL_CA_BUNDLE", os.environ.get('CURL_CA_BUNDLE')) + show_value("pip._vendor.certifi.where()", where()) + show_value("pip._vendor.DEBUNDLED", pip._vendor.DEBUNDLED) + + show_vendor_versions() + show_tags(options) return SUCCESS diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/download.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/download.py index 5642b56..46e8371 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/download.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/download.py @@ -4,15 +4,17 @@ import logging import os from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import RequirementCommand from pip._internal.cli.cmdoptions import make_target_python -from pip._internal.legacy_resolve import Resolver -from pip._internal.operations.prepare import RequirementPreparer -from pip._internal.req import RequirementSet -from pip._internal.req.req_tracker import RequirementTracker -from pip._internal.utils.filesystem import check_path_owner -from pip._internal.utils.misc import ensure_dir, normalize_path +from pip._internal.cli.req_command import RequirementCommand, with_cleanup +from pip._internal.cli.status_codes import SUCCESS +from pip._internal.req.req_tracker import get_requirement_tracker +from pip._internal.utils.misc import ensure_dir, normalize_path, write_output from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List logger = logging.getLogger(__name__) @@ -29,7 +31,6 @@ class DownloadCommand(RequirementCommand): pip also supports downloading from "requirements files", which provide an easy way to specify a whole environment to be downloaded. """ - name = 'download' usage = """ %prog [options] <requirement specifier> [package-index-options] ... @@ -38,31 +39,25 @@ class DownloadCommand(RequirementCommand): %prog [options] <local project path> ... %prog [options] <archive url/path> ...""" - summary = 'Download packages.' + def add_options(self): + # type: () -> None + self.cmd_opts.add_option(cmdoptions.constraints()) + self.cmd_opts.add_option(cmdoptions.requirements()) + self.cmd_opts.add_option(cmdoptions.build_dir()) + self.cmd_opts.add_option(cmdoptions.no_deps()) + self.cmd_opts.add_option(cmdoptions.global_options()) + self.cmd_opts.add_option(cmdoptions.no_binary()) + self.cmd_opts.add_option(cmdoptions.only_binary()) + self.cmd_opts.add_option(cmdoptions.prefer_binary()) + self.cmd_opts.add_option(cmdoptions.src()) + self.cmd_opts.add_option(cmdoptions.pre()) + self.cmd_opts.add_option(cmdoptions.require_hashes()) + self.cmd_opts.add_option(cmdoptions.progress_bar()) + self.cmd_opts.add_option(cmdoptions.no_build_isolation()) + self.cmd_opts.add_option(cmdoptions.use_pep517()) + self.cmd_opts.add_option(cmdoptions.no_use_pep517()) - def __init__(self, *args, **kw): - super(DownloadCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option(cmdoptions.constraints()) - cmd_opts.add_option(cmdoptions.requirements()) - cmd_opts.add_option(cmdoptions.build_dir()) - cmd_opts.add_option(cmdoptions.no_deps()) - cmd_opts.add_option(cmdoptions.global_options()) - cmd_opts.add_option(cmdoptions.no_binary()) - cmd_opts.add_option(cmdoptions.only_binary()) - cmd_opts.add_option(cmdoptions.prefer_binary()) - cmd_opts.add_option(cmdoptions.src()) - cmd_opts.add_option(cmdoptions.pre()) - cmd_opts.add_option(cmdoptions.no_clean()) - cmd_opts.add_option(cmdoptions.require_hashes()) - cmd_opts.add_option(cmdoptions.progress_bar()) - cmd_opts.add_option(cmdoptions.no_build_isolation()) - cmd_opts.add_option(cmdoptions.use_pep517()) - cmd_opts.add_option(cmdoptions.no_use_pep517()) - - cmd_opts.add_option( + self.cmd_opts.add_option( '-d', '--dest', '--destination-dir', '--destination-directory', dest='download_dir', metavar='dir', @@ -70,7 +65,7 @@ class DownloadCommand(RequirementCommand): help=("Download packages into <dir>."), ) - cmdoptions.add_target_python_options(cmd_opts) + cmdoptions.add_target_python_options(self.cmd_opts) index_opts = cmdoptions.make_option_group( cmdoptions.index_group, @@ -78,9 +73,12 @@ class DownloadCommand(RequirementCommand): ) self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) + self.parser.insert_option_group(0, self.cmd_opts) + @with_cleanup def run(self, options, args): + # type: (Values, List[str]) -> int + options.ignore_installed = True # editable doesn't really make sense for `pip download`, but the bowels # of the RequirementSet code require that property. @@ -88,81 +86,58 @@ class DownloadCommand(RequirementCommand): cmdoptions.check_dist_restriction(options) - options.src_dir = os.path.abspath(options.src_dir) options.download_dir = normalize_path(options.download_dir) ensure_dir(options.download_dir) - with self._build_session(options) as session: - target_python = make_target_python(options) - finder = self._build_package_finder( - options=options, - session=session, - target_python=target_python, - ) - build_delete = (not (options.no_clean or options.build_dir)) - if options.cache_dir and not check_path_owner(options.cache_dir): - logger.warning( - "The directory '%s' or its parent directory is not owned " - "by the current user and caching wheels has been " - "disabled. check the permissions and owner of that " - "directory. If executing pip with sudo, you may want " - "sudo's -H flag.", - options.cache_dir, - ) - options.cache_dir = None + session = self.get_default_session(options) - with RequirementTracker() as req_tracker, TempDirectory( - options.build_dir, delete=build_delete, kind="download" - ) as directory: + target_python = make_target_python(options) + finder = self._build_package_finder( + options=options, + session=session, + target_python=target_python, + ) + build_delete = (not (options.no_clean or options.build_dir)) - requirement_set = RequirementSet( - require_hashes=options.require_hashes, - ) - self.populate_requirement_set( - requirement_set, - args, - options, - finder, - session, - self.name, - None - ) + req_tracker = self.enter_context(get_requirement_tracker()) - preparer = RequirementPreparer( - build_dir=directory.path, - src_dir=options.src_dir, - download_dir=options.download_dir, - wheel_download_dir=None, - progress_bar=options.progress_bar, - build_isolation=options.build_isolation, - req_tracker=req_tracker, - ) + directory = TempDirectory( + options.build_dir, + delete=build_delete, + kind="download", + globally_managed=True, + ) - resolver = Resolver( - preparer=preparer, - finder=finder, - session=session, - wheel_cache=None, - use_user_site=False, - upgrade_strategy="to-satisfy-only", - force_reinstall=False, - ignore_dependencies=options.ignore_dependencies, - py_version_info=options.python_version, - ignore_requires_python=False, - ignore_installed=True, - isolated=options.isolated_mode, - ) - resolver.resolve(requirement_set) + reqs = self.get_requirements(args, options, finder, session) - downloaded = ' '.join([ - req.name for req in requirement_set.successfully_downloaded - ]) - if downloaded: - logger.info('Successfully downloaded %s', downloaded) + preparer = self.make_requirement_preparer( + temp_build_dir=directory, + options=options, + req_tracker=req_tracker, + session=session, + finder=finder, + download_dir=options.download_dir, + use_user_site=False, + ) - # Clean up - if not options.no_clean: - requirement_set.cleanup_files() + resolver = self.make_resolver( + preparer=preparer, + finder=finder, + options=options, + py_version_info=options.python_version, + ) - return requirement_set + self.trace_basic_info(finder) + + requirement_set = resolver.resolve( + reqs, check_supported_wheels=True + ) + + downloaded = ' '.join([req.name # type: ignore + for req in requirement_set.requirements.values() + if req.successfully_downloaded]) + if downloaded: + write_output('Successfully downloaded %s', downloaded) + + return SUCCESS diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/freeze.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/freeze.py index 9fc5b04..2071fba 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/freeze.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/freeze.py @@ -5,12 +5,18 @@ import sys from pip._internal.cache import WheelCache from pip._internal.cli import cmdoptions from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import SUCCESS from pip._internal.models.format_control import FormatControl from pip._internal.operations.freeze import freeze from pip._internal.utils.compat import stdlib_pkgs +from pip._internal.utils.typing import MYPY_CHECK_RUNNING DEV_PKGS = {'pip', 'setuptools', 'distribute', 'wheel'} +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List + class FreezeCommand(Command): """ @@ -18,15 +24,13 @@ class FreezeCommand(Command): packages are listed in a case-insensitive sorted order. """ - name = 'freeze' + usage = """ %prog [options]""" - summary = 'Output installed packages in requirements format.' log_streams = ("ext://sys.stderr", "ext://sys.stderr") - def __init__(self, *args, **kw): - super(FreezeCommand, self).__init__(*args, **kw) - + def add_options(self): + # type: () -> None self.cmd_opts.add_option( '-r', '--requirement', dest='requirements', @@ -63,7 +67,7 @@ class FreezeCommand(Command): dest='freeze_all', action='store_true', help='Do not skip these packages in the output:' - ' %s' % ', '.join(DEV_PKGS)) + ' {}'.format(', '.join(DEV_PKGS))) self.cmd_opts.add_option( '--exclude-editable', dest='exclude_editable', @@ -73,6 +77,7 @@ class FreezeCommand(Command): self.parser.insert_option_group(0, self.cmd_opts) def run(self, options, args): + # type: (Values, List[str]) -> int format_control = FormatControl(set(), set()) wheel_cache = WheelCache(options.cache_dir, format_control) skip = set(stdlib_pkgs) @@ -87,15 +92,12 @@ class FreezeCommand(Command): local_only=options.local, user_only=options.user, paths=options.path, - skip_regex=options.skip_requirements_regex, isolated=options.isolated_mode, wheel_cache=wheel_cache, skip=skip, exclude_editable=options.exclude_editable, ) - try: - for line in freeze(**freeze_kwargs): - sys.stdout.write(line + '\n') - finally: - wheel_cache.cleanup() + for line in freeze(**freeze_kwargs): + sys.stdout.write(line + '\n') + return SUCCESS diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/hash.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/hash.py index 423440e..37831c3 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/hash.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/hash.py @@ -5,9 +5,14 @@ import logging import sys from pip._internal.cli.base_command import Command -from pip._internal.cli.status_codes import ERROR +from pip._internal.cli.status_codes import ERROR, SUCCESS from pip._internal.utils.hashes import FAVORITE_HASH, STRONG_HASHES -from pip._internal.utils.misc import read_chunks +from pip._internal.utils.misc import read_chunks, write_output +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List logger = logging.getLogger(__name__) @@ -18,37 +23,38 @@ class HashCommand(Command): These can be used with --hash in a requirements file to do repeatable installs. - """ - name = 'hash' + usage = '%prog [options] <file> ...' - summary = 'Compute hashes of package archives.' ignore_require_venv = True - def __init__(self, *args, **kw): - super(HashCommand, self).__init__(*args, **kw) + def add_options(self): + # type: () -> None self.cmd_opts.add_option( '-a', '--algorithm', dest='algorithm', choices=STRONG_HASHES, action='store', default=FAVORITE_HASH, - help='The hash algorithm to use: one of %s' % - ', '.join(STRONG_HASHES)) + help='The hash algorithm to use: one of {}'.format( + ', '.join(STRONG_HASHES))) self.parser.insert_option_group(0, self.cmd_opts) def run(self, options, args): + # type: (Values, List[str]) -> int if not args: self.parser.print_usage(sys.stderr) return ERROR algorithm = options.algorithm for path in args: - logger.info('%s:\n--hash=%s:%s', - path, algorithm, _hash_of_file(path, algorithm)) + write_output('%s:\n--hash=%s:%s', + path, algorithm, _hash_of_file(path, algorithm)) + return SUCCESS def _hash_of_file(path, algorithm): + # type: (str, str) -> str """Return the hash digest of a file.""" with open(path, 'rb') as archive: hash = hashlib.new(algorithm) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/help.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/help.py index 49a81cb..a2edc29 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/help.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/help.py @@ -3,18 +3,25 @@ from __future__ import absolute_import from pip._internal.cli.base_command import Command from pip._internal.cli.status_codes import SUCCESS from pip._internal.exceptions import CommandError +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List + from optparse import Values class HelpCommand(Command): """Show help for commands""" - name = 'help' + usage = """ %prog <command>""" - summary = 'Show help for commands.' ignore_require_venv = True def run(self, options, args): - from pip._internal.commands import commands_dict, get_similar_commands + # type: (Values, List[str]) -> int + from pip._internal.commands import ( + commands_dict, create_command, get_similar_commands, + ) try: # 'pip help' with no args is handled by pip.__init__.parseopt() @@ -25,13 +32,13 @@ class HelpCommand(Command): if cmd_name not in commands_dict: guess = get_similar_commands(cmd_name) - msg = ['unknown command "%s"' % cmd_name] + msg = ['unknown command "{}"'.format(cmd_name)] if guess: - msg.append('maybe you meant "%s"' % guess) + msg.append('maybe you meant "{}"'.format(guess)) raise CommandError(' - '.join(msg)) - command = commands_dict[cmd_name]() + command = create_command(cmd_name) command.parser.print_help() return SUCCESS diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/install.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/install.py index ebeceac..704e2d6 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/install.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/install.py @@ -5,71 +5,61 @@ import logging import operator import os import shutil +import site from optparse import SUPPRESS_HELP from pip._vendor import pkg_resources +from pip._vendor.packaging.utils import canonicalize_name from pip._internal.cache import WheelCache from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import RequirementCommand from pip._internal.cli.cmdoptions import make_target_python -from pip._internal.cli.status_codes import ERROR -from pip._internal.exceptions import ( - CommandError, InstallationError, PreviousBuildDirError, -) -from pip._internal.legacy_resolve import Resolver +from pip._internal.cli.req_command import RequirementCommand, with_cleanup +from pip._internal.cli.status_codes import ERROR, SUCCESS +from pip._internal.exceptions import CommandError, InstallationError from pip._internal.locations import distutils_scheme from pip._internal.operations.check import check_install_conflicts -from pip._internal.operations.prepare import RequirementPreparer -from pip._internal.req import RequirementSet, install_given_reqs -from pip._internal.req.req_tracker import RequirementTracker -from pip._internal.utils.filesystem import check_path_owner +from pip._internal.req import install_given_reqs +from pip._internal.req.req_tracker import get_requirement_tracker +from pip._internal.utils.datetime import today_is_later_than +from pip._internal.utils.distutils_args import parse_distutils_args +from pip._internal.utils.filesystem import test_writable_dir from pip._internal.utils.misc import ( - ensure_dir, get_installed_version, + ensure_dir, + get_installed_version, + get_pip_version, protect_pip_from_modification_on_windows, + write_output, ) from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING from pip._internal.utils.virtualenv import virtualenv_no_global -from pip._internal.wheel import WheelBuilder +from pip._internal.wheel_builder import build, should_build_for_install_command + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import Iterable, List, Optional + + from pip._internal.models.format_control import FormatControl + from pip._internal.operations.check import ConflictDetails + from pip._internal.req.req_install import InstallRequirement + from pip._internal.wheel_builder import BinaryAllowedPredicate + logger = logging.getLogger(__name__) -def is_wheel_installed(): - """ - Return whether the wheel package is installed. - """ - try: - import wheel # noqa: F401 - except ImportError: - return False +def get_check_binary_allowed(format_control): + # type: (FormatControl) -> BinaryAllowedPredicate + def check_binary_allowed(req): + # type: (InstallRequirement) -> bool + if req.use_pep517: + return True + canonical_name = canonicalize_name(req.name) + allowed_formats = format_control.get_allowed_formats(canonical_name) + return "binary" in allowed_formats - return True - - -def build_wheels(builder, pep517_requirements, legacy_requirements, session): - """ - Build wheels for requirements, depending on whether wheel is installed. - """ - # We don't build wheels for legacy requirements if wheel is not installed. - should_build_legacy = is_wheel_installed() - - # Always build PEP 517 requirements - build_failures = builder.build( - pep517_requirements, - session=session, autobuilding=True - ) - - if should_build_legacy: - # We don't care about failures building legacy - # requirements, as we'll fall through to a direct - # install for those. - builder.build( - legacy_requirements, - session=session, autobuilding=True - ) - - return build_failures + return check_binary_allowed class InstallCommand(RequirementCommand): @@ -81,10 +71,9 @@ class InstallCommand(RequirementCommand): - Local project directories. - Local or remote source archives. - pip also supports installing from "requirements files," which provide + pip also supports installing from "requirements files", which provide an easy way to specify a whole environment to be installed. """ - name = 'install' usage = """ %prog [options] <requirement specifier> [package-index-options] ... @@ -93,20 +82,15 @@ class InstallCommand(RequirementCommand): %prog [options] [-e] <local project path> ... %prog [options] <archive url/path> ...""" - summary = 'Install packages.' + def add_options(self): + # type: () -> None + self.cmd_opts.add_option(cmdoptions.requirements()) + self.cmd_opts.add_option(cmdoptions.constraints()) + self.cmd_opts.add_option(cmdoptions.no_deps()) + self.cmd_opts.add_option(cmdoptions.pre()) - def __init__(self, *args, **kw): - super(InstallCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option(cmdoptions.requirements()) - cmd_opts.add_option(cmdoptions.constraints()) - cmd_opts.add_option(cmdoptions.no_deps()) - cmd_opts.add_option(cmdoptions.pre()) - - cmd_opts.add_option(cmdoptions.editable()) - cmd_opts.add_option( + self.cmd_opts.add_option(cmdoptions.editable()) + self.cmd_opts.add_option( '-t', '--target', dest='target_dir', metavar='dir', @@ -116,9 +100,9 @@ class InstallCommand(RequirementCommand): '<dir>. Use --upgrade to replace existing packages in <dir> ' 'with new versions.' ) - cmdoptions.add_target_python_options(cmd_opts) + cmdoptions.add_target_python_options(self.cmd_opts) - cmd_opts.add_option( + self.cmd_opts.add_option( '--user', dest='use_user_site', action='store_true', @@ -126,19 +110,19 @@ class InstallCommand(RequirementCommand): "platform. Typically ~/.local/, or %APPDATA%\\Python on " "Windows. (See the Python documentation for site.USER_BASE " "for full details.)") - cmd_opts.add_option( + self.cmd_opts.add_option( '--no-user', dest='use_user_site', action='store_false', help=SUPPRESS_HELP) - cmd_opts.add_option( + self.cmd_opts.add_option( '--root', dest='root_path', metavar='dir', default=None, help="Install everything relative to this alternate root " "directory.") - cmd_opts.add_option( + self.cmd_opts.add_option( '--prefix', dest='prefix_path', metavar='dir', @@ -146,11 +130,11 @@ class InstallCommand(RequirementCommand): help="Installation prefix where lib, bin and other top-level " "folders are placed") - cmd_opts.add_option(cmdoptions.build_dir()) + self.cmd_opts.add_option(cmdoptions.build_dir()) - cmd_opts.add_option(cmdoptions.src()) + self.cmd_opts.add_option(cmdoptions.src()) - cmd_opts.add_option( + self.cmd_opts.add_option( '-U', '--upgrade', dest='upgrade', action='store_true', @@ -159,7 +143,7 @@ class InstallCommand(RequirementCommand): 'upgrade-strategy used.' ) - cmd_opts.add_option( + self.cmd_opts.add_option( '--upgrade-strategy', dest='upgrade_strategy', default='only-if-needed', @@ -173,28 +157,32 @@ class InstallCommand(RequirementCommand): 'satisfy the requirements of the upgraded package(s).' ) - cmd_opts.add_option( + self.cmd_opts.add_option( '--force-reinstall', dest='force_reinstall', action='store_true', help='Reinstall all packages even if they are already ' 'up-to-date.') - cmd_opts.add_option( + self.cmd_opts.add_option( '-I', '--ignore-installed', dest='ignore_installed', action='store_true', - help='Ignore the installed packages (reinstalling instead).') + help='Ignore the installed packages, overwriting them. ' + 'This can break your system if the existing package ' + 'is of a different version or was installed ' + 'with a different package manager!' + ) - cmd_opts.add_option(cmdoptions.ignore_requires_python()) - cmd_opts.add_option(cmdoptions.no_build_isolation()) - cmd_opts.add_option(cmdoptions.use_pep517()) - cmd_opts.add_option(cmdoptions.no_use_pep517()) + self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) + self.cmd_opts.add_option(cmdoptions.no_build_isolation()) + self.cmd_opts.add_option(cmdoptions.use_pep517()) + self.cmd_opts.add_option(cmdoptions.no_use_pep517()) - cmd_opts.add_option(cmdoptions.install_options()) - cmd_opts.add_option(cmdoptions.global_options()) + self.cmd_opts.add_option(cmdoptions.install_options()) + self.cmd_opts.add_option(cmdoptions.global_options()) - cmd_opts.add_option( + self.cmd_opts.add_option( "--compile", action="store_true", dest="compile", @@ -202,21 +190,21 @@ class InstallCommand(RequirementCommand): help="Compile Python source files to bytecode", ) - cmd_opts.add_option( + self.cmd_opts.add_option( "--no-compile", action="store_false", dest="compile", help="Do not compile Python source files to bytecode", ) - cmd_opts.add_option( + self.cmd_opts.add_option( "--no-warn-script-location", action="store_false", dest="warn_script_location", default=True, help="Do not warn when installing scripts outside PATH", ) - cmd_opts.add_option( + self.cmd_opts.add_option( "--no-warn-conflicts", action="store_false", dest="warn_about_conflicts", @@ -224,12 +212,11 @@ class InstallCommand(RequirementCommand): help="Do not warn about broken dependencies", ) - cmd_opts.add_option(cmdoptions.no_binary()) - cmd_opts.add_option(cmdoptions.only_binary()) - cmd_opts.add_option(cmdoptions.prefer_binary()) - cmd_opts.add_option(cmdoptions.no_clean()) - cmd_opts.add_option(cmdoptions.require_hashes()) - cmd_opts.add_option(cmdoptions.progress_bar()) + self.cmd_opts.add_option(cmdoptions.no_binary()) + self.cmd_opts.add_option(cmdoptions.only_binary()) + self.cmd_opts.add_option(cmdoptions.prefer_binary()) + self.cmd_opts.add_option(cmdoptions.require_hashes()) + self.cmd_opts.add_option(cmdoptions.progress_bar()) index_opts = cmdoptions.make_option_group( cmdoptions.index_group, @@ -237,36 +224,34 @@ class InstallCommand(RequirementCommand): ) self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) + self.parser.insert_option_group(0, self.cmd_opts) + @with_cleanup def run(self, options, args): + # type: (Values, List[str]) -> int + if options.use_user_site and options.target_dir is not None: + raise CommandError("Can not combine '--user' and '--target'") + cmdoptions.check_install_build_global(options) upgrade_strategy = "to-satisfy-only" if options.upgrade: upgrade_strategy = options.upgrade_strategy - if options.build_dir: - options.build_dir = os.path.abspath(options.build_dir) - cmdoptions.check_dist_restriction(options, check_target=True) - options.src_dir = os.path.abspath(options.src_dir) install_options = options.install_options or [] - if options.use_user_site: - if options.prefix_path: - raise CommandError( - "Can not combine '--user' and '--prefix' as they imply " - "different installation locations" - ) - if virtualenv_no_global(): - raise InstallationError( - "Can not perform a '--user' install. User site-packages " - "are not visible in this virtualenv." - ) - install_options.append('--user') - install_options.append('--prefix=') - target_temp_dir = TempDirectory(kind="target") + logger.debug("Using %s", get_pip_version()) + options.use_user_site = decide_user_install( + options.use_user_site, + prefix_path=options.prefix_path, + target_dir=options.target_dir, + root_path=options.root_path, + isolated_mode=options.isolated_mode, + ) + + target_temp_dir = None # type: Optional[TempDirectory] + target_temp_dir_path = None # type: Optional[str] if options.target_dir: options.ignore_installed = True options.target_dir = os.path.abspath(options.target_dir) @@ -278,273 +263,457 @@ class InstallCommand(RequirementCommand): ) # Create a target directory for using with the target option - target_temp_dir.create() - install_options.append('--home=' + target_temp_dir.path) + target_temp_dir = TempDirectory(kind="target") + target_temp_dir_path = target_temp_dir.path + self.enter_context(target_temp_dir) global_options = options.global_options or [] - with self._build_session(options) as session: - target_python = make_target_python(options) - finder = self._build_package_finder( - options=options, - session=session, - target_python=target_python, - ignore_requires_python=options.ignore_requires_python, + session = self.get_default_session(options) + + target_python = make_target_python(options) + finder = self._build_package_finder( + options=options, + session=session, + target_python=target_python, + ignore_requires_python=options.ignore_requires_python, + ) + build_delete = (not (options.no_clean or options.build_dir)) + wheel_cache = WheelCache(options.cache_dir, options.format_control) + + req_tracker = self.enter_context(get_requirement_tracker()) + + directory = TempDirectory( + options.build_dir, + delete=build_delete, + kind="install", + globally_managed=True, + ) + + try: + reqs = self.get_requirements(args, options, finder, session) + + reject_location_related_install_options( + reqs, options.install_options ) - build_delete = (not (options.no_clean or options.build_dir)) - wheel_cache = WheelCache(options.cache_dir, options.format_control) - if options.cache_dir and not check_path_owner(options.cache_dir): - logger.warning( - "The directory '%s' or its parent directory is not owned " - "by the current user and caching wheels has been " - "disabled. check the permissions and owner of that " - "directory. If executing pip with sudo, you may want " - "sudo's -H flag.", - options.cache_dir, + preparer = self.make_requirement_preparer( + temp_build_dir=directory, + options=options, + req_tracker=req_tracker, + session=session, + finder=finder, + use_user_site=options.use_user_site, + ) + resolver = self.make_resolver( + preparer=preparer, + finder=finder, + options=options, + wheel_cache=wheel_cache, + use_user_site=options.use_user_site, + ignore_installed=options.ignore_installed, + ignore_requires_python=options.ignore_requires_python, + force_reinstall=options.force_reinstall, + upgrade_strategy=upgrade_strategy, + use_pep517=options.use_pep517, + ) + + self.trace_basic_info(finder) + + requirement_set = resolver.resolve( + reqs, check_supported_wheels=not options.target_dir + ) + + try: + pip_req = requirement_set.get_requirement("pip") + except KeyError: + modifying_pip = False + else: + # If we're not replacing an already installed pip, + # we're not modifying it. + modifying_pip = pip_req.satisfied_by is None + protect_pip_from_modification_on_windows( + modifying_pip=modifying_pip + ) + + check_binary_allowed = get_check_binary_allowed( + finder.format_control + ) + + reqs_to_build = [ + r for r in requirement_set.requirements.values() + if should_build_for_install_command( + r, check_binary_allowed ) - options.cache_dir = None + ] - with RequirementTracker() as req_tracker, TempDirectory( - options.build_dir, delete=build_delete, kind="install" - ) as directory: - requirement_set = RequirementSet( - require_hashes=options.require_hashes, - check_supported_wheels=not options.target_dir, + _, build_failures = build( + reqs_to_build, + wheel_cache=wheel_cache, + build_options=[], + global_options=[], + ) + + # If we're using PEP 517, we cannot do a direct install + # so we fail here. + pep517_build_failure_names = [ + r.name # type: ignore + for r in build_failures if r.use_pep517 + ] # type: List[str] + if pep517_build_failure_names: + raise InstallationError( + "Could not build wheels for {} which use" + " PEP 517 and cannot be installed directly".format( + ", ".join(pep517_build_failure_names) + ) ) + # For now, we just warn about failures building legacy + # requirements, as we'll fall through to a direct + # install for those. + for r in build_failures: + if not r.use_pep517: + r.legacy_install_reason = 8368 + + to_install = resolver.get_installation_order( + requirement_set + ) + + # Check for conflicts in the package set we're installing. + conflicts = None # type: Optional[ConflictDetails] + should_warn_about_conflicts = ( + not options.ignore_dependencies and + options.warn_about_conflicts + ) + if should_warn_about_conflicts: + conflicts = self._determine_conflicts(to_install) + + # Don't warn about script install locations if + # --target has been specified + warn_script_location = options.warn_script_location + if options.target_dir: + warn_script_location = False + + installed = install_given_reqs( + to_install, + install_options, + global_options, + root=options.root_path, + home=target_temp_dir_path, + prefix=options.prefix_path, + warn_script_location=warn_script_location, + use_user_site=options.use_user_site, + pycompile=options.compile, + ) + + lib_locations = get_lib_location_guesses( + user=options.use_user_site, + home=target_temp_dir_path, + root=options.root_path, + prefix=options.prefix_path, + isolated=options.isolated_mode, + ) + working_set = pkg_resources.WorkingSet(lib_locations) + + installed.sort(key=operator.attrgetter('name')) + items = [] + for result in installed: + item = result.name try: - self.populate_requirement_set( - requirement_set, args, options, finder, session, - self.name, wheel_cache - ) - preparer = RequirementPreparer( - build_dir=directory.path, - src_dir=options.src_dir, - download_dir=None, - wheel_download_dir=None, - progress_bar=options.progress_bar, - build_isolation=options.build_isolation, - req_tracker=req_tracker, + installed_version = get_installed_version( + result.name, working_set=working_set ) + if installed_version: + item += '-' + installed_version + except Exception: + pass + items.append(item) - resolver = Resolver( - preparer=preparer, - finder=finder, - session=session, - wheel_cache=wheel_cache, - use_user_site=options.use_user_site, - upgrade_strategy=upgrade_strategy, - force_reinstall=options.force_reinstall, - ignore_dependencies=options.ignore_dependencies, - ignore_requires_python=options.ignore_requires_python, - ignore_installed=options.ignore_installed, - isolated=options.isolated_mode, - use_pep517=options.use_pep517 - ) - resolver.resolve(requirement_set) + if conflicts is not None: + self._warn_about_conflicts( + conflicts, + new_resolver='2020-resolver' in options.features_enabled, + ) - protect_pip_from_modification_on_windows( - modifying_pip=requirement_set.has_requirement("pip") - ) + installed_desc = ' '.join(items) + if installed_desc: + write_output( + 'Successfully installed %s', installed_desc, + ) + except EnvironmentError as error: + show_traceback = (self.verbosity >= 1) - # Consider legacy and PEP517-using requirements separately - legacy_requirements = [] - pep517_requirements = [] - for req in requirement_set.requirements.values(): - if req.use_pep517: - pep517_requirements.append(req) - else: - legacy_requirements.append(req) + message = create_env_error_message( + error, show_traceback, options.use_user_site, + ) + logger.error(message, exc_info=show_traceback) # noqa - wheel_builder = WheelBuilder( - finder, preparer, wheel_cache, - build_options=[], global_options=[], - ) - - build_failures = build_wheels( - builder=wheel_builder, - pep517_requirements=pep517_requirements, - legacy_requirements=legacy_requirements, - session=session, - ) - - # If we're using PEP 517, we cannot do a direct install - # so we fail here. - if build_failures: - raise InstallationError( - "Could not build wheels for {} which use" - " PEP 517 and cannot be installed directly".format( - ", ".join(r.name for r in build_failures))) - - to_install = resolver.get_installation_order( - requirement_set - ) - - # Consistency Checking of the package set we're installing. - should_warn_about_conflicts = ( - not options.ignore_dependencies and - options.warn_about_conflicts - ) - if should_warn_about_conflicts: - self._warn_about_conflicts(to_install) - - # Don't warn about script install locations if - # --target has been specified - warn_script_location = options.warn_script_location - if options.target_dir: - warn_script_location = False - - installed = install_given_reqs( - to_install, - install_options, - global_options, - root=options.root_path, - home=target_temp_dir.path, - prefix=options.prefix_path, - pycompile=options.compile, - warn_script_location=warn_script_location, - use_user_site=options.use_user_site, - ) - - lib_locations = get_lib_location_guesses( - user=options.use_user_site, - home=target_temp_dir.path, - root=options.root_path, - prefix=options.prefix_path, - isolated=options.isolated_mode, - ) - working_set = pkg_resources.WorkingSet(lib_locations) - - reqs = sorted(installed, key=operator.attrgetter('name')) - items = [] - for req in reqs: - item = req.name - try: - installed_version = get_installed_version( - req.name, working_set=working_set - ) - if installed_version: - item += '-' + installed_version - except Exception: - pass - items.append(item) - installed = ' '.join(items) - if installed: - logger.info('Successfully installed %s', installed) - except EnvironmentError as error: - show_traceback = (self.verbosity >= 1) - - message = create_env_error_message( - error, show_traceback, options.use_user_site, - ) - logger.error(message, exc_info=show_traceback) - - return ERROR - except PreviousBuildDirError: - options.no_clean = True - raise - finally: - # Clean up - if not options.no_clean: - requirement_set.cleanup_files() - wheel_cache.cleanup() + return ERROR if options.target_dir: + assert target_temp_dir self._handle_target_dir( options.target_dir, target_temp_dir, options.upgrade ) - return requirement_set + + return SUCCESS def _handle_target_dir(self, target_dir, target_temp_dir, upgrade): + # type: (str, TempDirectory, bool) -> None ensure_dir(target_dir) # Checking both purelib and platlib directories for installed # packages to be moved to target directory lib_dir_list = [] - with target_temp_dir: - # Checking both purelib and platlib directories for installed - # packages to be moved to target directory - scheme = distutils_scheme('', home=target_temp_dir.path) - purelib_dir = scheme['purelib'] - platlib_dir = scheme['platlib'] - data_dir = scheme['data'] + # Checking both purelib and platlib directories for installed + # packages to be moved to target directory + scheme = distutils_scheme('', home=target_temp_dir.path) + purelib_dir = scheme['purelib'] + platlib_dir = scheme['platlib'] + data_dir = scheme['data'] - if os.path.exists(purelib_dir): - lib_dir_list.append(purelib_dir) - if os.path.exists(platlib_dir) and platlib_dir != purelib_dir: - lib_dir_list.append(platlib_dir) - if os.path.exists(data_dir): - lib_dir_list.append(data_dir) + if os.path.exists(purelib_dir): + lib_dir_list.append(purelib_dir) + if os.path.exists(platlib_dir) and platlib_dir != purelib_dir: + lib_dir_list.append(platlib_dir) + if os.path.exists(data_dir): + lib_dir_list.append(data_dir) - for lib_dir in lib_dir_list: - for item in os.listdir(lib_dir): - if lib_dir == data_dir: - ddir = os.path.join(data_dir, item) - if any(s.startswith(ddir) for s in lib_dir_list[:-1]): - continue - target_item_dir = os.path.join(target_dir, item) - if os.path.exists(target_item_dir): - if not upgrade: - logger.warning( - 'Target directory %s already exists. Specify ' - '--upgrade to force replacement.', - target_item_dir - ) - continue - if os.path.islink(target_item_dir): - logger.warning( - 'Target directory %s already exists and is ' - 'a link. Pip will not automatically replace ' - 'links, please remove if replacement is ' - 'desired.', - target_item_dir - ) - continue - if os.path.isdir(target_item_dir): - shutil.rmtree(target_item_dir) - else: - os.remove(target_item_dir) + for lib_dir in lib_dir_list: + for item in os.listdir(lib_dir): + if lib_dir == data_dir: + ddir = os.path.join(data_dir, item) + if any(s.startswith(ddir) for s in lib_dir_list[:-1]): + continue + target_item_dir = os.path.join(target_dir, item) + if os.path.exists(target_item_dir): + if not upgrade: + logger.warning( + 'Target directory %s already exists. Specify ' + '--upgrade to force replacement.', + target_item_dir + ) + continue + if os.path.islink(target_item_dir): + logger.warning( + 'Target directory %s already exists and is ' + 'a link. pip will not automatically replace ' + 'links, please remove if replacement is ' + 'desired.', + target_item_dir + ) + continue + if os.path.isdir(target_item_dir): + shutil.rmtree(target_item_dir) + else: + os.remove(target_item_dir) - shutil.move( - os.path.join(lib_dir, item), - target_item_dir - ) + shutil.move( + os.path.join(lib_dir, item), + target_item_dir + ) - def _warn_about_conflicts(self, to_install): + def _determine_conflicts(self, to_install): + # type: (List[InstallRequirement]) -> Optional[ConflictDetails] try: - package_set, _dep_info = check_install_conflicts(to_install) + return check_install_conflicts(to_install) except Exception: - logger.error("Error checking for conflicts.", exc_info=True) - return - missing, conflicting = _dep_info + logger.exception( + "Error while checking for conflicts. Please file an issue on " + "pip's issue tracker: https://github.com/pypa/pip/issues/new" + ) + return None - # NOTE: There is some duplication here from pip check + def _warn_about_conflicts(self, conflict_details, new_resolver): + # type: (ConflictDetails, bool) -> None + package_set, (missing, conflicting) = conflict_details + if not missing and not conflicting: + return + + parts = [] # type: List[str] + if not new_resolver: + parts.append( + "After October 2020 you may experience errors when installing " + "or updating packages. This is because pip will change the " + "way that it resolves dependency conflicts.\n" + ) + parts.append( + "We recommend you use --use-feature=2020-resolver to test " + "your packages with the new resolver before it becomes the " + "default.\n" + ) + elif not today_is_later_than(year=2020, month=7, day=31): + # NOTE: trailing newlines here are intentional + parts.append( + "Pip will install or upgrade your package(s) and its " + "dependencies without taking into account other packages you " + "already have installed. This may cause an uncaught " + "dependency conflict.\n" + ) + form_link = "https://forms.gle/cWKMoDs8sUVE29hz9" + parts.append( + "If you would like pip to take your other packages into " + "account, please tell us here: {}\n".format(form_link) + ) + + # NOTE: There is some duplication here, with commands/check.py for project_name in missing: version = package_set[project_name][0] for dependency in missing[project_name]: - logger.critical( - "%s %s requires %s, which is not installed.", - project_name, version, dependency[1], + message = ( + "{name} {version} requires {requirement}, " + "which is not installed." + ).format( + name=project_name, + version=version, + requirement=dependency[1], ) + parts.append(message) for project_name in conflicting: version = package_set[project_name][0] for dep_name, dep_version, req in conflicting[project_name]: - logger.critical( - "%s %s has requirement %s, but you'll have %s %s which is " - "incompatible.", - project_name, version, req, dep_name, dep_version, + message = ( + "{name} {version} requires {requirement}, but you'll have " + "{dep_name} {dep_version} which is incompatible." + ).format( + name=project_name, + version=version, + requirement=req, + dep_name=dep_name, + dep_version=dep_version, ) + parts.append(message) + + logger.critical("\n".join(parts)) -def get_lib_location_guesses(*args, **kwargs): - scheme = distutils_scheme('', *args, **kwargs) +def get_lib_location_guesses( + user=False, # type: bool + home=None, # type: Optional[str] + root=None, # type: Optional[str] + isolated=False, # type: bool + prefix=None # type: Optional[str] +): + # type:(...) -> List[str] + scheme = distutils_scheme('', user=user, home=home, root=root, + isolated=isolated, prefix=prefix) return [scheme['purelib'], scheme['platlib']] +def site_packages_writable(root, isolated): + # type: (Optional[str], bool) -> bool + return all( + test_writable_dir(d) for d in set( + get_lib_location_guesses(root=root, isolated=isolated)) + ) + + +def decide_user_install( + use_user_site, # type: Optional[bool] + prefix_path=None, # type: Optional[str] + target_dir=None, # type: Optional[str] + root_path=None, # type: Optional[str] + isolated_mode=False, # type: bool +): + # type: (...) -> bool + """Determine whether to do a user install based on the input options. + + If use_user_site is False, no additional checks are done. + If use_user_site is True, it is checked for compatibility with other + options. + If use_user_site is None, the default behaviour depends on the environment, + which is provided by the other arguments. + """ + # In some cases (config from tox), use_user_site can be set to an integer + # rather than a bool, which 'use_user_site is False' wouldn't catch. + if (use_user_site is not None) and (not use_user_site): + logger.debug("Non-user install by explicit request") + return False + + if use_user_site: + if prefix_path: + raise CommandError( + "Can not combine '--user' and '--prefix' as they imply " + "different installation locations" + ) + if virtualenv_no_global(): + raise InstallationError( + "Can not perform a '--user' install. User site-packages " + "are not visible in this virtualenv." + ) + logger.debug("User install by explicit request") + return True + + # If we are here, user installs have not been explicitly requested/avoided + assert use_user_site is None + + # user install incompatible with --prefix/--target + if prefix_path or target_dir: + logger.debug("Non-user install due to --prefix or --target option") + return False + + # If user installs are not enabled, choose a non-user install + if not site.ENABLE_USER_SITE: + logger.debug("Non-user install because user site-packages disabled") + return False + + # If we have permission for a non-user install, do that, + # otherwise do a user install. + if site_packages_writable(root=root_path, isolated=isolated_mode): + logger.debug("Non-user install because site-packages writeable") + return False + + logger.info("Defaulting to user installation because normal site-packages " + "is not writeable") + return True + + +def reject_location_related_install_options(requirements, options): + # type: (List[InstallRequirement], Optional[List[str]]) -> None + """If any location-changing --install-option arguments were passed for + requirements or on the command-line, then show a deprecation warning. + """ + def format_options(option_names): + # type: (Iterable[str]) -> List[str] + return ["--{}".format(name.replace("_", "-")) for name in option_names] + + offenders = [] + + for requirement in requirements: + install_options = requirement.install_options + location_options = parse_distutils_args(install_options) + if location_options: + offenders.append( + "{!r} from {}".format( + format_options(location_options.keys()), requirement + ) + ) + + if options: + location_options = parse_distutils_args(options) + if location_options: + offenders.append( + "{!r} from command line".format( + format_options(location_options.keys()) + ) + ) + + if not offenders: + return + + raise CommandError( + "Location-changing options found in --install-option: {}." + " This is unsupported, use pip-level options like --user," + " --prefix, --root, and --target instead.".format( + "; ".join(offenders) + ) + ) + + def create_env_error_message(error, show_traceback, using_user_site): + # type: (EnvironmentError, bool, bool) -> str """Format an error message for an EnvironmentError It may occur anytime during the execution of the install command. diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/list.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/list.py index cf71b13..20e9bff 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/list.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/list.py @@ -4,54 +4,63 @@ import json import logging from pip._vendor import six -from pip._vendor.six.moves import zip_longest from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import Command -from pip._internal.cli.cmdoptions import make_search_scope +from pip._internal.cli.req_command import IndexGroupCommand +from pip._internal.cli.status_codes import SUCCESS from pip._internal.exceptions import CommandError -from pip._internal.index import PackageFinder +from pip._internal.index.collector import LinkCollector +from pip._internal.index.package_finder import PackageFinder from pip._internal.models.selection_prefs import SelectionPreferences from pip._internal.utils.misc import ( - dist_is_editable, get_installed_distributions, + dist_is_editable, + get_installed_distributions, + tabulate, + write_output, ) from pip._internal.utils.packaging import get_installer +from pip._internal.utils.parallel import map_multithread +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List, Set, Tuple, Iterator + + from pip._internal.network.session import PipSession + from pip._vendor.pkg_resources import Distribution logger = logging.getLogger(__name__) -class ListCommand(Command): +class ListCommand(IndexGroupCommand): """ List installed packages, including editables. Packages are listed in a case-insensitive sorted order. """ - name = 'list' + + ignore_require_venv = True usage = """ %prog [options]""" - summary = 'List installed packages.' - def __init__(self, *args, **kw): - super(ListCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option( + def add_options(self): + # type: () -> None + self.cmd_opts.add_option( '-o', '--outdated', action='store_true', default=False, help='List outdated packages') - cmd_opts.add_option( + self.cmd_opts.add_option( '-u', '--uptodate', action='store_true', default=False, help='List uptodate packages') - cmd_opts.add_option( + self.cmd_opts.add_option( '-e', '--editable', action='store_true', default=False, help='List editable projects.') - cmd_opts.add_option( + self.cmd_opts.add_option( '-l', '--local', action='store_true', default=False, @@ -64,8 +73,8 @@ class ListCommand(Command): action='store_true', default=False, help='Only output packages installed in user-site.') - cmd_opts.add_option(cmdoptions.list_path()) - cmd_opts.add_option( + self.cmd_opts.add_option(cmdoptions.list_path()) + self.cmd_opts.add_option( '--pre', action='store_true', default=False, @@ -73,7 +82,7 @@ class ListCommand(Command): "pip only finds stable versions."), ) - cmd_opts.add_option( + self.cmd_opts.add_option( '--format', action='store', dest='list_format', @@ -83,7 +92,7 @@ class ListCommand(Command): "or json", ) - cmd_opts.add_option( + self.cmd_opts.add_option( '--not-required', action='store_true', dest='not_required', @@ -91,13 +100,13 @@ class ListCommand(Command): "installed packages.", ) - cmd_opts.add_option( + self.cmd_opts.add_option( '--exclude-editable', action='store_false', dest='include_editable', help='Exclude editable package from output.', ) - cmd_opts.add_option( + self.cmd_opts.add_option( '--include-editable', action='store_true', dest='include_editable', @@ -109,13 +118,14 @@ class ListCommand(Command): ) self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) + self.parser.insert_option_group(0, self.cmd_opts) def _build_package_finder(self, options, session): + # type: (Values, PipSession) -> PackageFinder """ Create a package finder appropriate to this list command. """ - search_scope = make_search_scope(options) + link_collector = LinkCollector.create(session, options=options) # Pass allow_yanked=False to ignore yanked versions. selection_prefs = SelectionPreferences( @@ -124,13 +134,12 @@ class ListCommand(Command): ) return PackageFinder.create( - search_scope=search_scope, + link_collector=link_collector, selection_prefs=selection_prefs, - trusted_hosts=options.trusted_hosts, - session=session, ) def run(self, options, args): + # type: (Values, List[str]) -> int if options.outdated and options.uptodate: raise CommandError( "Options --outdated and --uptodate cannot be combined.") @@ -158,30 +167,40 @@ class ListCommand(Command): packages = self.get_uptodate(packages, options) self.output_package_listing(packages, options) + return SUCCESS def get_outdated(self, packages, options): + # type: (List[Distribution], Values) -> List[Distribution] return [ dist for dist in self.iter_packages_latest_infos(packages, options) if dist.latest_version > dist.parsed_version ] def get_uptodate(self, packages, options): + # type: (List[Distribution], Values) -> List[Distribution] return [ dist for dist in self.iter_packages_latest_infos(packages, options) if dist.latest_version == dist.parsed_version ] def get_not_required(self, packages, options): - dep_keys = set() + # type: (List[Distribution], Values) -> List[Distribution] + dep_keys = set() # type: Set[Distribution] for dist in packages: dep_keys.update(requirement.key for requirement in dist.requires()) - return {pkg for pkg in packages if pkg.key not in dep_keys} + + # Create a set to remove duplicate packages, and cast it to a list + # to keep the return type consistent with get_outdated and + # get_uptodate + return list({pkg for pkg in packages if pkg.key not in dep_keys}) def iter_packages_latest_infos(self, packages, options): + # type: (List[Distribution], Values) -> Iterator[Distribution] with self._build_session(options) as session: finder = self._build_package_finder(options, session) - for dist in packages: + def latest_info(dist): + # type: (Distribution) -> Distribution typ = 'unknown' all_candidates = finder.find_all_candidates(dist.key) if not options.pre: @@ -192,9 +211,9 @@ class ListCommand(Command): evaluator = finder.make_candidate_evaluator( project_name=dist.project_name, ) - best_candidate = evaluator.get_best_candidate(all_candidates) + best_candidate = evaluator.sort_best_candidate(all_candidates) if best_candidate is None: - continue + return None remote_version = best_candidate.version if best_candidate.link.is_wheel: @@ -204,9 +223,14 @@ class ListCommand(Command): # This is dirty but makes the rest of the code much cleaner dist.latest_version = remote_version dist.latest_filetype = typ - yield dist + return dist + + for dist in map_multithread(latest_info, packages): + if dist is not None: + yield dist def output_package_listing(self, packages, options): + # type: (List[Distribution], Values) -> None packages = sorted( packages, key=lambda dist: dist.project_name.lower(), @@ -217,14 +241,15 @@ class ListCommand(Command): elif options.list_format == 'freeze': for dist in packages: if options.verbose >= 1: - logger.info("%s==%s (%s)", dist.project_name, - dist.version, dist.location) + write_output("%s==%s (%s)", dist.project_name, + dist.version, dist.location) else: - logger.info("%s==%s", dist.project_name, dist.version) + write_output("%s==%s", dist.project_name, dist.version) elif options.list_format == 'json': - logger.info(format_for_json(packages, options)) + write_output(format_for_json(packages, options)) def output_package_listing_columns(self, data, header): + # type: (List[List[str]], List[str]) -> None # insert the header first: we need to know the size of column names if len(data) > 0: data.insert(0, header) @@ -236,28 +261,11 @@ class ListCommand(Command): pkg_strings.insert(1, " ".join(map(lambda x: '-' * x, sizes))) for val in pkg_strings: - logger.info(val) - - -def tabulate(vals): - # From pfmoore on GitHub: - # https://github.com/pypa/pip/issues/3651#issuecomment-216932564 - assert len(vals) > 0 - - sizes = [0] * max(len(x) for x in vals) - for row in vals: - sizes = [max(s, len(str(c))) for s, c in zip_longest(sizes, row)] - - result = [] - for row in vals: - display = " ".join([str(c).ljust(s) if c is not None else '' - for s, c in zip_longest(sizes, row)]) - result.append(display) - - return result, sizes + write_output(val) def format_for_columns(pkgs, options): + # type: (List[Distribution], Values) -> Tuple[List[List[str]], List[str]] """ Convert the package data into something usable by output_package_listing_columns. @@ -295,6 +303,7 @@ def format_for_columns(pkgs, options): def format_for_json(packages, options): + # type: (List[Distribution], Values) -> str data = [] for dist in packages: info = { diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/search.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/search.py index 5802711..ff09472 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/search.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/search.py @@ -12,26 +12,37 @@ from pip._vendor.packaging.version import parse as parse_version from pip._vendor.six.moves import xmlrpc_client # type: ignore from pip._internal.cli.base_command import Command +from pip._internal.cli.req_command import SessionCommandMixin from pip._internal.cli.status_codes import NO_MATCHES_FOUND, SUCCESS -from pip._internal.download import PipXmlrpcTransport from pip._internal.exceptions import CommandError from pip._internal.models.index import PyPI +from pip._internal.network.xmlrpc import PipXmlrpcTransport from pip._internal.utils.compat import get_terminal_size from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import get_distribution, write_output +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List, Dict, Optional + from typing_extensions import TypedDict + TransformedHit = TypedDict( + 'TransformedHit', + {'name': str, 'summary': str, 'versions': List[str]}, + ) logger = logging.getLogger(__name__) -class SearchCommand(Command): +class SearchCommand(Command, SessionCommandMixin): """Search for PyPI packages whose name or summary contains <query>.""" - name = 'search' + usage = """ %prog [options] <query>""" - summary = 'Search PyPI for packages.' ignore_require_venv = True - def __init__(self, *args, **kw): - super(SearchCommand, self).__init__(*args, **kw) + def add_options(self): + # type: () -> None self.cmd_opts.add_option( '-i', '--index', dest='index', @@ -42,6 +53,7 @@ class SearchCommand(Command): self.parser.insert_option_group(0, self.cmd_opts) def run(self, options, args): + # type: (Values, List[str]) -> int if not args: raise CommandError('Missing required argument (search query).') query = args @@ -58,21 +70,25 @@ class SearchCommand(Command): return NO_MATCHES_FOUND def search(self, query, options): + # type: (List[str], Values) -> List[Dict[str, str]] index_url = options.index - with self._build_session(options) as session: - transport = PipXmlrpcTransport(index_url, session) - pypi = xmlrpc_client.ServerProxy(index_url, transport) - hits = pypi.search({'name': query, 'summary': query}, 'or') - return hits + + session = self.get_default_session(options) + + transport = PipXmlrpcTransport(index_url, session) + pypi = xmlrpc_client.ServerProxy(index_url, transport) + hits = pypi.search({'name': query, 'summary': query}, 'or') + return hits def transform_hits(hits): + # type: (List[Dict[str, str]]) -> List[TransformedHit] """ The list from pypi is really a list of versions. We want a list of packages with the list of versions stored inline. This converts the list from pypi into one we can use. """ - packages = OrderedDict() + packages = OrderedDict() # type: OrderedDict[str, TransformedHit] for hit in hits: name = hit['name'] summary = hit['summary'] @@ -95,6 +111,7 @@ def transform_hits(hits): def print_results(hits, name_column_width=None, terminal_width=None): + # type: (List[TransformedHit], Optional[int], Optional[int]) -> None if not hits: return if name_column_width is None: @@ -112,28 +129,32 @@ def print_results(hits, name_column_width=None, terminal_width=None): target_width = terminal_width - name_column_width - 5 if target_width > 10: # wrap and indent summary to fit terminal - summary = textwrap.wrap(summary, target_width) - summary = ('\n' + ' ' * (name_column_width + 3)).join(summary) + summary_lines = textwrap.wrap(summary, target_width) + summary = ('\n' + ' ' * (name_column_width + 3)).join( + summary_lines) - line = '%-*s - %s' % (name_column_width, - '%s (%s)' % (name, latest), summary) + line = '{name_latest:{name_column_width}} - {summary}'.format( + name_latest='{name} ({latest})'.format(**locals()), + **locals()) try: - logger.info(line) + write_output(line) if name in installed_packages: - dist = pkg_resources.get_distribution(name) + dist = get_distribution(name) + assert dist is not None with indent_log(): if dist.version == latest: - logger.info('INSTALLED: %s (latest)', dist.version) + write_output('INSTALLED: %s (latest)', dist.version) else: - logger.info('INSTALLED: %s', dist.version) + write_output('INSTALLED: %s', dist.version) if parse_version(latest).pre: - logger.info('LATEST: %s (pre-release; install' - ' with "pip install --pre")', latest) + write_output('LATEST: %s (pre-release; install' + ' with "pip install --pre")', latest) else: - logger.info('LATEST: %s', latest) + write_output('LATEST: %s', latest) except UnicodeEncodeError: pass def highest_version(versions): + # type: (List[str]) -> str return max(versions, key=parse_version) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/show.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/show.py index a18a902..3892c59 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/show.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/show.py @@ -9,6 +9,12 @@ from pip._vendor.packaging.utils import canonicalize_name from pip._internal.cli.base_command import Command from pip._internal.cli.status_codes import ERROR, SUCCESS +from pip._internal.utils.misc import write_output +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List, Dict, Iterator logger = logging.getLogger(__name__) @@ -19,14 +25,13 @@ class ShowCommand(Command): The output is in RFC-compliant mail header format. """ - name = 'show' + usage = """ %prog [options] <package> ...""" - summary = 'Show information about installed packages.' ignore_require_venv = True - def __init__(self, *args, **kw): - super(ShowCommand, self).__init__(*args, **kw) + def add_options(self): + # type: () -> None self.cmd_opts.add_option( '-f', '--files', dest='files', @@ -37,6 +42,7 @@ class ShowCommand(Command): self.parser.insert_option_group(0, self.cmd_opts) def run(self, options, args): + # type: (Values, List[str]) -> int if not args: logger.warning('ERROR: Please provide a package name or names.') return ERROR @@ -50,6 +56,7 @@ class ShowCommand(Command): def search_packages_info(query): + # type: (List[str]) -> Iterator[Dict[str, str]] """ Gather details from installed distributions. Print distribution name, version, location, and installed files. Installed files requires a @@ -61,6 +68,21 @@ def search_packages_info(query): installed[canonicalize_name(p.project_name)] = p query_names = [canonicalize_name(name) for name in query] + missing = sorted( + [name for name, pkg in zip(query, query_names) if pkg not in installed] + ) + if missing: + logger.warning('Package(s) not found: %s', ', '.join(missing)) + + def get_requiring_packages(package_name): + # type: (str) -> List[str] + canonical_name = canonicalize_name(package_name) + return [ + pkg.project_name for pkg in pkg_resources.working_set + if canonical_name in + [canonicalize_name(required.name) for required in + pkg.requires()] + ] for dist in [installed[pkg] for pkg in query_names if pkg in installed]: package = { @@ -68,14 +90,15 @@ def search_packages_info(query): 'version': dist.version, 'location': dist.location, 'requires': [dep.project_name for dep in dist.requires()], + 'required_by': get_requiring_packages(dist.project_name) } file_list = None - metadata = None + metadata = '' if isinstance(dist, pkg_resources.DistInfoDistribution): # RECORDs should be part of .dist-info metadatas if dist.has_metadata('RECORD'): lines = dist.get_metadata_lines('RECORD') - paths = [l.split(',')[0] for l in lines] + paths = [line.split(',')[0] for line in lines] paths = [os.path.join(dist.location, p) for p in paths] file_list = [os.path.relpath(p, dist.location) for p in paths] @@ -123,46 +146,41 @@ def search_packages_info(query): def print_results(distributions, list_files=False, verbose=False): + # type: (Iterator[Dict[str, str]], bool, bool) -> bool """ - Print the informations from installed distributions found. + Print the information from installed distributions found. """ results_printed = False for i, dist in enumerate(distributions): results_printed = True if i > 0: - logger.info("---") + write_output("---") - name = dist.get('name', '') - required_by = [ - pkg.project_name for pkg in pkg_resources.working_set - if name in [required.name for required in pkg.requires()] - ] - - logger.info("Name: %s", name) - logger.info("Version: %s", dist.get('version', '')) - logger.info("Summary: %s", dist.get('summary', '')) - logger.info("Home-page: %s", dist.get('home-page', '')) - logger.info("Author: %s", dist.get('author', '')) - logger.info("Author-email: %s", dist.get('author-email', '')) - logger.info("License: %s", dist.get('license', '')) - logger.info("Location: %s", dist.get('location', '')) - logger.info("Requires: %s", ', '.join(dist.get('requires', []))) - logger.info("Required-by: %s", ', '.join(required_by)) + write_output("Name: %s", dist.get('name', '')) + write_output("Version: %s", dist.get('version', '')) + write_output("Summary: %s", dist.get('summary', '')) + write_output("Home-page: %s", dist.get('home-page', '')) + write_output("Author: %s", dist.get('author', '')) + write_output("Author-email: %s", dist.get('author-email', '')) + write_output("License: %s", dist.get('license', '')) + write_output("Location: %s", dist.get('location', '')) + write_output("Requires: %s", ', '.join(dist.get('requires', []))) + write_output("Required-by: %s", ', '.join(dist.get('required_by', []))) if verbose: - logger.info("Metadata-Version: %s", - dist.get('metadata-version', '')) - logger.info("Installer: %s", dist.get('installer', '')) - logger.info("Classifiers:") + write_output("Metadata-Version: %s", + dist.get('metadata-version', '')) + write_output("Installer: %s", dist.get('installer', '')) + write_output("Classifiers:") for classifier in dist.get('classifiers', []): - logger.info(" %s", classifier) - logger.info("Entry-points:") + write_output(" %s", classifier) + write_output("Entry-points:") for entry in dist.get('entry_points', []): - logger.info(" %s", entry.strip()) + write_output(" %s", entry.strip()) if list_files: - logger.info("Files:") + write_output("Files:") for line in dist.get('files', []): - logger.info(" %s", line.strip()) + write_output(" %s", line.strip()) if "files" not in dist: - logger.info("Cannot locate installed-files.txt") + write_output("Cannot locate installed-files.txt") return results_printed diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/uninstall.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/uninstall.py index 0cd6f54..3371fe4 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/uninstall.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/uninstall.py @@ -3,13 +3,23 @@ from __future__ import absolute_import from pip._vendor.packaging.utils import canonicalize_name from pip._internal.cli.base_command import Command +from pip._internal.cli.req_command import SessionCommandMixin +from pip._internal.cli.status_codes import SUCCESS from pip._internal.exceptions import InstallationError from pip._internal.req import parse_requirements -from pip._internal.req.constructors import install_req_from_line +from pip._internal.req.constructors import ( + install_req_from_line, + install_req_from_parsed_requirement, +) from pip._internal.utils.misc import protect_pip_from_modification_on_windows +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List -class UninstallCommand(Command): +class UninstallCommand(Command, SessionCommandMixin): """ Uninstall packages. @@ -19,14 +29,13 @@ class UninstallCommand(Command): leave behind no metadata to determine what files were installed. - Script wrappers installed by ``python setup.py develop``. """ - name = 'uninstall' + usage = """ %prog [options] <package> ... %prog [options] -r <requirements file> ...""" - summary = 'Uninstall packages.' - def __init__(self, *args, **kw): - super(UninstallCommand, self).__init__(*args, **kw) + def add_options(self): + # type: () -> None self.cmd_opts.add_option( '-r', '--requirement', dest='requirements', @@ -45,34 +54,42 @@ class UninstallCommand(Command): self.parser.insert_option_group(0, self.cmd_opts) def run(self, options, args): - with self._build_session(options) as session: - reqs_to_uninstall = {} - for name in args: - req = install_req_from_line( - name, isolated=options.isolated_mode, + # type: (Values, List[str]) -> int + session = self.get_default_session(options) + + reqs_to_uninstall = {} + for name in args: + req = install_req_from_line( + name, isolated=options.isolated_mode, + ) + if req.name: + reqs_to_uninstall[canonicalize_name(req.name)] = req + for filename in options.requirements: + for parsed_req in parse_requirements( + filename, + options=options, + session=session): + req = install_req_from_parsed_requirement( + parsed_req, + isolated=options.isolated_mode ) if req.name: reqs_to_uninstall[canonicalize_name(req.name)] = req - for filename in options.requirements: - for req in parse_requirements( - filename, - options=options, - session=session): - if req.name: - reqs_to_uninstall[canonicalize_name(req.name)] = req - if not reqs_to_uninstall: - raise InstallationError( - 'You must give at least one requirement to %(name)s (see ' - '"pip help %(name)s")' % dict(name=self.name) - ) - - protect_pip_from_modification_on_windows( - modifying_pip="pip" in reqs_to_uninstall + if not reqs_to_uninstall: + raise InstallationError( + 'You must give at least one requirement to {self.name} (see ' + '"pip help {self.name}")'.format(**locals()) ) - for req in reqs_to_uninstall.values(): - uninstall_pathset = req.uninstall( - auto_confirm=options.yes, verbose=self.verbosity > 0, - ) - if uninstall_pathset: - uninstall_pathset.commit() + protect_pip_from_modification_on_windows( + modifying_pip="pip" in reqs_to_uninstall + ) + + for req in reqs_to_uninstall.values(): + uninstall_pathset = req.uninstall( + auto_confirm=options.yes, verbose=self.verbosity > 0, + ) + if uninstall_pathset: + uninstall_pathset.commit() + + return SUCCESS diff --git a/venv/lib/python3.8/site-packages/pip/_internal/commands/wheel.py b/venv/lib/python3.8/site-packages/pip/_internal/commands/wheel.py index 97f3b14..0f71856 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/commands/wheel.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/commands/wheel.py @@ -1,19 +1,26 @@ # -*- coding: utf-8 -*- + from __future__ import absolute_import import logging import os +import shutil from pip._internal.cache import WheelCache from pip._internal.cli import cmdoptions -from pip._internal.cli.base_command import RequirementCommand -from pip._internal.exceptions import CommandError, PreviousBuildDirError -from pip._internal.legacy_resolve import Resolver -from pip._internal.operations.prepare import RequirementPreparer -from pip._internal.req import RequirementSet -from pip._internal.req.req_tracker import RequirementTracker +from pip._internal.cli.req_command import RequirementCommand, with_cleanup +from pip._internal.cli.status_codes import SUCCESS +from pip._internal.exceptions import CommandError +from pip._internal.req.req_tracker import get_requirement_tracker +from pip._internal.utils.misc import ensure_dir, normalize_path from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.wheel import WheelBuilder +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.wheel_builder import build, should_build_for_wheel_command + +if MYPY_CHECK_RUNNING: + from optparse import Values + from typing import List + logger = logging.getLogger(__name__) @@ -33,7 +40,6 @@ class WheelCommand(RequirementCommand): """ - name = 'wheel' usage = """ %prog [options] <requirement specifier> ... %prog [options] -r <requirements file> ... @@ -41,14 +47,10 @@ class WheelCommand(RequirementCommand): %prog [options] [-e] <local project path> ... %prog [options] <archive url/path> ...""" - summary = 'Build wheels from your requirements.' + def add_options(self): + # type: () -> None - def __init__(self, *args, **kw): - super(WheelCommand, self).__init__(*args, **kw) - - cmd_opts = self.cmd_opts - - cmd_opts.add_option( + self.cmd_opts.add_option( '-w', '--wheel-dir', dest='wheel_dir', metavar='dir', @@ -56,29 +58,29 @@ class WheelCommand(RequirementCommand): help=("Build wheels into <dir>, where the default is the " "current working directory."), ) - cmd_opts.add_option(cmdoptions.no_binary()) - cmd_opts.add_option(cmdoptions.only_binary()) - cmd_opts.add_option(cmdoptions.prefer_binary()) - cmd_opts.add_option( + self.cmd_opts.add_option(cmdoptions.no_binary()) + self.cmd_opts.add_option(cmdoptions.only_binary()) + self.cmd_opts.add_option(cmdoptions.prefer_binary()) + self.cmd_opts.add_option( '--build-option', dest='build_options', metavar='options', action='append', help="Extra arguments to be supplied to 'setup.py bdist_wheel'.", ) - cmd_opts.add_option(cmdoptions.no_build_isolation()) - cmd_opts.add_option(cmdoptions.use_pep517()) - cmd_opts.add_option(cmdoptions.no_use_pep517()) - cmd_opts.add_option(cmdoptions.constraints()) - cmd_opts.add_option(cmdoptions.editable()) - cmd_opts.add_option(cmdoptions.requirements()) - cmd_opts.add_option(cmdoptions.src()) - cmd_opts.add_option(cmdoptions.ignore_requires_python()) - cmd_opts.add_option(cmdoptions.no_deps()) - cmd_opts.add_option(cmdoptions.build_dir()) - cmd_opts.add_option(cmdoptions.progress_bar()) + self.cmd_opts.add_option(cmdoptions.no_build_isolation()) + self.cmd_opts.add_option(cmdoptions.use_pep517()) + self.cmd_opts.add_option(cmdoptions.no_use_pep517()) + self.cmd_opts.add_option(cmdoptions.constraints()) + self.cmd_opts.add_option(cmdoptions.editable()) + self.cmd_opts.add_option(cmdoptions.requirements()) + self.cmd_opts.add_option(cmdoptions.src()) + self.cmd_opts.add_option(cmdoptions.ignore_requires_python()) + self.cmd_opts.add_option(cmdoptions.no_deps()) + self.cmd_opts.add_option(cmdoptions.build_dir()) + self.cmd_opts.add_option(cmdoptions.progress_bar()) - cmd_opts.add_option( + self.cmd_opts.add_option( '--global-option', dest='global_options', action='append', @@ -86,7 +88,7 @@ class WheelCommand(RequirementCommand): help="Extra global options to be supplied to the setup.py " "call before the 'bdist_wheel' command.") - cmd_opts.add_option( + self.cmd_opts.add_option( '--pre', action='store_true', default=False, @@ -94,8 +96,7 @@ class WheelCommand(RequirementCommand): "pip only finds stable versions."), ) - cmd_opts.add_option(cmdoptions.no_clean()) - cmd_opts.add_option(cmdoptions.require_hashes()) + self.cmd_opts.add_option(cmdoptions.require_hashes()) index_opts = cmdoptions.make_option_group( cmdoptions.index_group, @@ -103,79 +104,85 @@ class WheelCommand(RequirementCommand): ) self.parser.insert_option_group(0, index_opts) - self.parser.insert_option_group(0, cmd_opts) + self.parser.insert_option_group(0, self.cmd_opts) + @with_cleanup def run(self, options, args): + # type: (Values, List[str]) -> int cmdoptions.check_install_build_global(options) - if options.build_dir: - options.build_dir = os.path.abspath(options.build_dir) + session = self.get_default_session(options) - options.src_dir = os.path.abspath(options.src_dir) + finder = self._build_package_finder(options, session) + build_delete = (not (options.no_clean or options.build_dir)) + wheel_cache = WheelCache(options.cache_dir, options.format_control) - with self._build_session(options) as session: - finder = self._build_package_finder(options, session) - build_delete = (not (options.no_clean or options.build_dir)) - wheel_cache = WheelCache(options.cache_dir, options.format_control) + options.wheel_dir = normalize_path(options.wheel_dir) + ensure_dir(options.wheel_dir) - with RequirementTracker() as req_tracker, TempDirectory( - options.build_dir, delete=build_delete, kind="wheel" - ) as directory: + req_tracker = self.enter_context(get_requirement_tracker()) - requirement_set = RequirementSet( - require_hashes=options.require_hashes, + directory = TempDirectory( + options.build_dir, + delete=build_delete, + kind="wheel", + globally_managed=True, + ) + + reqs = self.get_requirements(args, options, finder, session) + + preparer = self.make_requirement_preparer( + temp_build_dir=directory, + options=options, + req_tracker=req_tracker, + session=session, + finder=finder, + wheel_download_dir=options.wheel_dir, + use_user_site=False, + ) + + resolver = self.make_resolver( + preparer=preparer, + finder=finder, + options=options, + wheel_cache=wheel_cache, + ignore_requires_python=options.ignore_requires_python, + use_pep517=options.use_pep517, + ) + + self.trace_basic_info(finder) + + requirement_set = resolver.resolve( + reqs, check_supported_wheels=True + ) + + reqs_to_build = [ + r for r in requirement_set.requirements.values() + if should_build_for_wheel_command(r) + ] + + # build wheels + build_successes, build_failures = build( + reqs_to_build, + wheel_cache=wheel_cache, + build_options=options.build_options or [], + global_options=options.global_options or [], + ) + for req in build_successes: + assert req.link and req.link.is_wheel + assert req.local_file_path + # copy from cache to target directory + try: + shutil.copy(req.local_file_path, options.wheel_dir) + except OSError as e: + logger.warning( + "Building wheel for %s failed: %s", + req.name, e, ) + build_failures.append(req) + if len(build_failures) != 0: + raise CommandError( + "Failed to build one or more wheels" + ) - try: - self.populate_requirement_set( - requirement_set, args, options, finder, session, - self.name, wheel_cache - ) - - preparer = RequirementPreparer( - build_dir=directory.path, - src_dir=options.src_dir, - download_dir=None, - wheel_download_dir=options.wheel_dir, - progress_bar=options.progress_bar, - build_isolation=options.build_isolation, - req_tracker=req_tracker, - ) - - resolver = Resolver( - preparer=preparer, - finder=finder, - session=session, - wheel_cache=wheel_cache, - use_user_site=False, - upgrade_strategy="to-satisfy-only", - force_reinstall=False, - ignore_dependencies=options.ignore_dependencies, - ignore_requires_python=options.ignore_requires_python, - ignore_installed=True, - isolated=options.isolated_mode, - use_pep517=options.use_pep517 - ) - resolver.resolve(requirement_set) - - # build wheels - wb = WheelBuilder( - finder, preparer, wheel_cache, - build_options=options.build_options or [], - global_options=options.global_options or [], - no_clean=options.no_clean, - ) - build_failures = wb.build( - requirement_set.requirements.values(), session=session, - ) - if len(build_failures) != 0: - raise CommandError( - "Failed to build one or more wheels" - ) - except PreviousBuildDirError: - options.no_clean = True - raise - finally: - if not options.no_clean: - requirement_set.cleanup_files() - wheel_cache.cleanup() + return SUCCESS diff --git a/venv/lib/python3.8/site-packages/pip/_internal/configuration.py b/venv/lib/python3.8/site-packages/pip/_internal/configuration.py index 437e92e..e49a5f4 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/configuration.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/configuration.py @@ -19,7 +19,8 @@ import sys from pip._vendor.six.moves import configparser from pip._internal.exceptions import ( - ConfigurationError, ConfigurationFileCouldNotBeLoaded, + ConfigurationError, + ConfigurationFileCouldNotBeLoaded, ) from pip._internal.utils import appdirs from pip._internal.utils.compat import WINDOWS, expanduser @@ -73,6 +74,7 @@ CONFIG_BASENAME = 'pip.ini' if WINDOWS else 'pip.conf' def get_configuration_files(): + # type: () -> Dict[Kind, List[str]] global_config_files = [ os.path.join(path, CONFIG_BASENAME) for path in appdirs.site_config_dirs('pip') @@ -109,7 +111,7 @@ class Configuration(object): """ def __init__(self, isolated, load_only=None): - # type: (bool, Kind) -> None + # type: (bool, Optional[Kind]) -> None super(Configuration, self).__init__() _valid_load_only = [kinds.USER, kinds.GLOBAL, kinds.SITE, None] @@ -119,8 +121,8 @@ class Configuration(object): ", ".join(map(repr, _valid_load_only[:-1])) ) ) - self.isolated = isolated # type: bool - self.load_only = load_only # type: Optional[Kind] + self.isolated = isolated + self.load_only = load_only # The order here determines the override order. self._override_order = [ @@ -180,6 +182,7 @@ class Configuration(object): """ self._ensure_have_load_only() + assert self.load_only fname, parser = self._get_parser_to_modify() if parser is not None: @@ -195,10 +198,10 @@ class Configuration(object): def unset_value(self, key): # type: (str) -> None - """Unset a value in the configuration. - """ + """Unset a value in the configuration.""" self._ensure_have_load_only() + assert self.load_only if key not in self._config[self.load_only]: raise ConfigurationError("No such key - {}".format(key)) @@ -206,30 +209,18 @@ class Configuration(object): if parser is not None: section, name = _disassemble_key(key) - - # Remove the key in the parser - modified_something = False - if parser.has_section(section): - # Returns whether the option was removed or not - modified_something = parser.remove_option(section, name) - - if modified_something: - # name removed from parser, section may now be empty - section_iter = iter(parser.items(section)) - try: - val = next(section_iter) - except StopIteration: - val = None - - if val is None: - parser.remove_section(section) - - self._mark_as_modified(fname, parser) - else: + if not (parser.has_section(section) + and parser.remove_option(section, name)): + # The option was not removed. raise ConfigurationError( "Fatal Internal error [id=1]. Please report as a bug." ) + # The section may be empty after the option was removed. + if not parser.items(section): + parser.remove_section(section) + self._mark_as_modified(fname, parser) + del self._config[self.load_only][key] def save(self): @@ -275,7 +266,7 @@ class Configuration(object): # type: () -> None """Loads configuration from configuration files """ - config_files = dict(self._iter_config_files()) + config_files = dict(self.iter_config_files()) if config_files[kinds.ENV][0:1] == [os.devnull]: logger.debug( "Skipping loading configuration files due to " @@ -337,7 +328,7 @@ class Configuration(object): """Loads configuration from environment variables """ self._config[kinds.ENV_VAR].update( - self._normalized_keys(":env:", self._get_environ_vars()) + self._normalized_keys(":env:", self.get_environ_vars()) ) def _normalized_keys(self, section, items): @@ -353,7 +344,7 @@ class Configuration(object): normalized[key] = val return normalized - def _get_environ_vars(self): + def get_environ_vars(self): # type: () -> Iterable[Tuple[str, str]] """Returns a generator with all environmental vars with prefix PIP_""" for key, val in os.environ.items(): @@ -365,7 +356,7 @@ class Configuration(object): yield key[4:].lower(), val # XXX: This is patched in the tests. - def _iter_config_files(self): + def iter_config_files(self): # type: () -> Iterable[Tuple[Kind, List[str]]] """Yields variant and configuration files associated with it. @@ -396,9 +387,15 @@ class Configuration(object): # finally virtualenv configuration first trumping others yield kinds.SITE, config_files[kinds.SITE] + def get_values_in_config(self, variant): + # type: (Kind) -> Dict[str, Any] + """Get values present in a config file""" + return self._config[variant] + def _get_parser_to_modify(self): # type: () -> Tuple[str, RawConfigParser] # Determine which parser to modify + assert self.load_only parsers = self._parsers[self.load_only] if not parsers: # This should not happen if everything works correctly. @@ -415,3 +412,7 @@ class Configuration(object): file_parser_tuple = (fname, parser) if file_parser_tuple not in self._modified_parsers: self._modified_parsers.append(file_parser_tuple) + + def __repr__(self): + # type: () -> str + return "{}({!r})".format(self.__class__.__name__, self._dictionary) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/distributions/__init__.py b/venv/lib/python3.8/site-packages/pip/_internal/distributions/__init__.py index fdf332a..d5c1afc 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/distributions/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/distributions/__init__.py @@ -1,6 +1,5 @@ -from pip._internal.distributions.source import SourceDistribution +from pip._internal.distributions.sdist import SourceDistribution from pip._internal.distributions.wheel import WheelDistribution - from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: @@ -12,11 +11,13 @@ def make_distribution_for_install_requirement(install_req): # type: (InstallRequirement) -> AbstractDistribution """Returns a Distribution for the given InstallRequirement """ - # If it's not an editable, is a wheel, it's a WheelDistribution + # Editable requirements will always be source distributions. They use the + # legacy logic until we create a modern standard for them. if install_req.editable: return SourceDistribution(install_req) - if install_req.link and install_req.is_wheel: + # If it's a wheel, it's a WheelDistribution + if install_req.is_wheel: return WheelDistribution(install_req) # Otherwise, a SourceDistribution diff --git a/venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-38.pyc index 2d41e5a9122446848ea3d28faf963cae28aae850..5a5fd33c2dfbdd63977b33218868f7ba2558e739 100644 GIT binary patch delta 248 zcmdnSc8-lVl$V!_0SGkz?TX(&k@v5Z3XoI7ki}5MSHf7s(99SN;xQG;lrT@$V)Pea zxy6y1l39|Nl#^P-1XMb?pHa~RWWuj3{fzwFRQ;mL($cI<{o<lz{glMK%+#FZ{GyW7 zV!evWD*dw5yfXcq%q0DS%94!yJYziz{o>4$RNaEa<m|-s)Z)pP8H1%kh82U|#Ky+R z!3@GhJU}r&P43BAOmeKnDVfD3lT(>ynS(@&Kq`?4ZXov-hfQvNN@-529V3ue3{u9! L2!u>5Ad(pXY4$wu delta 206 zcmX@dwvCN9l$V!_0SKO#ZHSAV$op483&^Qq$YLnsD`Bi*Xl4us@tBH~fFyH~QVGjs z6-IwC)>|B@DVZgSNja%SOh65{SaLG+vL`n)Dk^gWxxZZXOL7bJ3o;9IGxLf|5_58N zjWSG1D~$6KL4uRtFb2zl)D?rRW@TgKVB%rqU@qbXiuq}B-%^@<mPv-KIKQ+gIdyU^ d(=1VtL=i{_62UWBhgp)7iHC`Wk%y6o834Z2FjW8m diff --git a/venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/base.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/base.cpython-38.pyc index 2763a7b97629ef210b6890e14f51dd0014943c17..39a6172192456e46e27cefaae3c88b2712cb4f14 100644 GIT binary patch delta 852 zcmY*WPixdb6wf4+Y<4%<v_+6=1*sHV!Q>!<hzPZ6TcvBM7HJM0vYBZ+?c`5qlG63E zhk8{h`4simt4F_q*L(xNf`T}cR@u&wU*7M%dB2(W-Vf)i*V}a6jwV<C&o^{xp7!R( zTr#X-z_d{Pbp{eW)Pb@MW+X6#KqHX9lN>TLu|lhfnXHxAq21UPYbTws)7UN6O`On? zIXcny-4n2^VH>wUYPd~$C&mc~Jq+Gz{mxJIj6r`4YB$0dC8UUA775V@^~~DV`W9MR zd9m~wZEOw(tAl0fwcq3g&C-ZT+j&k!!RfG69+k10iXvicgB+HWlZ2#&^t$U&d=TxD zmo&wM$Lhk#Whip~<y;4LwP@UY??`$E>NY~nLl8RCe(eN%SwaFnD$9Ku2p$JGN-1G+ z#tS0+<I#uUh@?jWqr)H{6?<9wz<(47T9Ets#pR;<Y%F+PseN010!q;I>bvm@v?~|h znsO!QQ~zPQdJOM$7bF+D1kI@S;P%6|iqA;s8(byS)=pDX?F~!HFrp%3k?O@2rQdMA zdrzMJr*zlEpj&-1XUEr+-gPD9URE0u#t@oF@2Mlx3Tz3U{Df+dtwYZ-A?QE|nn-_& z&q;si<uvz^YzEG_FX%B>&#!MZUYZt!%gOn2UQGDKc$Cw0m#YEPR&ha8W5U@<k^Ep6 zaU!yk$3$>b#iy^zadOBlB{F~2uX=OrUk(6Ww2HUX!Perlr8TlrM75O-_eoqdHB6M< eOhT1i+fR}VmyA3Gk_pv(TX*D!Kq8Rau)$w%=+$rl delta 472 zcmYjN%}T>S5Z>9{q|qjg6hTBqP&^c@h1O#cst3j2gLvt|C3XY0q$VV-h!=(W0%f0~ zo&--mfd@}s^8)G{h<I=|__wg%?zc1F%r|@MKHG&O#~CNMUe521U)iuQdr(CtiG+YO z^+^Nh(k2DsQ=fF$05*walHU-?eLg_mG$b67lJTa??3W;QJSj!j?|H4jOOpE{JW^mP zWi!<rW{e;m6Cw)<F(Mz0O0OGLqIOhnpCvsn2+Gyd)&4~-^z@_J<x8%KvMJmNM<AfC z`8II%#OEd~<Z=ENZ1v6;of+f_MIiLDrXrYBbz{rX+SoxTvDi{WV=n(+_h2kI^BDZm zRWseEu@9!&F{iIwtu7*@&bRrN9|S`DYd)q^Yz+)Sdrma7D0gknVVrTuA|*4{!=x^b zw<6B{Ga1G!N&6z!meX8gePa**E;YlGj^FBKl6d*gYj)FxQ>)$$Wk2xO09m3NTGVD1 Fd;vA+V<Z3o diff --git a/venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-38.pyc index 781e0ed6b016eefd6a7cb37e7603b388e5b96a6b..caba054a70ec98e1c2902d6572d23c2e59b86346 100644 GIT binary patch delta 600 zcmZWlO>fgc5Zw>QcA7Yp9x8$0(hD*YHd2K|C4`Uyv=zccKo9Z7a<WUZWc{ICyJ~vj z0DqwJl|R9?5`V-u{srQIn00ahvC_VsHy*!vGvA%IKRWZg9R$b!eVzOySED=edteMP zEK!DIj7>}=$!JV5;#55YPNkLg;$HX7l6L0AP8av2oAu*9M#qTR%=v<t!|`Vt?=bfr z^7~hlyJH`>d#|UHX)-=}F@BZ2J&U5#=oqr@o3au`o=S*^&xNj(nAIi&+?%BHRl49W zMb5bTmfgoELvZ<P6)ua6hiYBdA4RCuJY;DuxSSWN;ySokUxw#AKM$pth2^?h7WrZD zIMkxz56X?AZm#j^U=PGJ0YIb~k?A8BB4s-GR1M&1?GIh&_QtFhk|jbHGBw`1q78V> zS90L(L-kha^03(@`^^s$9gU3MO#?>sFYpX?08AHc1Gw0-U8~DQ{-9aXd!O3dr6_|$ z<P}%2p8&QZbx^HKkuMa5e_DG>EFkf%t{UcMg$l~mB2ioywVHFSdZzf`Uo|t>MX+5* kvYAsEC!GiI`tU!;t@|V^SS|Te40YPfG{i$<!G)Lp0joflrT_o{ delta 309 zcmcb`xtE<Ul$V!_0SKO#ZHU{%IFV1rSpmpPVMt-jVaR2SVq|1+XGmd6VQyhaVNPXi zW{zS?VF_l?WPJ(Jq{(<o#4)M3q$n}D#3d6*XC{@FWaj5>e4@pu%mGyJ%T2!|w?Mxj zvp_d9uec;JCr8&P!=$vrI6o02I5~{Tlbai;u9yjA9OL9wOp&}SKvoe*vnF#9`(y!T zS#A&qEK<Zd*@9V#n-9o`=}2Wxvjlmdh!?I1NjXT28AyQ4EM@}|9E>b%9L!)bKTYPz gEG+7JU=GB1RGqgtY;yBcN^?@}7(v=WPUK+*07Ei53jhEB diff --git a/venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/source.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/source.cpython-38.pyc deleted file mode 100644 index a0dd331d63404a9ad1dec00250ba536d1754e4fe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3054 zcmb_eTW{P%6rQoY-pwW{X&S;sv<x?imCB}pR9sY5g|@0%L4cH-RxOU>ncX<`+Rn^u z(yTTwq*BWhe}IS0W8Zk@oj)<JAR+z%LV|G4*qiRs3JD2Y9*^hDoZEco8-G4KTPJY+ zy7R-=Kh6^JGk%O;9(-JaN8Nyi6HXJ-!nc#quG4ZT_T9wodM(fPy`<9hTRtU%46CAc zNLy3a2(NJe9^t<54%}9q)0?DG{SEYy)dn?lAN1mcUrl#nnWbHkY8YF1e?w^*M*2z& z?|7r9<1B^olh;$F!z2mu`>K?gj8M(^<-o@!coc(1kQU{n<#5_^xx?Liq~&psSKtjU zp&MrYX4aFD7&jFDL<w0FxfBZAQ7mN2&S8Aan`XVv;QDM+FqoK!()z@d7CCEYlIcxY z%~Bz_VqKv_9_nx;V0jqb2|GeDov{sJ6?H@^K!@OGnTTPrWIYw99rnr9PuTh8w;8A` z20+FV(FvnHwyuQk<;{GLiB2bo({{FAy0!Z8XIEKUW?gnEmm%NlrK-bTUtVE1dZ}P< zo?CvmVXa<g;%+V?%^uGJi;_?&wi_pj4WsatsXU1_i&LFh1?z<?L6M<#_WH3)8=(@s z!NQb-pEiFW9Ys?LcQ-}Kb_HZDl-laskPtM+on)OjvI!ecZ`RW+YqJstYht?>OM#%V z9zoJ$RruYs+9KG<;|u$Uj?3^UME!tlks&=KfCIYPaEvR(wyAZ54sfFZZk`fJ`yr82 zF!_(mOS+pc<#GN-T!8S6H#b*$ci+lF9JCK?ffh0ilcjN_sHGx&*e7!awdZ#_0btAK zL|I!Sh%cgR=p&*1<(rQIv-$6<BNtbeR~6pqH;$<}i2VUAqNTRC<zx#3XWzX~?$b8Z z2Y2q(_Pv2Cf7kAToe_ArV#^y=2GsU^?sD%C%Dfz}+BcN=E$3UZUwJ@eI)K`GKn{Qw z1{L|eo*LG<kFyS8#C}zIZ8)uG^sGKHs2tD(=a8bT(D>c+Kp|7u51z6kbHkH|WZ(ai zoF|`>HS*Q5<$*tD^%t;OFRT`N(BnacPxG0Px5N2EQdk+D!XC#xpIwb?s>_679}{*8 z6LuCF4QvMr=>XVn2;{-Ndqlfnh+cu`kha}Lcz*)~1Ij9^{gs<pSFjCaGsZ<OQZCXc zh9XBgcnxrwrR^k!THA&ChJp9sY4)A7YyzdYUr4$NpEJ-5$nC{j&OY6DIDxpFwzEjS zfEc!6*TAsTe;#xL?Bg`bx;e1WMj}QgRxNZJu5p^@%v6b6!HvHg0#dn^77f;enYw^1 zbT^k5Uq$QahUfT4{o7A~Vo{Z10=~hB=$aRjED95Ku^GrPRw5Y1t{zE_Z8bcJmZXm^ zcw1SV8ee4+{DYdD8?6LR2rzMzBT%vGp<|}UX2}{V!=02isJVZ-@DhmBJT!zlaC<-s zb;tk9Kk|<HH~zm!O*PvQG70zkr%Sp*T6-KG{g+EpTspt}4pY56x3Mz_ZA5OWzw%M6 z>~T=6AD6+#vwSa?*%t74Q)k_z1YEPfUYt%=!gvNyOfwA(E~2=-$HLN?4LFPdtY<A% z1C_BTOmSWt4qApnWPVHQI?EC~5%ebVFrv3&7xiDcCbY)zCLF`V%~k`@yh!@b;>lGS zn<x<Dr<v@AN&m(1L=|35Ol&L^AUTy}ArFp&4lrm_?*Yzok;7prv6ju0H6Dm`$1If4 z2ikp<R5SlbLpiR@e6%T|JCpOC9$y8<0z1d}a71;4G}YZurVzZGL#u8#%#8<s1X7;F z?-`ZHDHMiMaNwI0g@Zwv2J-?k`p9?yL=hBD+l-mHQIU=6%AAHHSx8+Tw?Q}5;EM_X zXbS(3suujlZ^uAB(mYiti&a+qF_{wzb}r#TF(M?MH>TPxu!UZ4tD<riKv0y=>5&iP zN7`|rKL_*F8Z@L*r!&rps^`{ejXK09P+Na_UXA)kHP@pab&fp8zNrV}@a@e1>DB5^ zjV{u8kQeKmVjXDfpZl-1xZ3bdEeO)ED}un(gP@!7UV{CZAlUAONhzrY0nef!kkc4t z6B|nxj~XNnS%C&S3W=#kz3G~3#~Rb7idzp`Zk~a9X&xW@&11wB2xODe@eHaa{sKv4 zd-Lq%G;uc)IsV`(%Zp|TF!G^=np}eEl3|0+J;`fRyHG@Z5r22=Z%)mbp>R8O_iyt4 Bm8Adx diff --git a/venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-38.pyc index dec6adf300dd9a6907b88bf18f9b4a0863c800db..93566e312e99c4e2d8a9b4c6986667bfa0e817a9 100644 GIT binary patch literal 1594 zcmaJ>PmkO*6t|PiWOh2cZC6w(NFZy)Wh9zZ;*U5W)M{x9qKwM6)zVyCPwbh=)`_#W z(>9}Wp}iu$1DyB@e3V={@fA1#&z^0SDNsj#aqQ>k_kO>hbANYtjG#^b`i<@l5c=JH z^jicU*Pxq+U^wDfq7r8qyKx|cGR#6h4rNphvVk8*a#+S$jFA}V+u%2lqjD$P@oPgl zF3)A>FuH|!%ttQ}ABpgJm`(W3T{Ip40jHoT?&7SdZx&L(@U81}V>Qd|7X`eFd1DJz z!TkO=5AHmmhhN?}{F)x!pUu9S-GbTo>qkqfg;9;pg`vE+hc1++PgX)m@SD6AZTAk# zAF-vlSyWu;+@;ZP0eoD8ZU`8GGR#pHaGZra;Nc6DMLgmIcn|mx%80v*$L^f|8SB#{ zQA1*)vW76?^C127lJS^8ySFL~;Yt`%DN8CLIAK*wU~A1ZbF~v@Hrox!Sw-do!f26O z*^;KJp$x$jA1cR??91jVa8w^cH}}9iLnr72n~4p6z<wN>%WiC=%?ign_%ZnD;CpNb z&(1tHE6>AY6rhjMx9AA{g6{hFcZi2jd9?odwqo26yAq@nmT_hoS!h-InN8ITAeI!B zRp3!7-9mw!Xki;&0W>~!heRJe*v%|y48T&@4?Hwl$hN4K1ORb|^+GHCDux!P4S-Vu z>KjZv#K8ZUNvWQI%0BsMHXU{$ICkfy%9*4tJz6un>h`W1BecW(hSo}VQN>E39g-UE z3YrF8WQ1IFc>OEV7hvYkWx7(ONOjvZCq-&>o^n<dLgq?aVUnlqI(;mv$EhslY2DhD zsy<9UO-*6N6~`P1(4=)yrxf53x?(czOT?tU%A{_)_m;xa|JV9HBx77gD4qn9U>^rK zKtnYAdwuozb!8@R4wZ*4%vp0|rz)=^_iy09{}j)B_0v%A!BjU~_)FBCpErf%v@l9~ z;d-Zyx#;}f-H2Lj-_n<=IRF>qutvc;{ddxD-0LVEQR?WTv>Q`eD&7FAw3|?R+Aw*x z5>v`mPN{Zy=}XQy(0axtsz+cZ(9ICc2uFj_1wS{N?soCIsGVZGEII<@C9lX!w#ZB7 z4AkTh?B3aSgI}67iEV4pvv#O<Z~vErC*LbC+pL3>xYEg%47AI!JJ{au_;{L}DGUVe i{&6}6M_)#-TwlE>XY|<yv(Fvf#_<Y5!tex<v*ABwV8=uN delta 420 zcmZutJx{|h5Vd0`geEOj2R;NWY!NL*z=#+?fW%M<AqE(zTI@nfnglzkKtf_Df1vUo zC<_uBGk=3Ee*m#DBM|t)z=EZB^1XY0cjssKYpirwEEbSHul=W!PdqHm;p%X4wz`WL zVe}3$%E^EnQ)V6@&w2x;hqGdQan=-EMyWXEayXh+Q~2c;>mt?I(vXunBq+fn;|6s} zm)_$6W_Si^8>1mW>X{i0e3=MCCt0QAhpfpU_uFaWN1@D!;Fnq9w~H<b-I+=rbRLm_ znLjq`NiVL)eq8fInUq^WP+K`)ORrX=7O+Z@?TV{~GT#te*!rf}Q19f(2F4>|T<z0& z2a?=TIO>`%IAwSPQz5J#XnO}d!~}#tWqxyjgOx1}3BktHv}w*Y^n#8aW2xEaA&Z3C aGpoya<v*LuUhhRL4fqE9jRaHIaLEsVcU>I- diff --git a/venv/lib/python3.8/site-packages/pip/_internal/distributions/base.py b/venv/lib/python3.8/site-packages/pip/_internal/distributions/base.py index b9af3f0..b836b98 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/distributions/base.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/distributions/base.py @@ -2,6 +2,15 @@ import abc from pip._vendor.six import add_metaclass +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional + + from pip._vendor.pkg_resources import Distribution + from pip._internal.req import InstallRequirement + from pip._internal.index.package_finder import PackageFinder + @add_metaclass(abc.ABCMeta) class AbstractDistribution(object): @@ -21,13 +30,16 @@ class AbstractDistribution(object): """ def __init__(self, req): + # type: (InstallRequirement) -> None super(AbstractDistribution, self).__init__() self.req = req @abc.abstractmethod def get_pkg_resources_distribution(self): + # type: () -> Optional[Distribution] raise NotImplementedError() @abc.abstractmethod def prepare_distribution_metadata(self, finder, build_isolation): + # type: (PackageFinder, bool) -> None raise NotImplementedError() diff --git a/venv/lib/python3.8/site-packages/pip/_internal/distributions/installed.py b/venv/lib/python3.8/site-packages/pip/_internal/distributions/installed.py index c4a64e7..0d15bf4 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/distributions/installed.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/distributions/installed.py @@ -1,4 +1,11 @@ from pip._internal.distributions.base import AbstractDistribution +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional + + from pip._vendor.pkg_resources import Distribution + from pip._internal.index.package_finder import PackageFinder class InstalledDistribution(AbstractDistribution): @@ -9,7 +16,9 @@ class InstalledDistribution(AbstractDistribution): """ def get_pkg_resources_distribution(self): + # type: () -> Optional[Distribution] return self.req.satisfied_by def prepare_distribution_metadata(self, finder, build_isolation): + # type: (PackageFinder, bool) -> None pass diff --git a/venv/lib/python3.8/site-packages/pip/_internal/distributions/source.py b/venv/lib/python3.8/site-packages/pip/_internal/distributions/source.py deleted file mode 100644 index e5d9fd4..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/distributions/source.py +++ /dev/null @@ -1,80 +0,0 @@ -import logging - -from pip._internal.build_env import BuildEnvironment -from pip._internal.distributions.base import AbstractDistribution -from pip._internal.exceptions import InstallationError - -logger = logging.getLogger(__name__) - - -class SourceDistribution(AbstractDistribution): - """Represents a source distribution. - - The preparation step for these needs metadata for the packages to be - generated, either using PEP 517 or using the legacy `setup.py egg_info`. - - NOTE from @pradyunsg (14 June 2019) - I expect SourceDistribution class will need to be split into - `legacy_source` (setup.py based) and `source` (PEP 517 based) when we start - bringing logic for preparation out of InstallRequirement into this class. - """ - - def get_pkg_resources_distribution(self): - return self.req.get_dist() - - def prepare_distribution_metadata(self, finder, build_isolation): - # Prepare for building. We need to: - # 1. Load pyproject.toml (if it exists) - # 2. Set up the build environment - - self.req.load_pyproject_toml() - should_isolate = self.req.use_pep517 and build_isolation - - def _raise_conflicts(conflicting_with, conflicting_reqs): - raise InstallationError( - "Some build dependencies for %s conflict with %s: %s." % ( - self.req, conflicting_with, ', '.join( - '%s is incompatible with %s' % (installed, wanted) - for installed, wanted in sorted(conflicting)))) - - if should_isolate: - # Isolate in a BuildEnvironment and install the build-time - # requirements. - self.req.build_env = BuildEnvironment() - self.req.build_env.install_requirements( - finder, self.req.pyproject_requires, 'overlay', - "Installing build dependencies" - ) - conflicting, missing = self.req.build_env.check_requirements( - self.req.requirements_to_check - ) - if conflicting: - _raise_conflicts("PEP 517/518 supported requirements", - conflicting) - if missing: - logger.warning( - "Missing build requirements in pyproject.toml for %s.", - self.req, - ) - logger.warning( - "The project does not specify a build backend, and " - "pip cannot fall back to setuptools without %s.", - " and ".join(map(repr, sorted(missing))) - ) - # Install any extra build dependencies that the backend requests. - # This must be done in a second pass, as the pyproject.toml - # dependencies must be installed before we can call the backend. - with self.req.build_env: - # We need to have the env active when calling the hook. - self.req.spin_message = "Getting requirements to build wheel" - reqs = self.req.pep517_backend.get_requires_for_build_wheel() - conflicting, missing = self.req.build_env.check_requirements(reqs) - if conflicting: - _raise_conflicts("the backend dependencies", conflicting) - self.req.build_env.install_requirements( - finder, missing, 'normal', - "Installing backend dependencies" - ) - - self.req.prepare_metadata() - self.req.assert_source_matches_version() diff --git a/venv/lib/python3.8/site-packages/pip/_internal/distributions/wheel.py b/venv/lib/python3.8/site-packages/pip/_internal/distributions/wheel.py index de7be38..bf3482b 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/distributions/wheel.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/distributions/wheel.py @@ -1,6 +1,12 @@ -from pip._vendor import pkg_resources +from zipfile import ZipFile from pip._internal.distributions.base import AbstractDistribution +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.wheel import pkg_resources_distribution_for_wheel + +if MYPY_CHECK_RUNNING: + from pip._vendor.pkg_resources import Distribution + from pip._internal.index.package_finder import PackageFinder class WheelDistribution(AbstractDistribution): @@ -10,8 +16,21 @@ class WheelDistribution(AbstractDistribution): """ def get_pkg_resources_distribution(self): - return list(pkg_resources.find_distributions( - self.req.source_dir))[0] + # type: () -> Distribution + """Loads the metadata from the wheel file into memory and returns a + Distribution that uses it, not relying on the wheel file or + requirement. + """ + # Set as part of preparation during download. + assert self.req.local_file_path + # Wheels are never unnamed. + assert self.req.name + + with ZipFile(self.req.local_file_path, allowZip64=True) as z: + return pkg_resources_distribution_for_wheel( + z, self.req.name, self.req.local_file_path + ) def prepare_distribution_metadata(self, finder, build_isolation): + # type: (PackageFinder, bool) -> None pass diff --git a/venv/lib/python3.8/site-packages/pip/_internal/download.py b/venv/lib/python3.8/site-packages/pip/_internal/download.py deleted file mode 100644 index fc1f4dd..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/download.py +++ /dev/null @@ -1,1177 +0,0 @@ -from __future__ import absolute_import - -import cgi -import email.utils -import json -import logging -import mimetypes -import os -import platform -import re -import shutil -import sys - -from pip._vendor import requests, urllib3 -from pip._vendor.cachecontrol import CacheControlAdapter -from pip._vendor.cachecontrol.caches import FileCache -from pip._vendor.lockfile import LockError -from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter -from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth -from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response -from pip._vendor.requests.structures import CaseInsensitiveDict -from pip._vendor.requests.utils import get_netrc_auth -# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is -# why we ignore the type on this import -from pip._vendor.six.moves import xmlrpc_client # type: ignore -from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._vendor.six.moves.urllib import request as urllib_request - -import pip -from pip._internal.exceptions import HashMismatch, InstallationError -from pip._internal.models.index import PyPI -# Import ssl from compat so the initial import occurs in only one place. -from pip._internal.utils.compat import HAS_TLS, ssl -from pip._internal.utils.encoding import auto_decode -from pip._internal.utils.filesystem import check_path_owner -from pip._internal.utils.glibc import libc_ver -from pip._internal.utils.marker_files import write_delete_marker_file -from pip._internal.utils.misc import ( - ARCHIVE_EXTENSIONS, ask, ask_input, ask_password, ask_path_exists, - backup_dir, consume, display_path, format_size, get_installed_version, - path_to_url, remove_auth_from_url, rmtree, split_auth_netloc_from_url, - splitext, unpack_file, -) -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.ui import DownloadProgressProvider -from pip._internal.vcs import vcs - -if MYPY_CHECK_RUNNING: - from typing import ( - Optional, Tuple, Dict, IO, Text, Union - ) - from optparse import Values - from pip._internal.models.link import Link - from pip._internal.utils.hashes import Hashes - from pip._internal.vcs.versioncontrol import AuthInfo, VersionControl - - Credentials = Tuple[str, str, str] - - -__all__ = ['get_file_content', - 'is_url', 'url_to_path', 'path_to_url', - 'is_archive_file', 'unpack_vcs_link', - 'unpack_file_url', 'is_vcs_url', 'is_file_url', - 'unpack_http_url', 'unpack_url', - 'parse_content_disposition', 'sanitize_content_filename'] - - -logger = logging.getLogger(__name__) - - -try: - import keyring # noqa -except ImportError: - keyring = None -except Exception as exc: - logger.warning("Keyring is skipped due to an exception: %s", - str(exc)) - keyring = None - -# These are environment variables present when running under various -# CI systems. For each variable, some CI systems that use the variable -# are indicated. The collection was chosen so that for each of a number -# of popular systems, at least one of the environment variables is used. -# This list is used to provide some indication of and lower bound for -# CI traffic to PyPI. Thus, it is okay if the list is not comprehensive. -# For more background, see: https://github.com/pypa/pip/issues/5499 -CI_ENVIRONMENT_VARIABLES = ( - # Azure Pipelines - 'BUILD_BUILDID', - # Jenkins - 'BUILD_ID', - # AppVeyor, CircleCI, Codeship, Gitlab CI, Shippable, Travis CI - 'CI', - # Explicit environment variable. - 'PIP_IS_CI', -) - - -def looks_like_ci(): - # type: () -> bool - """ - Return whether it looks like pip is running under CI. - """ - # We don't use the method of checking for a tty (e.g. using isatty()) - # because some CI systems mimic a tty (e.g. Travis CI). Thus that - # method doesn't provide definitive information in either direction. - return any(name in os.environ for name in CI_ENVIRONMENT_VARIABLES) - - -def user_agent(): - """ - Return a string representing the user agent. - """ - data = { - "installer": {"name": "pip", "version": pip.__version__}, - "python": platform.python_version(), - "implementation": { - "name": platform.python_implementation(), - }, - } - - if data["implementation"]["name"] == 'CPython': - data["implementation"]["version"] = platform.python_version() - elif data["implementation"]["name"] == 'PyPy': - if sys.pypy_version_info.releaselevel == 'final': - pypy_version_info = sys.pypy_version_info[:3] - else: - pypy_version_info = sys.pypy_version_info - data["implementation"]["version"] = ".".join( - [str(x) for x in pypy_version_info] - ) - elif data["implementation"]["name"] == 'Jython': - # Complete Guess - data["implementation"]["version"] = platform.python_version() - elif data["implementation"]["name"] == 'IronPython': - # Complete Guess - data["implementation"]["version"] = platform.python_version() - - if sys.platform.startswith("linux"): - from pip._vendor import distro - distro_infos = dict(filter( - lambda x: x[1], - zip(["name", "version", "id"], distro.linux_distribution()), - )) - libc = dict(filter( - lambda x: x[1], - zip(["lib", "version"], libc_ver()), - )) - if libc: - distro_infos["libc"] = libc - if distro_infos: - data["distro"] = distro_infos - - if sys.platform.startswith("darwin") and platform.mac_ver()[0]: - data["distro"] = {"name": "macOS", "version": platform.mac_ver()[0]} - - if platform.system(): - data.setdefault("system", {})["name"] = platform.system() - - if platform.release(): - data.setdefault("system", {})["release"] = platform.release() - - if platform.machine(): - data["cpu"] = platform.machine() - - if HAS_TLS: - data["openssl_version"] = ssl.OPENSSL_VERSION - - setuptools_version = get_installed_version("setuptools") - if setuptools_version is not None: - data["setuptools_version"] = setuptools_version - - # Use None rather than False so as not to give the impression that - # pip knows it is not being run under CI. Rather, it is a null or - # inconclusive result. Also, we include some value rather than no - # value to make it easier to know that the check has been run. - data["ci"] = True if looks_like_ci() else None - - user_data = os.environ.get("PIP_USER_AGENT_USER_DATA") - if user_data is not None: - data["user_data"] = user_data - - return "{data[installer][name]}/{data[installer][version]} {json}".format( - data=data, - json=json.dumps(data, separators=(",", ":"), sort_keys=True), - ) - - -def _get_keyring_auth(url, username): - """Return the tuple auth for a given url from keyring.""" - if not url or not keyring: - return None - - try: - try: - get_credential = keyring.get_credential - except AttributeError: - pass - else: - logger.debug("Getting credentials from keyring for %s", url) - cred = get_credential(url, username) - if cred is not None: - return cred.username, cred.password - return None - - if username: - logger.debug("Getting password from keyring for %s", url) - password = keyring.get_password(url, username) - if password: - return username, password - - except Exception as exc: - logger.warning("Keyring is skipped due to an exception: %s", - str(exc)) - - -class MultiDomainBasicAuth(AuthBase): - - def __init__(self, prompting=True, index_urls=None): - # type: (bool, Optional[Values]) -> None - self.prompting = prompting - self.index_urls = index_urls - self.passwords = {} # type: Dict[str, AuthInfo] - # When the user is prompted to enter credentials and keyring is - # available, we will offer to save them. If the user accepts, - # this value is set to the credentials they entered. After the - # request authenticates, the caller should call - # ``save_credentials`` to save these. - self._credentials_to_save = None # type: Optional[Credentials] - - def _get_index_url(self, url): - """Return the original index URL matching the requested URL. - - Cached or dynamically generated credentials may work against - the original index URL rather than just the netloc. - - The provided url should have had its username and password - removed already. If the original index url had credentials then - they will be included in the return value. - - Returns None if no matching index was found, or if --no-index - was specified by the user. - """ - if not url or not self.index_urls: - return None - - for u in self.index_urls: - prefix = remove_auth_from_url(u).rstrip("/") + "/" - if url.startswith(prefix): - return u - - def _get_new_credentials(self, original_url, allow_netrc=True, - allow_keyring=True): - """Find and return credentials for the specified URL.""" - # Split the credentials and netloc from the url. - url, netloc, url_user_password = split_auth_netloc_from_url( - original_url) - - # Start with the credentials embedded in the url - username, password = url_user_password - if username is not None and password is not None: - logger.debug("Found credentials in url for %s", netloc) - return url_user_password - - # Find a matching index url for this request - index_url = self._get_index_url(url) - if index_url: - # Split the credentials from the url. - index_info = split_auth_netloc_from_url(index_url) - if index_info: - index_url, _, index_url_user_password = index_info - logger.debug("Found index url %s", index_url) - - # If an index URL was found, try its embedded credentials - if index_url and index_url_user_password[0] is not None: - username, password = index_url_user_password - if username is not None and password is not None: - logger.debug("Found credentials in index url for %s", netloc) - return index_url_user_password - - # Get creds from netrc if we still don't have them - if allow_netrc: - netrc_auth = get_netrc_auth(original_url) - if netrc_auth: - logger.debug("Found credentials in netrc for %s", netloc) - return netrc_auth - - # If we don't have a password and keyring is available, use it. - if allow_keyring: - # The index url is more specific than the netloc, so try it first - kr_auth = (_get_keyring_auth(index_url, username) or - _get_keyring_auth(netloc, username)) - if kr_auth: - logger.debug("Found credentials in keyring for %s", netloc) - return kr_auth - - return username, password - - def _get_url_and_credentials(self, original_url): - """Return the credentials to use for the provided URL. - - If allowed, netrc and keyring may be used to obtain the - correct credentials. - - Returns (url_without_credentials, username, password). Note - that even if the original URL contains credentials, this - function may return a different username and password. - """ - url, netloc, _ = split_auth_netloc_from_url(original_url) - - # Use any stored credentials that we have for this netloc - username, password = self.passwords.get(netloc, (None, None)) - - if username is None and password is None: - # No stored credentials. Acquire new credentials without prompting - # the user. (e.g. from netrc, keyring, or the URL itself) - username, password = self._get_new_credentials(original_url) - - if username is not None or password is not None: - # Convert the username and password if they're None, so that - # this netloc will show up as "cached" in the conditional above. - # Further, HTTPBasicAuth doesn't accept None, so it makes sense to - # cache the value that is going to be used. - username = username or "" - password = password or "" - - # Store any acquired credentials. - self.passwords[netloc] = (username, password) - - assert ( - # Credentials were found - (username is not None and password is not None) or - # Credentials were not found - (username is None and password is None) - ), "Could not load credentials from url: {}".format(original_url) - - return url, username, password - - def __call__(self, req): - # Get credentials for this request - url, username, password = self._get_url_and_credentials(req.url) - - # Set the url of the request to the url without any credentials - req.url = url - - if username is not None and password is not None: - # Send the basic auth with this request - req = HTTPBasicAuth(username, password)(req) - - # Attach a hook to handle 401 responses - req.register_hook("response", self.handle_401) - - return req - - # Factored out to allow for easy patching in tests - def _prompt_for_password(self, netloc): - username = ask_input("User for %s: " % netloc) - if not username: - return None, None - auth = _get_keyring_auth(netloc, username) - if auth: - return auth[0], auth[1], False - password = ask_password("Password: ") - return username, password, True - - # Factored out to allow for easy patching in tests - def _should_save_password_to_keyring(self): - if not keyring: - return False - return ask("Save credentials to keyring [y/N]: ", ["y", "n"]) == "y" - - def handle_401(self, resp, **kwargs): - # We only care about 401 responses, anything else we want to just - # pass through the actual response - if resp.status_code != 401: - return resp - - # We are not able to prompt the user so simply return the response - if not self.prompting: - return resp - - parsed = urllib_parse.urlparse(resp.url) - - # Prompt the user for a new username and password - username, password, save = self._prompt_for_password(parsed.netloc) - - # Store the new username and password to use for future requests - self._credentials_to_save = None - if username is not None and password is not None: - self.passwords[parsed.netloc] = (username, password) - - # Prompt to save the password to keyring - if save and self._should_save_password_to_keyring(): - self._credentials_to_save = (parsed.netloc, username, password) - - # Consume content and release the original connection to allow our new - # request to reuse the same one. - resp.content - resp.raw.release_conn() - - # Add our new username and password to the request - req = HTTPBasicAuth(username or "", password or "")(resp.request) - req.register_hook("response", self.warn_on_401) - - # On successful request, save the credentials that were used to - # keyring. (Note that if the user responded "no" above, this member - # is not set and nothing will be saved.) - if self._credentials_to_save: - req.register_hook("response", self.save_credentials) - - # Send our new request - new_resp = resp.connection.send(req, **kwargs) - new_resp.history.append(resp) - - return new_resp - - def warn_on_401(self, resp, **kwargs): - """Response callback to warn about incorrect credentials.""" - if resp.status_code == 401: - logger.warning('401 Error, Credentials not correct for %s', - resp.request.url) - - def save_credentials(self, resp, **kwargs): - """Response callback to save credentials on success.""" - assert keyring is not None, "should never reach here without keyring" - if not keyring: - return - - creds = self._credentials_to_save - self._credentials_to_save = None - if creds and resp.status_code < 400: - try: - logger.info('Saving credentials to keyring') - keyring.set_password(*creds) - except Exception: - logger.exception('Failed to save credentials') - - -class LocalFSAdapter(BaseAdapter): - - def send(self, request, stream=None, timeout=None, verify=None, cert=None, - proxies=None): - pathname = url_to_path(request.url) - - resp = Response() - resp.status_code = 200 - resp.url = request.url - - try: - stats = os.stat(pathname) - except OSError as exc: - resp.status_code = 404 - resp.raw = exc - else: - modified = email.utils.formatdate(stats.st_mtime, usegmt=True) - content_type = mimetypes.guess_type(pathname)[0] or "text/plain" - resp.headers = CaseInsensitiveDict({ - "Content-Type": content_type, - "Content-Length": stats.st_size, - "Last-Modified": modified, - }) - - resp.raw = open(pathname, "rb") - resp.close = resp.raw.close - - return resp - - def close(self): - pass - - -class SafeFileCache(FileCache): - """ - A file based cache which is safe to use even when the target directory may - not be accessible or writable. - """ - - def __init__(self, *args, **kwargs): - super(SafeFileCache, self).__init__(*args, **kwargs) - - # Check to ensure that the directory containing our cache directory - # is owned by the user current executing pip. If it does not exist - # we will check the parent directory until we find one that does exist. - # If it is not owned by the user executing pip then we will disable - # the cache and log a warning. - if not check_path_owner(self.directory): - logger.warning( - "The directory '%s' or its parent directory is not owned by " - "the current user and the cache has been disabled. Please " - "check the permissions and owner of that directory. If " - "executing pip with sudo, you may want sudo's -H flag.", - self.directory, - ) - - # Set our directory to None to disable the Cache - self.directory = None - - def get(self, *args, **kwargs): - # If we don't have a directory, then the cache should be a no-op. - if self.directory is None: - return - - try: - return super(SafeFileCache, self).get(*args, **kwargs) - except (LockError, OSError, IOError): - # We intentionally silence this error, if we can't access the cache - # then we can just skip caching and process the request as if - # caching wasn't enabled. - pass - - def set(self, *args, **kwargs): - # If we don't have a directory, then the cache should be a no-op. - if self.directory is None: - return - - try: - return super(SafeFileCache, self).set(*args, **kwargs) - except (LockError, OSError, IOError): - # We intentionally silence this error, if we can't access the cache - # then we can just skip caching and process the request as if - # caching wasn't enabled. - pass - - def delete(self, *args, **kwargs): - # If we don't have a directory, then the cache should be a no-op. - if self.directory is None: - return - - try: - return super(SafeFileCache, self).delete(*args, **kwargs) - except (LockError, OSError, IOError): - # We intentionally silence this error, if we can't access the cache - # then we can just skip caching and process the request as if - # caching wasn't enabled. - pass - - -class InsecureHTTPAdapter(HTTPAdapter): - - def cert_verify(self, conn, url, verify, cert): - conn.cert_reqs = 'CERT_NONE' - conn.ca_certs = None - - -class PipSession(requests.Session): - - timeout = None # type: Optional[int] - - def __init__(self, *args, **kwargs): - retries = kwargs.pop("retries", 0) - cache = kwargs.pop("cache", None) - insecure_hosts = kwargs.pop("insecure_hosts", []) - index_urls = kwargs.pop("index_urls", None) - - super(PipSession, self).__init__(*args, **kwargs) - - # Attach our User Agent to the request - self.headers["User-Agent"] = user_agent() - - # Attach our Authentication handler to the session - self.auth = MultiDomainBasicAuth(index_urls=index_urls) - - # Create our urllib3.Retry instance which will allow us to customize - # how we handle retries. - retries = urllib3.Retry( - # Set the total number of retries that a particular request can - # have. - total=retries, - - # A 503 error from PyPI typically means that the Fastly -> Origin - # connection got interrupted in some way. A 503 error in general - # is typically considered a transient error so we'll go ahead and - # retry it. - # A 500 may indicate transient error in Amazon S3 - # A 520 or 527 - may indicate transient error in CloudFlare - status_forcelist=[500, 503, 520, 527], - - # Add a small amount of back off between failed requests in - # order to prevent hammering the service. - backoff_factor=0.25, - ) - - # We want to _only_ cache responses on securely fetched origins. We do - # this because we can't validate the response of an insecurely fetched - # origin, and we don't want someone to be able to poison the cache and - # require manual eviction from the cache to fix it. - if cache: - secure_adapter = CacheControlAdapter( - cache=SafeFileCache(cache, use_dir_lock=True), - max_retries=retries, - ) - else: - secure_adapter = HTTPAdapter(max_retries=retries) - - # Our Insecure HTTPAdapter disables HTTPS validation. It does not - # support caching (see above) so we'll use it for all http:// URLs as - # well as any https:// host that we've marked as ignoring TLS errors - # for. - insecure_adapter = InsecureHTTPAdapter(max_retries=retries) - # Save this for later use in add_insecure_host(). - self._insecure_adapter = insecure_adapter - - self.mount("https://", secure_adapter) - self.mount("http://", insecure_adapter) - - # Enable file:// urls - self.mount("file://", LocalFSAdapter()) - - # We want to use a non-validating adapter for any requests which are - # deemed insecure. - for host in insecure_hosts: - self.add_insecure_host(host) - - def add_insecure_host(self, host): - # type: (str) -> None - self.mount('https://{}/'.format(host), self._insecure_adapter) - - def request(self, method, url, *args, **kwargs): - # Allow setting a default timeout on a session - kwargs.setdefault("timeout", self.timeout) - - # Dispatch the actual request - return super(PipSession, self).request(method, url, *args, **kwargs) - - -def get_file_content(url, comes_from=None, session=None): - # type: (str, Optional[str], Optional[PipSession]) -> Tuple[str, Text] - """Gets the content of a file; it may be a filename, file: URL, or - http: URL. Returns (location, content). Content is unicode. - - :param url: File path or url. - :param comes_from: Origin description of requirements. - :param session: Instance of pip.download.PipSession. - """ - if session is None: - raise TypeError( - "get_file_content() missing 1 required keyword argument: 'session'" - ) - - match = _scheme_re.search(url) - if match: - scheme = match.group(1).lower() - if (scheme == 'file' and comes_from and - comes_from.startswith('http')): - raise InstallationError( - 'Requirements file %s references URL %s, which is local' - % (comes_from, url)) - if scheme == 'file': - path = url.split(':', 1)[1] - path = path.replace('\\', '/') - match = _url_slash_drive_re.match(path) - if match: - path = match.group(1) + ':' + path.split('|', 1)[1] - path = urllib_parse.unquote(path) - if path.startswith('/'): - path = '/' + path.lstrip('/') - url = path - else: - # FIXME: catch some errors - resp = session.get(url) - resp.raise_for_status() - return resp.url, resp.text - try: - with open(url, 'rb') as f: - content = auto_decode(f.read()) - except IOError as exc: - raise InstallationError( - 'Could not open requirements file: %s' % str(exc) - ) - return url, content - - -_scheme_re = re.compile(r'^(http|https|file):', re.I) -_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I) - - -def is_url(name): - # type: (Union[str, Text]) -> bool - """Returns true if the name looks like a URL""" - if ':' not in name: - return False - scheme = name.split(':', 1)[0].lower() - return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes - - -def url_to_path(url): - # type: (str) -> str - """ - Convert a file: URL to a path. - """ - assert url.startswith('file:'), ( - "You can only turn file: urls into filenames (not %r)" % url) - - _, netloc, path, _, _ = urllib_parse.urlsplit(url) - - if not netloc or netloc == 'localhost': - # According to RFC 8089, same as empty authority. - netloc = '' - elif sys.platform == 'win32': - # If we have a UNC path, prepend UNC share notation. - netloc = '\\\\' + netloc - else: - raise ValueError( - 'non-local file URIs are not supported on this platform: %r' - % url - ) - - path = urllib_request.url2pathname(netloc + path) - return path - - -def is_archive_file(name): - # type: (str) -> bool - """Return True if `name` is a considered as an archive file.""" - ext = splitext(name)[1].lower() - if ext in ARCHIVE_EXTENSIONS: - return True - return False - - -def unpack_vcs_link(link, location): - vcs_backend = _get_used_vcs_backend(link) - vcs_backend.unpack(location, url=link.url) - - -def _get_used_vcs_backend(link): - # type: (Link) -> Optional[VersionControl] - """ - Return a VersionControl object or None. - """ - for vcs_backend in vcs.backends: - if link.scheme in vcs_backend.schemes: - return vcs_backend - return None - - -def is_vcs_url(link): - # type: (Link) -> bool - return bool(_get_used_vcs_backend(link)) - - -def is_file_url(link): - # type: (Link) -> bool - return link.url.lower().startswith('file:') - - -def is_dir_url(link): - # type: (Link) -> bool - """Return whether a file:// Link points to a directory. - - ``link`` must not have any other scheme but file://. Call is_file_url() - first. - - """ - link_path = url_to_path(link.url_without_fragment) - return os.path.isdir(link_path) - - -def _progress_indicator(iterable, *args, **kwargs): - return iterable - - -def _download_url( - resp, # type: Response - link, # type: Link - content_file, # type: IO - hashes, # type: Optional[Hashes] - progress_bar # type: str -): - # type: (...) -> None - try: - total_length = int(resp.headers['content-length']) - except (ValueError, KeyError, TypeError): - total_length = 0 - - cached_resp = getattr(resp, "from_cache", False) - if logger.getEffectiveLevel() > logging.INFO: - show_progress = False - elif cached_resp: - show_progress = False - elif total_length > (40 * 1000): - show_progress = True - elif not total_length: - show_progress = True - else: - show_progress = False - - show_url = link.show_url - - def resp_read(chunk_size): - try: - # Special case for urllib3. - for chunk in resp.raw.stream( - chunk_size, - # We use decode_content=False here because we don't - # want urllib3 to mess with the raw bytes we get - # from the server. If we decompress inside of - # urllib3 then we cannot verify the checksum - # because the checksum will be of the compressed - # file. This breakage will only occur if the - # server adds a Content-Encoding header, which - # depends on how the server was configured: - # - Some servers will notice that the file isn't a - # compressible file and will leave the file alone - # and with an empty Content-Encoding - # - Some servers will notice that the file is - # already compressed and will leave the file - # alone and will add a Content-Encoding: gzip - # header - # - Some servers won't notice anything at all and - # will take a file that's already been compressed - # and compress it again and set the - # Content-Encoding: gzip header - # - # By setting this not to decode automatically we - # hope to eliminate problems with the second case. - decode_content=False): - yield chunk - except AttributeError: - # Standard file-like object. - while True: - chunk = resp.raw.read(chunk_size) - if not chunk: - break - yield chunk - - def written_chunks(chunks): - for chunk in chunks: - content_file.write(chunk) - yield chunk - - progress_indicator = _progress_indicator - - if link.netloc == PyPI.netloc: - url = show_url - else: - url = link.url_without_fragment - - if show_progress: # We don't show progress on cached responses - progress_indicator = DownloadProgressProvider(progress_bar, - max=total_length) - if total_length: - logger.info("Downloading %s (%s)", url, format_size(total_length)) - else: - logger.info("Downloading %s", url) - elif cached_resp: - logger.info("Using cached %s", url) - else: - logger.info("Downloading %s", url) - - logger.debug('Downloading from URL %s', link) - - downloaded_chunks = written_chunks( - progress_indicator( - resp_read(CONTENT_CHUNK_SIZE), - CONTENT_CHUNK_SIZE - ) - ) - if hashes: - hashes.check_against_chunks(downloaded_chunks) - else: - consume(downloaded_chunks) - - -def _copy_file(filename, location, link): - copy = True - download_location = os.path.join(location, link.filename) - if os.path.exists(download_location): - response = ask_path_exists( - 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)abort' % - display_path(download_location), ('i', 'w', 'b', 'a')) - if response == 'i': - copy = False - elif response == 'w': - logger.warning('Deleting %s', display_path(download_location)) - os.remove(download_location) - elif response == 'b': - dest_file = backup_dir(download_location) - logger.warning( - 'Backing up %s to %s', - display_path(download_location), - display_path(dest_file), - ) - shutil.move(download_location, dest_file) - elif response == 'a': - sys.exit(-1) - if copy: - shutil.copy(filename, download_location) - logger.info('Saved %s', display_path(download_location)) - - -def unpack_http_url( - link, # type: Link - location, # type: str - download_dir=None, # type: Optional[str] - session=None, # type: Optional[PipSession] - hashes=None, # type: Optional[Hashes] - progress_bar="on" # type: str -): - # type: (...) -> None - if session is None: - raise TypeError( - "unpack_http_url() missing 1 required keyword argument: 'session'" - ) - - with TempDirectory(kind="unpack") as temp_dir: - # If a download dir is specified, is the file already downloaded there? - already_downloaded_path = None - if download_dir: - already_downloaded_path = _check_download_dir(link, - download_dir, - hashes) - - if already_downloaded_path: - from_path = already_downloaded_path - content_type = mimetypes.guess_type(from_path)[0] - else: - # let's download to a tmp dir - from_path, content_type = _download_http_url(link, - session, - temp_dir.path, - hashes, - progress_bar) - - # unpack the archive to the build dir location. even when only - # downloading archives, they have to be unpacked to parse dependencies - unpack_file(from_path, location, content_type, link) - - # a download dir is specified; let's copy the archive there - if download_dir and not already_downloaded_path: - _copy_file(from_path, download_dir, link) - - if not already_downloaded_path: - os.unlink(from_path) - - -def unpack_file_url( - link, # type: Link - location, # type: str - download_dir=None, # type: Optional[str] - hashes=None # type: Optional[Hashes] -): - # type: (...) -> None - """Unpack link into location. - - If download_dir is provided and link points to a file, make a copy - of the link file inside download_dir. - """ - link_path = url_to_path(link.url_without_fragment) - - # If it's a url to a local directory - if is_dir_url(link): - if os.path.isdir(location): - rmtree(location) - shutil.copytree(link_path, location, symlinks=True) - if download_dir: - logger.info('Link is a directory, ignoring download_dir') - return - - # If --require-hashes is off, `hashes` is either empty, the - # link's embedded hash, or MissingHashes; it is required to - # match. If --require-hashes is on, we are satisfied by any - # hash in `hashes` matching: a URL-based or an option-based - # one; no internet-sourced hash will be in `hashes`. - if hashes: - hashes.check_against_path(link_path) - - # If a download dir is specified, is the file already there and valid? - already_downloaded_path = None - if download_dir: - already_downloaded_path = _check_download_dir(link, - download_dir, - hashes) - - if already_downloaded_path: - from_path = already_downloaded_path - else: - from_path = link_path - - content_type = mimetypes.guess_type(from_path)[0] - - # unpack the archive to the build dir location. even when only downloading - # archives, they have to be unpacked to parse dependencies - unpack_file(from_path, location, content_type, link) - - # a download dir is specified and not already downloaded - if download_dir and not already_downloaded_path: - _copy_file(from_path, download_dir, link) - - -class PipXmlrpcTransport(xmlrpc_client.Transport): - """Provide a `xmlrpclib.Transport` implementation via a `PipSession` - object. - """ - - def __init__(self, index_url, session, use_datetime=False): - xmlrpc_client.Transport.__init__(self, use_datetime) - index_parts = urllib_parse.urlparse(index_url) - self._scheme = index_parts.scheme - self._session = session - - def request(self, host, handler, request_body, verbose=False): - parts = (self._scheme, host, handler, None, None, None) - url = urllib_parse.urlunparse(parts) - try: - headers = {'Content-Type': 'text/xml'} - response = self._session.post(url, data=request_body, - headers=headers, stream=True) - response.raise_for_status() - self.verbose = verbose - return self.parse_response(response.raw) - except requests.HTTPError as exc: - logger.critical( - "HTTP error %s while getting %s", - exc.response.status_code, url, - ) - raise - - -def unpack_url( - link, # type: Link - location, # type: str - download_dir=None, # type: Optional[str] - only_download=False, # type: bool - session=None, # type: Optional[PipSession] - hashes=None, # type: Optional[Hashes] - progress_bar="on" # type: str -): - # type: (...) -> None - """Unpack link. - If link is a VCS link: - if only_download, export into download_dir and ignore location - else unpack into location - for other types of link: - - unpack into location - - if download_dir, copy the file into download_dir - - if only_download, mark location for deletion - - :param hashes: A Hashes object, one of whose embedded hashes must match, - or HashMismatch will be raised. If the Hashes is empty, no matches are - required, and unhashable types of requirements (like VCS ones, which - would ordinarily raise HashUnsupported) are allowed. - """ - # non-editable vcs urls - if is_vcs_url(link): - unpack_vcs_link(link, location) - - # file urls - elif is_file_url(link): - unpack_file_url(link, location, download_dir, hashes=hashes) - - # http urls - else: - if session is None: - session = PipSession() - - unpack_http_url( - link, - location, - download_dir, - session, - hashes=hashes, - progress_bar=progress_bar - ) - if only_download: - write_delete_marker_file(location) - - -def sanitize_content_filename(filename): - # type: (str) -> str - """ - Sanitize the "filename" value from a Content-Disposition header. - """ - return os.path.basename(filename) - - -def parse_content_disposition(content_disposition, default_filename): - # type: (str, str) -> str - """ - Parse the "filename" value from a Content-Disposition header, and - return the default filename if the result is empty. - """ - _type, params = cgi.parse_header(content_disposition) - filename = params.get('filename') - if filename: - # We need to sanitize the filename to prevent directory traversal - # in case the filename contains ".." path parts. - filename = sanitize_content_filename(filename) - return filename or default_filename - - -def _download_http_url( - link, # type: Link - session, # type: PipSession - temp_dir, # type: str - hashes, # type: Optional[Hashes] - progress_bar # type: str -): - # type: (...) -> Tuple[str, str] - """Download link url into temp_dir using provided session""" - target_url = link.url.split('#', 1)[0] - try: - resp = session.get( - target_url, - # We use Accept-Encoding: identity here because requests - # defaults to accepting compressed responses. This breaks in - # a variety of ways depending on how the server is configured. - # - Some servers will notice that the file isn't a compressible - # file and will leave the file alone and with an empty - # Content-Encoding - # - Some servers will notice that the file is already - # compressed and will leave the file alone and will add a - # Content-Encoding: gzip header - # - Some servers won't notice anything at all and will take - # a file that's already been compressed and compress it again - # and set the Content-Encoding: gzip header - # By setting this to request only the identity encoding We're - # hoping to eliminate the third case. Hopefully there does not - # exist a server which when given a file will notice it is - # already compressed and that you're not asking for a - # compressed file and will then decompress it before sending - # because if that's the case I don't think it'll ever be - # possible to make this work. - headers={"Accept-Encoding": "identity"}, - stream=True, - ) - resp.raise_for_status() - except requests.HTTPError as exc: - logger.critical( - "HTTP error %s while getting %s", exc.response.status_code, link, - ) - raise - - content_type = resp.headers.get('content-type', '') - filename = link.filename # fallback - # Have a look at the Content-Disposition header for a better guess - content_disposition = resp.headers.get('content-disposition') - if content_disposition: - filename = parse_content_disposition(content_disposition, filename) - ext = splitext(filename)[1] # type: Optional[str] - if not ext: - ext = mimetypes.guess_extension(content_type) - if ext: - filename += ext - if not ext and link.url != resp.url: - ext = os.path.splitext(resp.url)[1] - if ext: - filename += ext - file_path = os.path.join(temp_dir, filename) - with open(file_path, 'wb') as content_file: - _download_url(resp, link, content_file, hashes, progress_bar) - return file_path, content_type - - -def _check_download_dir(link, download_dir, hashes): - # type: (Link, str, Optional[Hashes]) -> Optional[str] - """ Check download_dir for previously downloaded file with correct hash - If a correct file is found return its path else None - """ - download_path = os.path.join(download_dir, link.filename) - if os.path.exists(download_path): - # If already downloaded, does its hash match? - logger.info('File was already downloaded %s', download_path) - if hashes: - try: - hashes.check_against_path(download_path) - except HashMismatch: - logger.warning( - 'Previously-downloaded file %s has bad hash. ' - 'Re-downloading.', - download_path - ) - os.unlink(download_path) - return None - return download_path - return None diff --git a/venv/lib/python3.8/site-packages/pip/_internal/exceptions.py b/venv/lib/python3.8/site-packages/pip/_internal/exceptions.py index 096adcd..3f26215 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/exceptions.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/exceptions.py @@ -1,4 +1,5 @@ """Exceptions used throughout package""" + from __future__ import absolute_import from itertools import chain, groupby, repeat @@ -8,10 +9,20 @@ from pip._vendor.six import iteritems from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: - from typing import Optional + from typing import Any, Optional, List, Dict, Text + from pip._vendor.pkg_resources import Distribution + from pip._vendor.requests.models import Response, Request + from pip._vendor.six import PY3 + from pip._vendor.six.moves import configparser + from pip._internal.req.req_install import InstallRequirement + if PY3: + from hashlib import _Hash + else: + from hashlib import _hash as _Hash + class PipError(Exception): """Base pip exception""" @@ -80,10 +91,38 @@ class CommandError(PipError): """Raised when there is an error in command-line arguments""" +class SubProcessError(PipError): + """Raised when there is an error raised while executing a + command in subprocess""" + + class PreviousBuildDirError(PipError): """Raised when there's a previous conflicting build directory""" +class NetworkConnectionError(PipError): + """HTTP connection error""" + + def __init__(self, error_msg, response=None, request=None): + # type: (Text, Response, Request) -> None + """ + Initialize NetworkConnectionError with `request` and `response` + objects. + """ + self.response = response + self.request = request + self.error_msg = error_msg + if (self.response is not None and not self.request and + hasattr(response, 'request')): + self.request = self.response.request + super(NetworkConnectionError, self).__init__( + error_msg, response, request) + + def __str__(self): + # type: () -> str + return str(self.error_msg) + + class InvalidWheelFilename(InstallationError): """Invalid wheel filename.""" @@ -92,16 +131,39 @@ class UnsupportedWheel(InstallationError): """Unsupported wheel.""" +class MetadataInconsistent(InstallationError): + """Built metadata contains inconsistent information. + + This is raised when the metadata contains values (e.g. name and version) + that do not match the information previously obtained from sdist filename + or user-supplied ``#egg=`` value. + """ + def __init__(self, ireq, field, built): + # type: (InstallRequirement, str, Any) -> None + self.ireq = ireq + self.field = field + self.built = built + + def __str__(self): + # type: () -> str + return "Requested {} has different {} in metadata: {!r}".format( + self.ireq, self.field, self.built, + ) + + class HashErrors(InstallationError): """Multiple HashError instances rolled into one for reporting""" def __init__(self): - self.errors = [] + # type: () -> None + self.errors = [] # type: List[HashError] def append(self, error): + # type: (HashError) -> None self.errors.append(error) def __str__(self): + # type: () -> str lines = [] self.errors.sort(key=lambda e: e.order) for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__): @@ -109,11 +171,14 @@ class HashErrors(InstallationError): lines.extend(e.body() for e in errors_of_cls) if lines: return '\n'.join(lines) + return '' def __nonzero__(self): + # type: () -> bool return bool(self.errors) def __bool__(self): + # type: () -> bool return self.__nonzero__() @@ -135,23 +200,27 @@ class HashError(InstallationError): """ req = None # type: Optional[InstallRequirement] head = '' + order = None # type: Optional[int] def body(self): + # type: () -> str """Return a summary of me for display under the heading. This default implementation simply prints a description of the triggering requirement. :param req: The InstallRequirement that provoked this error, with - populate_link() having already been called + its link already populated by the resolver's _populate_link(). """ - return ' %s' % self._requirement_name() + return ' {}'.format(self._requirement_name()) def __str__(self): - return '%s\n%s' % (self.head, self.body()) + # type: () -> str + return '{}\n{}'.format(self.head, self.body()) def _requirement_name(self): + # type: () -> str """Return a description of the requirement that triggered me. This default implementation returns long description of the req, with @@ -192,6 +261,7 @@ class HashMissing(HashError): 'has a hash.)') def __init__(self, gotten_hash): + # type: (str) -> None """ :param gotten_hash: The hash of the (possibly malicious) archive we just downloaded @@ -199,6 +269,7 @@ class HashMissing(HashError): self.gotten_hash = gotten_hash def body(self): + # type: () -> str # Dodge circular import. from pip._internal.utils.hashes import FAVORITE_HASH @@ -211,9 +282,9 @@ class HashMissing(HashError): # In case someone feeds something downright stupid # to InstallRequirement's constructor. else getattr(self.req, 'req', None)) - return ' %s --hash=%s:%s' % (package or 'unknown package', - FAVORITE_HASH, - self.gotten_hash) + return ' {} --hash={}:{}'.format(package or 'unknown package', + FAVORITE_HASH, + self.gotten_hash) class HashUnpinned(HashError): @@ -241,6 +312,7 @@ class HashMismatch(HashError): 'someone may have tampered with them.') def __init__(self, allowed, gots): + # type: (Dict[str, List[str]], Dict[str, _Hash]) -> None """ :param allowed: A dict of algorithm names pointing to lists of allowed hex digests @@ -251,10 +323,12 @@ class HashMismatch(HashError): self.gots = gots def body(self): - return ' %s:\n%s' % (self._requirement_name(), - self._hash_comparison()) + # type: () -> str + return ' {}:\n{}'.format(self._requirement_name(), + self._hash_comparison()) def _hash_comparison(self): + # type: () -> str """ Return a comparison of actual and expected hash values. @@ -266,18 +340,18 @@ class HashMismatch(HashError): """ def hash_then_or(hash_name): + # type: (str) -> chain[str] # For now, all the decent hashes have 6-char names, so we can get # away with hard-coding space literals. return chain([hash_name], repeat(' or')) - lines = [] + lines = [] # type: List[str] for hash_name, expecteds in iteritems(self.allowed): prefix = hash_then_or(hash_name) - lines.extend((' Expected %s %s' % (next(prefix), e)) + lines.extend((' Expected {} {}'.format(next(prefix), e)) for e in expecteds) - lines.append(' Got %s\n' % - self.gots[hash_name].hexdigest()) - prefix = ' or' + lines.append(' Got {}\n'.format( + self.gots[hash_name].hexdigest())) return '\n'.join(lines) @@ -291,15 +365,17 @@ class ConfigurationFileCouldNotBeLoaded(ConfigurationError): """ def __init__(self, reason="could not be loaded", fname=None, error=None): + # type: (str, Optional[str], Optional[configparser.Error]) -> None super(ConfigurationFileCouldNotBeLoaded, self).__init__(error) self.reason = reason self.fname = fname self.error = error def __str__(self): + # type: () -> str if self.fname is not None: message_part = " in {}.".format(self.fname) else: assert self.error is not None - message_part = ".\n{}\n".format(self.error.message) + message_part = ".\n{}\n".format(self.error) return "Configuration file {}{}".format(self.reason, message_part) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/index.py b/venv/lib/python3.8/site-packages/pip/_internal/index.py deleted file mode 100644 index a1aaad5..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/index.py +++ /dev/null @@ -1,1508 +0,0 @@ -"""Routines related to PyPI, indexes""" -from __future__ import absolute_import - -import cgi -import itertools -import logging -import mimetypes -import os -import re - -from pip._vendor import html5lib, requests, six -from pip._vendor.distlib.compat import unescape -from pip._vendor.packaging import specifiers -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.packaging.version import parse as parse_version -from pip._vendor.requests.exceptions import HTTPError, RetryError, SSLError -from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._vendor.six.moves.urllib import request as urllib_request - -from pip._internal.download import is_url, url_to_path -from pip._internal.exceptions import ( - BestVersionAlreadyInstalled, DistributionNotFound, InvalidWheelFilename, - UnsupportedWheel, -) -from pip._internal.models.candidate import InstallationCandidate -from pip._internal.models.format_control import FormatControl -from pip._internal.models.link import Link -from pip._internal.models.selection_prefs import SelectionPreferences -from pip._internal.models.target_python import TargetPython -from pip._internal.utils.compat import ipaddress -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, WHEEL_EXTENSION, path_to_url, - redact_password_from_url, -) -from pip._internal.utils.packaging import check_requires_python -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.wheel import Wheel - -if MYPY_CHECK_RUNNING: - from logging import Logger - from typing import ( - Any, Callable, FrozenSet, Iterable, Iterator, List, MutableMapping, - Optional, Sequence, Set, Text, Tuple, Union, - ) - import xml.etree.ElementTree - from pip._vendor.packaging.version import _BaseVersion - from pip._vendor.requests import Response - from pip._internal.models.search_scope import SearchScope - from pip._internal.req import InstallRequirement - from pip._internal.download import PipSession - from pip._internal.pep425tags import Pep425Tag - from pip._internal.utils.hashes import Hashes - - BuildTag = Tuple[Any, ...] # either empty tuple or Tuple[int, str] - CandidateSortingKey = ( - Tuple[int, int, int, _BaseVersion, BuildTag, Optional[int]] - ) - HTMLElement = xml.etree.ElementTree.Element - SecureOrigin = Tuple[str, str, Optional[str]] - - -__all__ = ['FormatControl', 'FoundCandidates', 'PackageFinder'] - - -SECURE_ORIGINS = [ - # protocol, hostname, port - # Taken from Chrome's list of secure origins (See: http://bit.ly/1qrySKC) - ("https", "*", "*"), - ("*", "localhost", "*"), - ("*", "127.0.0.0/8", "*"), - ("*", "::1/128", "*"), - ("file", "*", None), - # ssh is always secure. - ("ssh", "*", "*"), -] # type: List[SecureOrigin] - - -logger = logging.getLogger(__name__) - - -def _match_vcs_scheme(url): - # type: (str) -> Optional[str] - """Look for VCS schemes in the URL. - - Returns the matched VCS scheme, or None if there's no match. - """ - from pip._internal.vcs import vcs - for scheme in vcs.schemes: - if url.lower().startswith(scheme) and url[len(scheme)] in '+:': - return scheme - return None - - -def _is_url_like_archive(url): - # type: (str) -> bool - """Return whether the URL looks like an archive. - """ - filename = Link(url).filename - for bad_ext in ARCHIVE_EXTENSIONS: - if filename.endswith(bad_ext): - return True - return False - - -class _NotHTML(Exception): - def __init__(self, content_type, request_desc): - # type: (str, str) -> None - super(_NotHTML, self).__init__(content_type, request_desc) - self.content_type = content_type - self.request_desc = request_desc - - -def _ensure_html_header(response): - # type: (Response) -> None - """Check the Content-Type header to ensure the response contains HTML. - - Raises `_NotHTML` if the content type is not text/html. - """ - content_type = response.headers.get("Content-Type", "") - if not content_type.lower().startswith("text/html"): - raise _NotHTML(content_type, response.request.method) - - -class _NotHTTP(Exception): - pass - - -def _ensure_html_response(url, session): - # type: (str, PipSession) -> None - """Send a HEAD request to the URL, and ensure the response contains HTML. - - Raises `_NotHTTP` if the URL is not available for a HEAD request, or - `_NotHTML` if the content type is not text/html. - """ - scheme, netloc, path, query, fragment = urllib_parse.urlsplit(url) - if scheme not in {'http', 'https'}: - raise _NotHTTP() - - resp = session.head(url, allow_redirects=True) - resp.raise_for_status() - - _ensure_html_header(resp) - - -def _get_html_response(url, session): - # type: (str, PipSession) -> Response - """Access an HTML page with GET, and return the response. - - This consists of three parts: - - 1. If the URL looks suspiciously like an archive, send a HEAD first to - check the Content-Type is HTML, to avoid downloading a large file. - Raise `_NotHTTP` if the content type cannot be determined, or - `_NotHTML` if it is not HTML. - 2. Actually perform the request. Raise HTTP exceptions on network failures. - 3. Check the Content-Type header to make sure we got HTML, and raise - `_NotHTML` otherwise. - """ - if _is_url_like_archive(url): - _ensure_html_response(url, session=session) - - logger.debug('Getting page %s', redact_password_from_url(url)) - - resp = session.get( - url, - headers={ - "Accept": "text/html", - # We don't want to blindly returned cached data for - # /simple/, because authors generally expecting that - # twine upload && pip install will function, but if - # they've done a pip install in the last ~10 minutes - # it won't. Thus by setting this to zero we will not - # blindly use any cached data, however the benefit of - # using max-age=0 instead of no-cache, is that we will - # still support conditional requests, so we will still - # minimize traffic sent in cases where the page hasn't - # changed at all, we will just always incur the round - # trip for the conditional GET now instead of only - # once per 10 minutes. - # For more information, please see pypa/pip#5670. - "Cache-Control": "max-age=0", - }, - ) - resp.raise_for_status() - - # The check for archives above only works if the url ends with - # something that looks like an archive. However that is not a - # requirement of an url. Unless we issue a HEAD request on every - # url we cannot know ahead of time for sure if something is HTML - # or not. However we can check after we've downloaded it. - _ensure_html_header(resp) - - return resp - - -def _handle_get_page_fail( - link, # type: Link - reason, # type: Union[str, Exception] - meth=None # type: Optional[Callable[..., None]] -): - # type: (...) -> None - if meth is None: - meth = logger.debug - meth("Could not fetch URL %s: %s - skipping", link, reason) - - -def _get_html_page(link, session=None): - # type: (Link, Optional[PipSession]) -> Optional[HTMLPage] - if session is None: - raise TypeError( - "_get_html_page() missing 1 required keyword argument: 'session'" - ) - - url = link.url.split('#', 1)[0] - - # Check for VCS schemes that do not support lookup as web pages. - vcs_scheme = _match_vcs_scheme(url) - if vcs_scheme: - logger.debug('Cannot look at %s URL %s', vcs_scheme, link) - return None - - # Tack index.html onto file:// URLs that point to directories - scheme, _, path, _, _, _ = urllib_parse.urlparse(url) - if (scheme == 'file' and os.path.isdir(urllib_request.url2pathname(path))): - # add trailing slash if not present so urljoin doesn't trim - # final segment - if not url.endswith('/'): - url += '/' - url = urllib_parse.urljoin(url, 'index.html') - logger.debug(' file: URL is directory, getting %s', url) - - try: - resp = _get_html_response(url, session=session) - except _NotHTTP: - logger.debug( - 'Skipping page %s because it looks like an archive, and cannot ' - 'be checked by HEAD.', link, - ) - except _NotHTML as exc: - logger.debug( - 'Skipping page %s because the %s request got Content-Type: %s', - link, exc.request_desc, exc.content_type, - ) - except HTTPError as exc: - _handle_get_page_fail(link, exc) - except RetryError as exc: - _handle_get_page_fail(link, exc) - except SSLError as exc: - reason = "There was a problem confirming the ssl certificate: " - reason += str(exc) - _handle_get_page_fail(link, reason, meth=logger.info) - except requests.ConnectionError as exc: - _handle_get_page_fail(link, "connection error: %s" % exc) - except requests.Timeout: - _handle_get_page_fail(link, "timed out") - else: - return HTMLPage(resp.content, resp.url, resp.headers) - return None - - -def _check_link_requires_python( - link, # type: Link - version_info, # type: Tuple[int, int, int] - ignore_requires_python=False, # type: bool -): - # type: (...) -> bool - """ - Return whether the given Python version is compatible with a link's - "Requires-Python" value. - - :param version_info: A 3-tuple of ints representing the Python - major-minor-micro version to check. - :param ignore_requires_python: Whether to ignore the "Requires-Python" - value if the given Python version isn't compatible. - """ - try: - is_compatible = check_requires_python( - link.requires_python, version_info=version_info, - ) - except specifiers.InvalidSpecifier: - logger.debug( - "Ignoring invalid Requires-Python (%r) for link: %s", - link.requires_python, link, - ) - else: - if not is_compatible: - version = '.'.join(map(str, version_info)) - if not ignore_requires_python: - logger.debug( - 'Link requires a different Python (%s not in: %r): %s', - version, link.requires_python, link, - ) - return False - - logger.debug( - 'Ignoring failed Requires-Python check (%s not in: %r) ' - 'for link: %s', - version, link.requires_python, link, - ) - - return True - - -class LinkEvaluator(object): - - """ - Responsible for evaluating links for a particular project. - """ - - _py_version_re = re.compile(r'-py([123]\.?[0-9]?)$') - - # Don't include an allow_yanked default value to make sure each call - # site considers whether yanked releases are allowed. This also causes - # that decision to be made explicit in the calling code, which helps - # people when reading the code. - def __init__( - self, - project_name, # type: str - canonical_name, # type: str - formats, # type: FrozenSet - target_python, # type: TargetPython - allow_yanked, # type: bool - ignore_requires_python=None, # type: Optional[bool] - ): - # type: (...) -> None - """ - :param project_name: The user supplied package name. - :param canonical_name: The canonical package name. - :param formats: The formats allowed for this package. Should be a set - with 'binary' or 'source' or both in it. - :param target_python: The target Python interpreter to use when - evaluating link compatibility. This is used, for example, to - check wheel compatibility, as well as when checking the Python - version, e.g. the Python version embedded in a link filename - (or egg fragment) and against an HTML link's optional PEP 503 - "data-requires-python" attribute. - :param allow_yanked: Whether files marked as yanked (in the sense - of PEP 592) are permitted to be candidates for install. - :param ignore_requires_python: Whether to ignore incompatible - PEP 503 "data-requires-python" values in HTML links. Defaults - to False. - """ - if ignore_requires_python is None: - ignore_requires_python = False - - self._allow_yanked = allow_yanked - self._canonical_name = canonical_name - self._ignore_requires_python = ignore_requires_python - self._formats = formats - self._target_python = target_python - - self.project_name = project_name - - def evaluate_link(self, link): - # type: (Link) -> Tuple[bool, Optional[Text]] - """ - Determine whether a link is a candidate for installation. - - :return: A tuple (is_candidate, result), where `result` is (1) a - version string if `is_candidate` is True, and (2) if - `is_candidate` is False, an optional string to log the reason - the link fails to qualify. - """ - version = None - if link.is_yanked and not self._allow_yanked: - reason = link.yanked_reason or '<none given>' - # Mark this as a unicode string to prevent "UnicodeEncodeError: - # 'ascii' codec can't encode character" in Python 2 when - # the reason contains non-ascii characters. - return (False, u'yanked for reason: {}'.format(reason)) - - if link.egg_fragment: - egg_info = link.egg_fragment - ext = link.ext - else: - egg_info, ext = link.splitext() - if not ext: - return (False, 'not a file') - if ext not in SUPPORTED_EXTENSIONS: - return (False, 'unsupported archive format: %s' % ext) - if "binary" not in self._formats and ext == WHEEL_EXTENSION: - reason = 'No binaries permitted for %s' % self.project_name - return (False, reason) - if "macosx10" in link.path and ext == '.zip': - return (False, 'macosx10 one') - if ext == WHEEL_EXTENSION: - try: - wheel = Wheel(link.filename) - except InvalidWheelFilename: - return (False, 'invalid wheel filename') - if canonicalize_name(wheel.name) != self._canonical_name: - reason = 'wrong project name (not %s)' % self.project_name - return (False, reason) - - supported_tags = self._target_python.get_tags() - if not wheel.supported(supported_tags): - # Include the wheel's tags in the reason string to - # simplify troubleshooting compatibility issues. - file_tags = wheel.get_formatted_file_tags() - reason = ( - "none of the wheel's tags match: {}".format( - ', '.join(file_tags) - ) - ) - return (False, reason) - - version = wheel.version - - # This should be up by the self.ok_binary check, but see issue 2700. - if "source" not in self._formats and ext != WHEEL_EXTENSION: - return (False, 'No sources permitted for %s' % self.project_name) - - if not version: - version = _extract_version_from_fragment( - egg_info, self._canonical_name, - ) - if not version: - return ( - False, 'Missing project version for %s' % self.project_name, - ) - - match = self._py_version_re.search(version) - if match: - version = version[:match.start()] - py_version = match.group(1) - if py_version != self._target_python.py_version: - return (False, 'Python version is incorrect') - - supports_python = _check_link_requires_python( - link, version_info=self._target_python.py_version_info, - ignore_requires_python=self._ignore_requires_python, - ) - if not supports_python: - # Return None for the reason text to suppress calling - # _log_skipped_link(). - return (False, None) - - logger.debug('Found link %s, version: %s', link, version) - - return (True, version) - - -def filter_unallowed_hashes( - candidates, # type: List[InstallationCandidate] - hashes, # type: Hashes - project_name, # type: str -): - # type: (...) -> List[InstallationCandidate] - """ - Filter out candidates whose hashes aren't allowed, and return a new - list of candidates. - - If at least one candidate has an allowed hash, then all candidates with - either an allowed hash or no hash specified are returned. Otherwise, - the given candidates are returned. - - Including the candidates with no hash specified when there is a match - allows a warning to be logged if there is a more preferred candidate - with no hash specified. Returning all candidates in the case of no - matches lets pip report the hash of the candidate that would otherwise - have been installed (e.g. permitting the user to more easily update - their requirements file with the desired hash). - """ - if not hashes: - logger.debug( - 'Given no hashes to check %s links for project %r: ' - 'discarding no candidates', - len(candidates), - project_name, - ) - # Make sure we're not returning back the given value. - return list(candidates) - - matches_or_no_digest = [] - # Collect the non-matches for logging purposes. - non_matches = [] - match_count = 0 - for candidate in candidates: - link = candidate.link - if not link.has_hash: - pass - elif link.is_hash_allowed(hashes=hashes): - match_count += 1 - else: - non_matches.append(candidate) - continue - - matches_or_no_digest.append(candidate) - - if match_count: - filtered = matches_or_no_digest - else: - # Make sure we're not returning back the given value. - filtered = list(candidates) - - if len(filtered) == len(candidates): - discard_message = 'discarding no candidates' - else: - discard_message = 'discarding {} non-matches:\n {}'.format( - len(non_matches), - '\n '.join(str(candidate.link) for candidate in non_matches) - ) - - logger.debug( - 'Checked %s links for project %r against %s hashes ' - '(%s matches, %s no digest): %s', - len(candidates), - project_name, - hashes.digest_count, - match_count, - len(matches_or_no_digest) - match_count, - discard_message - ) - - return filtered - - -class CandidatePreferences(object): - - """ - Encapsulates some of the preferences for filtering and sorting - InstallationCandidate objects. - """ - - def __init__( - self, - prefer_binary=False, # type: bool - allow_all_prereleases=False, # type: bool - ): - # type: (...) -> None - """ - :param allow_all_prereleases: Whether to allow all pre-releases. - """ - self.allow_all_prereleases = allow_all_prereleases - self.prefer_binary = prefer_binary - - -class CandidateEvaluator(object): - - """ - Responsible for filtering and sorting candidates for installation based - on what tags are valid. - """ - - @classmethod - def create( - cls, - project_name, # type: str - target_python=None, # type: Optional[TargetPython] - prefer_binary=False, # type: bool - allow_all_prereleases=False, # type: bool - specifier=None, # type: Optional[specifiers.BaseSpecifier] - hashes=None, # type: Optional[Hashes] - ): - # type: (...) -> CandidateEvaluator - """Create a CandidateEvaluator object. - - :param target_python: The target Python interpreter to use when - checking compatibility. If None (the default), a TargetPython - object will be constructed from the running Python. - :param hashes: An optional collection of allowed hashes. - """ - if target_python is None: - target_python = TargetPython() - if specifier is None: - specifier = specifiers.SpecifierSet() - - supported_tags = target_python.get_tags() - - return cls( - project_name=project_name, - supported_tags=supported_tags, - specifier=specifier, - prefer_binary=prefer_binary, - allow_all_prereleases=allow_all_prereleases, - hashes=hashes, - ) - - def __init__( - self, - project_name, # type: str - supported_tags, # type: List[Pep425Tag] - specifier, # type: specifiers.BaseSpecifier - prefer_binary=False, # type: bool - allow_all_prereleases=False, # type: bool - hashes=None, # type: Optional[Hashes] - ): - # type: (...) -> None - """ - :param supported_tags: The PEP 425 tags supported by the target - Python in order of preference (most preferred first). - """ - self._allow_all_prereleases = allow_all_prereleases - self._hashes = hashes - self._prefer_binary = prefer_binary - self._project_name = project_name - self._specifier = specifier - self._supported_tags = supported_tags - - def get_applicable_candidates( - self, - candidates, # type: List[InstallationCandidate] - ): - # type: (...) -> List[InstallationCandidate] - """ - Return the applicable candidates from a list of candidates. - """ - # Using None infers from the specifier instead. - allow_prereleases = self._allow_all_prereleases or None - specifier = self._specifier - versions = { - str(v) for v in specifier.filter( - # We turn the version object into a str here because otherwise - # when we're debundled but setuptools isn't, Python will see - # packaging.version.Version and - # pkg_resources._vendor.packaging.version.Version as different - # types. This way we'll use a str as a common data interchange - # format. If we stop using the pkg_resources provided specifier - # and start using our own, we can drop the cast to str(). - (str(c.version) for c in candidates), - prereleases=allow_prereleases, - ) - } - - # Again, converting version to str to deal with debundling. - applicable_candidates = [ - c for c in candidates if str(c.version) in versions - ] - - return filter_unallowed_hashes( - candidates=applicable_candidates, - hashes=self._hashes, - project_name=self._project_name, - ) - - def make_found_candidates( - self, - candidates, # type: List[InstallationCandidate] - ): - # type: (...) -> FoundCandidates - """ - Create and return a `FoundCandidates` instance. - - :param specifier: An optional object implementing `filter` - (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable - versions. - """ - applicable_candidates = self.get_applicable_candidates(candidates) - - return FoundCandidates( - candidates, - applicable_candidates=applicable_candidates, - evaluator=self, - ) - - def _sort_key(self, candidate): - # type: (InstallationCandidate) -> CandidateSortingKey - """ - Function to pass as the `key` argument to a call to sorted() to sort - InstallationCandidates by preference. - - Returns a tuple such that tuples sorting as greater using Python's - default comparison operator are more preferred. - - The preference is as follows: - - First and foremost, candidates with allowed (matching) hashes are - always preferred over candidates without matching hashes. This is - because e.g. if the only candidate with an allowed hash is yanked, - we still want to use that candidate. - - Second, excepting hash considerations, candidates that have been - yanked (in the sense of PEP 592) are always less preferred than - candidates that haven't been yanked. Then: - - If not finding wheels, they are sorted by version only. - If finding wheels, then the sort order is by version, then: - 1. existing installs - 2. wheels ordered via Wheel.support_index_min(self._supported_tags) - 3. source archives - If prefer_binary was set, then all wheels are sorted above sources. - - Note: it was considered to embed this logic into the Link - comparison operators, but then different sdist links - with the same version, would have to be considered equal - """ - valid_tags = self._supported_tags - support_num = len(valid_tags) - build_tag = tuple() # type: BuildTag - binary_preference = 0 - link = candidate.link - if link.is_wheel: - # can raise InvalidWheelFilename - wheel = Wheel(link.filename) - if not wheel.supported(valid_tags): - raise UnsupportedWheel( - "%s is not a supported wheel for this platform. It " - "can't be sorted." % wheel.filename - ) - if self._prefer_binary: - binary_preference = 1 - pri = -(wheel.support_index_min(valid_tags)) - if wheel.build_tag is not None: - match = re.match(r'^(\d+)(.*)$', wheel.build_tag) - build_tag_groups = match.groups() - build_tag = (int(build_tag_groups[0]), build_tag_groups[1]) - else: # sdist - pri = -(support_num) - has_allowed_hash = int(link.is_hash_allowed(self._hashes)) - yank_value = -1 * int(link.is_yanked) # -1 for yanked. - return ( - has_allowed_hash, yank_value, binary_preference, candidate.version, - build_tag, pri, - ) - - def get_best_candidate( - self, - candidates, # type: List[InstallationCandidate] - ): - # type: (...) -> Optional[InstallationCandidate] - """ - Return the best candidate per the instance's sort order, or None if - no candidate is acceptable. - """ - if not candidates: - return None - - best_candidate = max(candidates, key=self._sort_key) - - # Log a warning per PEP 592 if necessary before returning. - link = best_candidate.link - if link.is_yanked: - reason = link.yanked_reason or '<none given>' - msg = ( - # Mark this as a unicode string to prevent - # "UnicodeEncodeError: 'ascii' codec can't encode character" - # in Python 2 when the reason contains non-ascii characters. - u'The candidate selected for download or install is a ' - 'yanked version: {candidate}\n' - 'Reason for being yanked: {reason}' - ).format(candidate=best_candidate, reason=reason) - logger.warning(msg) - - return best_candidate - - -class FoundCandidates(object): - """A collection of candidates, returned by `PackageFinder.find_candidates`. - - This class is only intended to be instantiated by CandidateEvaluator's - `make_found_candidates()` method. - """ - - def __init__( - self, - candidates, # type: List[InstallationCandidate] - applicable_candidates, # type: List[InstallationCandidate] - evaluator, # type: CandidateEvaluator - ): - # type: (...) -> None - """ - :param candidates: A sequence of all available candidates found. - :param applicable_candidates: The applicable candidates. - :param evaluator: A CandidateEvaluator object to sort applicable - candidates by order of preference. - """ - self._applicable_candidates = applicable_candidates - self._candidates = candidates - self._evaluator = evaluator - - def iter_all(self): - # type: () -> Iterable[InstallationCandidate] - """Iterate through all candidates. - """ - return iter(self._candidates) - - def iter_applicable(self): - # type: () -> Iterable[InstallationCandidate] - """Iterate through the applicable candidates. - """ - return iter(self._applicable_candidates) - - def get_best(self): - # type: () -> Optional[InstallationCandidate] - """Return the best candidate available, or None if no applicable - candidates are found. - """ - candidates = list(self.iter_applicable()) - return self._evaluator.get_best_candidate(candidates) - - -class PackageFinder(object): - """This finds packages. - - This is meant to match easy_install's technique for looking for - packages, by reading pages and looking for appropriate links. - """ - - def __init__( - self, - search_scope, # type: SearchScope - session, # type: PipSession - target_python, # type: TargetPython - allow_yanked, # type: bool - format_control=None, # type: Optional[FormatControl] - trusted_hosts=None, # type: Optional[List[str]] - candidate_prefs=None, # type: CandidatePreferences - ignore_requires_python=None, # type: Optional[bool] - ): - # type: (...) -> None - """ - This constructor is primarily meant to be used by the create() class - method and from tests. - - :param session: The Session to use to make requests. - :param format_control: A FormatControl object, used to control - the selection of source packages / binary packages when consulting - the index and links. - :param candidate_prefs: Options to use when creating a - CandidateEvaluator object. - """ - if trusted_hosts is None: - trusted_hosts = [] - if candidate_prefs is None: - candidate_prefs = CandidatePreferences() - - format_control = format_control or FormatControl(set(), set()) - - self._allow_yanked = allow_yanked - self._candidate_prefs = candidate_prefs - self._ignore_requires_python = ignore_requires_python - self._target_python = target_python - - self.search_scope = search_scope - self.session = session - self.format_control = format_control - self.trusted_hosts = trusted_hosts - - # These are boring links that have already been logged somehow. - self._logged_links = set() # type: Set[Link] - - # Don't include an allow_yanked default value to make sure each call - # site considers whether yanked releases are allowed. This also causes - # that decision to be made explicit in the calling code, which helps - # people when reading the code. - @classmethod - def create( - cls, - search_scope, # type: SearchScope - selection_prefs, # type: SelectionPreferences - trusted_hosts=None, # type: Optional[List[str]] - session=None, # type: Optional[PipSession] - target_python=None, # type: Optional[TargetPython] - ): - # type: (...) -> PackageFinder - """Create a PackageFinder. - - :param selection_prefs: The candidate selection preferences, as a - SelectionPreferences object. - :param trusted_hosts: Domains not to emit warnings for when not using - HTTPS. - :param session: The Session to use to make requests. - :param target_python: The target Python interpreter to use when - checking compatibility. If None (the default), a TargetPython - object will be constructed from the running Python. - """ - if session is None: - raise TypeError( - "PackageFinder.create() missing 1 required keyword argument: " - "'session'" - ) - if target_python is None: - target_python = TargetPython() - - candidate_prefs = CandidatePreferences( - prefer_binary=selection_prefs.prefer_binary, - allow_all_prereleases=selection_prefs.allow_all_prereleases, - ) - - return cls( - candidate_prefs=candidate_prefs, - search_scope=search_scope, - session=session, - target_python=target_python, - allow_yanked=selection_prefs.allow_yanked, - format_control=selection_prefs.format_control, - trusted_hosts=trusted_hosts, - ignore_requires_python=selection_prefs.ignore_requires_python, - ) - - @property - def find_links(self): - # type: () -> List[str] - return self.search_scope.find_links - - @property - def index_urls(self): - # type: () -> List[str] - return self.search_scope.index_urls - - @property - def allow_all_prereleases(self): - # type: () -> bool - return self._candidate_prefs.allow_all_prereleases - - def set_allow_all_prereleases(self): - # type: () -> None - self._candidate_prefs.allow_all_prereleases = True - - def add_trusted_host(self, host, source=None): - # type: (str, Optional[str]) -> None - """ - :param source: An optional source string, for logging where the host - string came from. - """ - # It is okay to add a previously added host because PipSession stores - # the resulting prefixes in a dict. - msg = 'adding trusted host: {!r}'.format(host) - if source is not None: - msg += ' (from {})'.format(source) - logger.info(msg) - self.session.add_insecure_host(host) - if host in self.trusted_hosts: - return - - self.trusted_hosts.append(host) - - def iter_secure_origins(self): - # type: () -> Iterator[SecureOrigin] - for secure_origin in SECURE_ORIGINS: - yield secure_origin - for host in self.trusted_hosts: - yield ('*', host, '*') - - @staticmethod - def _sort_locations(locations, expand_dir=False): - # type: (Sequence[str], bool) -> Tuple[List[str], List[str]] - """ - Sort locations into "files" (archives) and "urls", and return - a pair of lists (files,urls) - """ - files = [] - urls = [] - - # puts the url for the given file path into the appropriate list - def sort_path(path): - url = path_to_url(path) - if mimetypes.guess_type(url, strict=False)[0] == 'text/html': - urls.append(url) - else: - files.append(url) - - for url in locations: - - is_local_path = os.path.exists(url) - is_file_url = url.startswith('file:') - - if is_local_path or is_file_url: - if is_local_path: - path = url - else: - path = url_to_path(url) - if os.path.isdir(path): - if expand_dir: - path = os.path.realpath(path) - for item in os.listdir(path): - sort_path(os.path.join(path, item)) - elif is_file_url: - urls.append(url) - else: - logger.warning( - "Path '{0}' is ignored: " - "it is a directory.".format(path), - ) - elif os.path.isfile(path): - sort_path(path) - else: - logger.warning( - "Url '%s' is ignored: it is neither a file " - "nor a directory.", url, - ) - elif is_url(url): - # Only add url with clear scheme - urls.append(url) - else: - logger.warning( - "Url '%s' is ignored. It is either a non-existing " - "path or lacks a specific scheme.", url, - ) - - return files, urls - - def _validate_secure_origin(self, logger, location): - # type: (Logger, Link) -> bool - # Determine if this url used a secure transport mechanism - parsed = urllib_parse.urlparse(str(location)) - origin = (parsed.scheme, parsed.hostname, parsed.port) - - # The protocol to use to see if the protocol matches. - # Don't count the repository type as part of the protocol: in - # cases such as "git+ssh", only use "ssh". (I.e., Only verify against - # the last scheme.) - protocol = origin[0].rsplit('+', 1)[-1] - - # Determine if our origin is a secure origin by looking through our - # hardcoded list of secure origins, as well as any additional ones - # configured on this PackageFinder instance. - for secure_origin in self.iter_secure_origins(): - if protocol != secure_origin[0] and secure_origin[0] != "*": - continue - - try: - # We need to do this decode dance to ensure that we have a - # unicode object, even on Python 2.x. - addr = ipaddress.ip_address( - origin[1] - if ( - isinstance(origin[1], six.text_type) or - origin[1] is None - ) - else origin[1].decode("utf8") - ) - network = ipaddress.ip_network( - secure_origin[1] - if isinstance(secure_origin[1], six.text_type) - # setting secure_origin[1] to proper Union[bytes, str] - # creates problems in other places - else secure_origin[1].decode("utf8") # type: ignore - ) - except ValueError: - # We don't have both a valid address or a valid network, so - # we'll check this origin against hostnames. - if (origin[1] and - origin[1].lower() != secure_origin[1].lower() and - secure_origin[1] != "*"): - continue - else: - # We have a valid address and network, so see if the address - # is contained within the network. - if addr not in network: - continue - - # Check to see if the port patches - if (origin[2] != secure_origin[2] and - secure_origin[2] != "*" and - secure_origin[2] is not None): - continue - - # If we've gotten here, then this origin matches the current - # secure origin and we should return True - return True - - # If we've gotten to this point, then the origin isn't secure and we - # will not accept it as a valid location to search. We will however - # log a warning that we are ignoring it. - logger.warning( - "The repository located at %s is not a trusted or secure host and " - "is being ignored. If this repository is available via HTTPS we " - "recommend you use HTTPS instead, otherwise you may silence " - "this warning and allow it anyway with '--trusted-host %s'.", - parsed.hostname, - parsed.hostname, - ) - - return False - - def make_link_evaluator(self, project_name): - # type: (str) -> LinkEvaluator - canonical_name = canonicalize_name(project_name) - formats = self.format_control.get_allowed_formats(canonical_name) - - return LinkEvaluator( - project_name=project_name, - canonical_name=canonical_name, - formats=formats, - target_python=self._target_python, - allow_yanked=self._allow_yanked, - ignore_requires_python=self._ignore_requires_python, - ) - - def find_all_candidates(self, project_name): - # type: (str) -> List[InstallationCandidate] - """Find all available InstallationCandidate for project_name - - This checks index_urls and find_links. - All versions found are returned as an InstallationCandidate list. - - See LinkEvaluator.evaluate_link() for details on which files - are accepted. - """ - search_scope = self.search_scope - index_locations = search_scope.get_index_urls_locations(project_name) - index_file_loc, index_url_loc = self._sort_locations(index_locations) - fl_file_loc, fl_url_loc = self._sort_locations( - self.find_links, expand_dir=True, - ) - - file_locations = (Link(url) for url in itertools.chain( - index_file_loc, fl_file_loc, - )) - - # We trust every url that the user has given us whether it was given - # via --index-url or --find-links. - # We want to filter out any thing which does not have a secure origin. - url_locations = [ - link for link in itertools.chain( - (Link(url) for url in index_url_loc), - (Link(url) for url in fl_url_loc), - ) - if self._validate_secure_origin(logger, link) - ] - - logger.debug('%d location(s) to search for versions of %s:', - len(url_locations), project_name) - - for location in url_locations: - logger.debug('* %s', location) - - link_evaluator = self.make_link_evaluator(project_name) - find_links_versions = self._package_versions( - link_evaluator, - # We trust every directly linked archive in find_links - (Link(url, '-f') for url in self.find_links), - ) - - page_versions = [] - for page in self._get_pages(url_locations, project_name): - logger.debug('Analyzing links from page %s', page.url) - with indent_log(): - page_versions.extend( - self._package_versions(link_evaluator, page.iter_links()) - ) - - file_versions = self._package_versions(link_evaluator, file_locations) - if file_versions: - file_versions.sort(reverse=True) - logger.debug( - 'Local files found: %s', - ', '.join([ - url_to_path(candidate.link.url) - for candidate in file_versions - ]) - ) - - # This is an intentional priority ordering - return file_versions + find_links_versions + page_versions - - def make_candidate_evaluator( - self, - project_name, # type: str - specifier=None, # type: Optional[specifiers.BaseSpecifier] - hashes=None, # type: Optional[Hashes] - ): - # type: (...) -> CandidateEvaluator - """Create a CandidateEvaluator object to use. - """ - candidate_prefs = self._candidate_prefs - return CandidateEvaluator.create( - project_name=project_name, - target_python=self._target_python, - prefer_binary=candidate_prefs.prefer_binary, - allow_all_prereleases=candidate_prefs.allow_all_prereleases, - specifier=specifier, - hashes=hashes, - ) - - def find_candidates( - self, - project_name, # type: str - specifier=None, # type: Optional[specifiers.BaseSpecifier] - hashes=None, # type: Optional[Hashes] - ): - # type: (...) -> FoundCandidates - """Find matches for the given project and specifier. - - :param specifier: An optional object implementing `filter` - (e.g. `packaging.specifiers.SpecifierSet`) to filter applicable - versions. - - :return: A `FoundCandidates` instance. - """ - candidates = self.find_all_candidates(project_name) - candidate_evaluator = self.make_candidate_evaluator( - project_name=project_name, - specifier=specifier, - hashes=hashes, - ) - return candidate_evaluator.make_found_candidates(candidates) - - def find_requirement(self, req, upgrade): - # type: (InstallRequirement, bool) -> Optional[Link] - """Try to find a Link matching req - - Expects req, an InstallRequirement and upgrade, a boolean - Returns a Link if found, - Raises DistributionNotFound or BestVersionAlreadyInstalled otherwise - """ - hashes = req.hashes(trust_internet=False) - candidates = self.find_candidates( - req.name, specifier=req.specifier, hashes=hashes, - ) - best_candidate = candidates.get_best() - - installed_version = None # type: Optional[_BaseVersion] - if req.satisfied_by is not None: - installed_version = parse_version(req.satisfied_by.version) - - def _format_versions(cand_iter): - # This repeated parse_version and str() conversion is needed to - # handle different vendoring sources from pip and pkg_resources. - # If we stop using the pkg_resources provided specifier and start - # using our own, we can drop the cast to str(). - return ", ".join(sorted( - {str(c.version) for c in cand_iter}, - key=parse_version, - )) or "none" - - if installed_version is None and best_candidate is None: - logger.critical( - 'Could not find a version that satisfies the requirement %s ' - '(from versions: %s)', - req, - _format_versions(candidates.iter_all()), - ) - - raise DistributionNotFound( - 'No matching distribution found for %s' % req - ) - - best_installed = False - if installed_version and ( - best_candidate is None or - best_candidate.version <= installed_version): - best_installed = True - - if not upgrade and installed_version is not None: - if best_installed: - logger.debug( - 'Existing installed version (%s) is most up-to-date and ' - 'satisfies requirement', - installed_version, - ) - else: - logger.debug( - 'Existing installed version (%s) satisfies requirement ' - '(most up-to-date version is %s)', - installed_version, - best_candidate.version, - ) - return None - - if best_installed: - # We have an existing version, and its the best version - logger.debug( - 'Installed version (%s) is most up-to-date (past versions: ' - '%s)', - installed_version, - _format_versions(candidates.iter_applicable()), - ) - raise BestVersionAlreadyInstalled - - logger.debug( - 'Using version %s (newest of versions: %s)', - best_candidate.version, - _format_versions(candidates.iter_applicable()), - ) - return best_candidate.link - - def _get_pages(self, locations, project_name): - # type: (Iterable[Link], str) -> Iterable[HTMLPage] - """ - Yields (page, page_url) from the given locations, skipping - locations that have errors. - """ - seen = set() # type: Set[Link] - for location in locations: - if location in seen: - continue - seen.add(location) - - page = _get_html_page(location, session=self.session) - if page is None: - continue - - yield page - - def _sort_links(self, links): - # type: (Iterable[Link]) -> List[Link] - """ - Returns elements of links in order, non-egg links first, egg links - second, while eliminating duplicates - """ - eggs, no_eggs = [], [] - seen = set() # type: Set[Link] - for link in links: - if link not in seen: - seen.add(link) - if link.egg_fragment: - eggs.append(link) - else: - no_eggs.append(link) - return no_eggs + eggs - - def _log_skipped_link(self, link, reason): - # type: (Link, Text) -> None - if link not in self._logged_links: - # Mark this as a unicode string to prevent "UnicodeEncodeError: - # 'ascii' codec can't encode character" in Python 2 when - # the reason contains non-ascii characters. - # Also, put the link at the end so the reason is more visible - # and because the link string is usually very long. - logger.debug(u'Skipping link: %s: %s', reason, link) - self._logged_links.add(link) - - def get_install_candidate(self, link_evaluator, link): - # type: (LinkEvaluator, Link) -> Optional[InstallationCandidate] - """ - If the link is a candidate for install, convert it to an - InstallationCandidate and return it. Otherwise, return None. - """ - is_candidate, result = link_evaluator.evaluate_link(link) - if not is_candidate: - if result: - self._log_skipped_link(link, reason=result) - return None - - return InstallationCandidate( - project=link_evaluator.project_name, - link=link, - # Convert the Text result to str since InstallationCandidate - # accepts str. - version=str(result), - ) - - def _package_versions(self, link_evaluator, links): - # type: (LinkEvaluator, Iterable[Link]) -> List[InstallationCandidate] - result = [] - for link in self._sort_links(links): - candidate = self.get_install_candidate(link_evaluator, link) - if candidate is not None: - result.append(candidate) - return result - - -def _find_name_version_sep(fragment, canonical_name): - # type: (str, str) -> int - """Find the separator's index based on the package's canonical name. - - :param fragment: A <package>+<version> filename "fragment" (stem) or - egg fragment. - :param canonical_name: The package's canonical name. - - This function is needed since the canonicalized name does not necessarily - have the same length as the egg info's name part. An example:: - - >>> fragment = 'foo__bar-1.0' - >>> canonical_name = 'foo-bar' - >>> _find_name_version_sep(fragment, canonical_name) - 8 - """ - # Project name and version must be separated by one single dash. Find all - # occurrences of dashes; if the string in front of it matches the canonical - # name, this is the one separating the name and version parts. - for i, c in enumerate(fragment): - if c != "-": - continue - if canonicalize_name(fragment[:i]) == canonical_name: - return i - raise ValueError("{} does not match {}".format(fragment, canonical_name)) - - -def _extract_version_from_fragment(fragment, canonical_name): - # type: (str, str) -> Optional[str] - """Parse the version string from a <package>+<version> filename - "fragment" (stem) or egg fragment. - - :param fragment: The string to parse. E.g. foo-2.1 - :param canonical_name: The canonicalized name of the package this - belongs to. - """ - try: - version_start = _find_name_version_sep(fragment, canonical_name) + 1 - except ValueError: - return None - version = fragment[version_start:] - if not version: - return None - return version - - -def _determine_base_url(document, page_url): - """Determine the HTML document's base URL. - - This looks for a ``<base>`` tag in the HTML document. If present, its href - attribute denotes the base URL of anchor tags in the document. If there is - no such tag (or if it does not have a valid href attribute), the HTML - file's URL is used as the base URL. - - :param document: An HTML document representation. The current - implementation expects the result of ``html5lib.parse()``. - :param page_url: The URL of the HTML document. - """ - for base in document.findall(".//base"): - href = base.get("href") - if href is not None: - return href - return page_url - - -def _get_encoding_from_headers(headers): - """Determine if we have any encoding information in our headers. - """ - if headers and "Content-Type" in headers: - content_type, params = cgi.parse_header(headers["Content-Type"]) - if "charset" in params: - return params['charset'] - return None - - -def _clean_link(url): - # type: (str) -> str - """Makes sure a link is fully encoded. That is, if a ' ' shows up in - the link, it will be rewritten to %20 (while not over-quoting - % or other characters).""" - # Split the URL into parts according to the general structure - # `scheme://netloc/path;parameters?query#fragment`. Note that the - # `netloc` can be empty and the URI will then refer to a local - # filesystem path. - result = urllib_parse.urlparse(url) - # In both cases below we unquote prior to quoting to make sure - # nothing is double quoted. - if result.netloc == "": - # On Windows the path part might contain a drive letter which - # should not be quoted. On Linux where drive letters do not - # exist, the colon should be quoted. We rely on urllib.request - # to do the right thing here. - path = urllib_request.pathname2url( - urllib_request.url2pathname(result.path)) - else: - # In addition to the `/` character we protect `@` so that - # revision strings in VCS URLs are properly parsed. - path = urllib_parse.quote(urllib_parse.unquote(result.path), safe="/@") - return urllib_parse.urlunparse(result._replace(path=path)) - - -def _create_link_from_element( - anchor, # type: HTMLElement - page_url, # type: str - base_url, # type: str -): - # type: (...) -> Optional[Link] - """ - Convert an anchor element in a simple repository page to a Link. - """ - href = anchor.get("href") - if not href: - return None - - url = _clean_link(urllib_parse.urljoin(base_url, href)) - pyrequire = anchor.get('data-requires-python') - pyrequire = unescape(pyrequire) if pyrequire else None - - yanked_reason = anchor.get('data-yanked') - if yanked_reason: - # This is a unicode string in Python 2 (and 3). - yanked_reason = unescape(yanked_reason) - - link = Link( - url, - comes_from=page_url, - requires_python=pyrequire, - yanked_reason=yanked_reason, - ) - - return link - - -class HTMLPage(object): - """Represents one page, along with its URL""" - - def __init__(self, content, url, headers=None): - # type: (bytes, str, MutableMapping[str, str]) -> None - self.content = content - self.url = url - self.headers = headers - - def __str__(self): - return redact_password_from_url(self.url) - - def iter_links(self): - # type: () -> Iterable[Link] - """Yields all links in the page""" - document = html5lib.parse( - self.content, - transport_encoding=_get_encoding_from_headers(self.headers), - namespaceHTMLElements=False, - ) - base_url = _determine_base_url(document, self.url) - for anchor in document.findall(".//a"): - link = _create_link_from_element( - anchor, - page_url=self.url, - base_url=base_url, - ) - if link is None: - continue - yield link diff --git a/venv/lib/python3.8/site-packages/pip/_internal/legacy_resolve.py b/venv/lib/python3.8/site-packages/pip/_internal/legacy_resolve.py deleted file mode 100644 index 1d9229c..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/legacy_resolve.py +++ /dev/null @@ -1,457 +0,0 @@ -"""Dependency Resolution - -The dependency resolution in pip is performed as follows: - -for top-level requirements: - a. only one spec allowed per project, regardless of conflicts or not. - otherwise a "double requirement" exception is raised - b. they override sub-dependency requirements. -for sub-dependencies - a. "first found, wins" (where the order is breadth first) -""" - -import logging -import sys -from collections import defaultdict -from itertools import chain - -from pip._vendor.packaging import specifiers - -from pip._internal.exceptions import ( - BestVersionAlreadyInstalled, DistributionNotFound, HashError, HashErrors, - UnsupportedPythonVersion, -) -from pip._internal.req.constructors import install_req_from_req_string -from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import ( - dist_in_usersite, ensure_dir, normalize_version_info, -) -from pip._internal.utils.packaging import ( - check_requires_python, get_requires_python, -) -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import DefaultDict, List, Optional, Set, Tuple - from pip._vendor import pkg_resources - - from pip._internal.cache import WheelCache - from pip._internal.distributions import AbstractDistribution - from pip._internal.download import PipSession - from pip._internal.index import PackageFinder - from pip._internal.operations.prepare import RequirementPreparer - from pip._internal.req.req_install import InstallRequirement - from pip._internal.req.req_set import RequirementSet - -logger = logging.getLogger(__name__) - - -def _check_dist_requires_python( - dist, # type: pkg_resources.Distribution - version_info, # type: Tuple[int, int, int] - ignore_requires_python=False, # type: bool -): - # type: (...) -> None - """ - Check whether the given Python version is compatible with a distribution's - "Requires-Python" value. - - :param version_info: A 3-tuple of ints representing the Python - major-minor-micro version to check. - :param ignore_requires_python: Whether to ignore the "Requires-Python" - value if the given Python version isn't compatible. - - :raises UnsupportedPythonVersion: When the given Python version isn't - compatible. - """ - requires_python = get_requires_python(dist) - try: - is_compatible = check_requires_python( - requires_python, version_info=version_info, - ) - except specifiers.InvalidSpecifier as exc: - logger.warning( - "Package %r has an invalid Requires-Python: %s", - dist.project_name, exc, - ) - return - - if is_compatible: - return - - version = '.'.join(map(str, version_info)) - if ignore_requires_python: - logger.debug( - 'Ignoring failed Requires-Python check for package %r: ' - '%s not in %r', - dist.project_name, version, requires_python, - ) - return - - raise UnsupportedPythonVersion( - 'Package {!r} requires a different Python: {} not in {!r}'.format( - dist.project_name, version, requires_python, - )) - - -class Resolver(object): - """Resolves which packages need to be installed/uninstalled to perform \ - the requested operation without breaking the requirements of any package. - """ - - _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} - - def __init__( - self, - preparer, # type: RequirementPreparer - session, # type: PipSession - finder, # type: PackageFinder - wheel_cache, # type: Optional[WheelCache] - use_user_site, # type: bool - ignore_dependencies, # type: bool - ignore_installed, # type: bool - ignore_requires_python, # type: bool - force_reinstall, # type: bool - isolated, # type: bool - upgrade_strategy, # type: str - use_pep517=None, # type: Optional[bool] - py_version_info=None, # type: Optional[Tuple[int, ...]] - ): - # type: (...) -> None - super(Resolver, self).__init__() - assert upgrade_strategy in self._allowed_strategies - - if py_version_info is None: - py_version_info = sys.version_info[:3] - else: - py_version_info = normalize_version_info(py_version_info) - - self._py_version_info = py_version_info - - self.preparer = preparer - self.finder = finder - self.session = session - - # NOTE: This would eventually be replaced with a cache that can give - # information about both sdist and wheels transparently. - self.wheel_cache = wheel_cache - - # This is set in resolve - self.require_hashes = None # type: Optional[bool] - - self.upgrade_strategy = upgrade_strategy - self.force_reinstall = force_reinstall - self.isolated = isolated - self.ignore_dependencies = ignore_dependencies - self.ignore_installed = ignore_installed - self.ignore_requires_python = ignore_requires_python - self.use_user_site = use_user_site - self.use_pep517 = use_pep517 - - self._discovered_dependencies = \ - defaultdict(list) # type: DefaultDict[str, List] - - def resolve(self, requirement_set): - # type: (RequirementSet) -> None - """Resolve what operations need to be done - - As a side-effect of this method, the packages (and their dependencies) - are downloaded, unpacked and prepared for installation. This - preparation is done by ``pip.operations.prepare``. - - Once PyPI has static dependency metadata available, it would be - possible to move the preparation to become a step separated from - dependency resolution. - """ - # make the wheelhouse - if self.preparer.wheel_download_dir: - ensure_dir(self.preparer.wheel_download_dir) - - # If any top-level requirement has a hash specified, enter - # hash-checking mode, which requires hashes from all. - root_reqs = ( - requirement_set.unnamed_requirements + - list(requirement_set.requirements.values()) - ) - self.require_hashes = ( - requirement_set.require_hashes or - any(req.has_hash_options for req in root_reqs) - ) - - # Display where finder is looking for packages - search_scope = self.finder.search_scope - locations = search_scope.get_formatted_locations() - if locations: - logger.info(locations) - - # Actually prepare the files, and collect any exceptions. Most hash - # exceptions cannot be checked ahead of time, because - # req.populate_link() needs to be called before we can make decisions - # based on link type. - discovered_reqs = [] # type: List[InstallRequirement] - hash_errors = HashErrors() - for req in chain(root_reqs, discovered_reqs): - try: - discovered_reqs.extend( - self._resolve_one(requirement_set, req) - ) - except HashError as exc: - exc.req = req - hash_errors.append(exc) - - if hash_errors: - raise hash_errors - - def _is_upgrade_allowed(self, req): - # type: (InstallRequirement) -> bool - if self.upgrade_strategy == "to-satisfy-only": - return False - elif self.upgrade_strategy == "eager": - return True - else: - assert self.upgrade_strategy == "only-if-needed" - return req.is_direct - - def _set_req_to_reinstall(self, req): - # type: (InstallRequirement) -> None - """ - Set a requirement to be installed. - """ - # Don't uninstall the conflict if doing a user install and the - # conflict is not a user install. - if not self.use_user_site or dist_in_usersite(req.satisfied_by): - req.conflicts_with = req.satisfied_by - req.satisfied_by = None - - # XXX: Stop passing requirement_set for options - def _check_skip_installed(self, req_to_install): - # type: (InstallRequirement) -> Optional[str] - """Check if req_to_install should be skipped. - - This will check if the req is installed, and whether we should upgrade - or reinstall it, taking into account all the relevant user options. - - After calling this req_to_install will only have satisfied_by set to - None if the req_to_install is to be upgraded/reinstalled etc. Any - other value will be a dist recording the current thing installed that - satisfies the requirement. - - Note that for vcs urls and the like we can't assess skipping in this - routine - we simply identify that we need to pull the thing down, - then later on it is pulled down and introspected to assess upgrade/ - reinstalls etc. - - :return: A text reason for why it was skipped, or None. - """ - if self.ignore_installed: - return None - - req_to_install.check_if_exists(self.use_user_site) - if not req_to_install.satisfied_by: - return None - - if self.force_reinstall: - self._set_req_to_reinstall(req_to_install) - return None - - if not self._is_upgrade_allowed(req_to_install): - if self.upgrade_strategy == "only-if-needed": - return 'already satisfied, skipping upgrade' - return 'already satisfied' - - # Check for the possibility of an upgrade. For link-based - # requirements we have to pull the tree down and inspect to assess - # the version #, so it's handled way down. - if not req_to_install.link: - try: - self.finder.find_requirement(req_to_install, upgrade=True) - except BestVersionAlreadyInstalled: - # Then the best version is installed. - return 'already up-to-date' - except DistributionNotFound: - # No distribution found, so we squash the error. It will - # be raised later when we re-try later to do the install. - # Why don't we just raise here? - pass - - self._set_req_to_reinstall(req_to_install) - return None - - def _get_abstract_dist_for(self, req): - # type: (InstallRequirement) -> AbstractDistribution - """Takes a InstallRequirement and returns a single AbstractDist \ - representing a prepared variant of the same. - """ - assert self.require_hashes is not None, ( - "require_hashes should have been set in Resolver.resolve()" - ) - - if req.editable: - return self.preparer.prepare_editable_requirement( - req, self.require_hashes, self.use_user_site, self.finder, - ) - - # satisfied_by is only evaluated by calling _check_skip_installed, - # so it must be None here. - assert req.satisfied_by is None - skip_reason = self._check_skip_installed(req) - - if req.satisfied_by: - return self.preparer.prepare_installed_requirement( - req, self.require_hashes, skip_reason - ) - - upgrade_allowed = self._is_upgrade_allowed(req) - abstract_dist = self.preparer.prepare_linked_requirement( - req, self.session, self.finder, upgrade_allowed, - self.require_hashes - ) - - # NOTE - # The following portion is for determining if a certain package is - # going to be re-installed/upgraded or not and reporting to the user. - # This should probably get cleaned up in a future refactor. - - # req.req is only avail after unpack for URL - # pkgs repeat check_if_exists to uninstall-on-upgrade - # (#14) - if not self.ignore_installed: - req.check_if_exists(self.use_user_site) - - if req.satisfied_by: - should_modify = ( - self.upgrade_strategy != "to-satisfy-only" or - self.force_reinstall or - self.ignore_installed or - req.link.scheme == 'file' - ) - if should_modify: - self._set_req_to_reinstall(req) - else: - logger.info( - 'Requirement already satisfied (use --upgrade to upgrade):' - ' %s', req, - ) - - return abstract_dist - - def _resolve_one( - self, - requirement_set, # type: RequirementSet - req_to_install # type: InstallRequirement - ): - # type: (...) -> List[InstallRequirement] - """Prepare a single requirements file. - - :return: A list of additional InstallRequirements to also install. - """ - # Tell user what we are doing for this requirement: - # obtain (editable), skipping, processing (local url), collecting - # (remote url or package name) - if req_to_install.constraint or req_to_install.prepared: - return [] - - req_to_install.prepared = True - - # register tmp src for cleanup in case something goes wrong - requirement_set.reqs_to_cleanup.append(req_to_install) - - abstract_dist = self._get_abstract_dist_for(req_to_install) - - # Parse and return dependencies - dist = abstract_dist.get_pkg_resources_distribution() - # This will raise UnsupportedPythonVersion if the given Python - # version isn't compatible with the distribution's Requires-Python. - _check_dist_requires_python( - dist, version_info=self._py_version_info, - ignore_requires_python=self.ignore_requires_python, - ) - - more_reqs = [] # type: List[InstallRequirement] - - def add_req(subreq, extras_requested): - sub_install_req = install_req_from_req_string( - str(subreq), - req_to_install, - isolated=self.isolated, - wheel_cache=self.wheel_cache, - use_pep517=self.use_pep517 - ) - parent_req_name = req_to_install.name - to_scan_again, add_to_parent = requirement_set.add_requirement( - sub_install_req, - parent_req_name=parent_req_name, - extras_requested=extras_requested, - ) - if parent_req_name and add_to_parent: - self._discovered_dependencies[parent_req_name].append( - add_to_parent - ) - more_reqs.extend(to_scan_again) - - with indent_log(): - # We add req_to_install before its dependencies, so that we - # can refer to it when adding dependencies. - if not requirement_set.has_requirement(req_to_install.name): - # 'unnamed' requirements will get added here - req_to_install.is_direct = True - requirement_set.add_requirement( - req_to_install, parent_req_name=None, - ) - - if not self.ignore_dependencies: - if req_to_install.extras: - logger.debug( - "Installing extra requirements: %r", - ','.join(req_to_install.extras), - ) - missing_requested = sorted( - set(req_to_install.extras) - set(dist.extras) - ) - for missing in missing_requested: - logger.warning( - '%s does not provide the extra \'%s\'', - dist, missing - ) - - available_requested = sorted( - set(dist.extras) & set(req_to_install.extras) - ) - for subreq in dist.requires(available_requested): - add_req(subreq, extras_requested=available_requested) - - if not req_to_install.editable and not req_to_install.satisfied_by: - # XXX: --no-install leads this to report 'Successfully - # downloaded' for only non-editable reqs, even though we took - # action on them. - requirement_set.successfully_downloaded.append(req_to_install) - - return more_reqs - - def get_installation_order(self, req_set): - # type: (RequirementSet) -> List[InstallRequirement] - """Create the installation order. - - The installation order is topological - requirements are installed - before the requiring thing. We break cycles at an arbitrary point, - and make no other guarantees. - """ - # The current implementation, which we may change at any point - # installs the user specified things in the order given, except when - # dependencies must come earlier to achieve topological order. - order = [] - ordered_reqs = set() # type: Set[InstallRequirement] - - def schedule(req): - if req.satisfied_by or req in ordered_reqs: - return - if req.constraint: - return - ordered_reqs.add(req) - for dep in self._discovered_dependencies[req.name]: - schedule(dep) - order.append(req) - - for install_req in req_set.requirements.values(): - schedule(install_req) - return order diff --git a/venv/lib/python3.8/site-packages/pip/_internal/locations.py b/venv/lib/python3.8/site-packages/pip/_internal/locations.py index 5f843d7..0c12354 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/locations.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/locations.py @@ -1,4 +1,8 @@ """Locations where we look for configs, install stuff, etc""" + +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False + from __future__ import absolute_import import os @@ -9,21 +13,35 @@ import sys import sysconfig from distutils import sysconfig as distutils_sysconfig from distutils.command.install import SCHEME_KEYS # type: ignore +from distutils.command.install import install as distutils_install_command +from pip._internal.models.scheme import Scheme from pip._internal.utils import appdirs from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.typing import MYPY_CHECK_RUNNING, cast from pip._internal.utils.virtualenv import running_under_virtualenv if MYPY_CHECK_RUNNING: - from typing import Any, Union, Dict, List, Optional + from typing import Dict, List, Optional, Union + + from distutils.cmd import Command as DistutilsCommand # Application Directories USER_CACHE_DIR = appdirs.user_cache_dir("pip") +def get_major_minor_version(): + # type: () -> str + """ + Return the major-minor version of the current Python as a string, e.g. + "3.7" or "3.10". + """ + return '{}.{}'.format(*sys.version_info) + + def get_src_prefix(): + # type: () -> str if running_under_virtualenv(): src_prefix = os.path.join(sys.prefix, 'src') else: @@ -74,29 +92,25 @@ else: bin_py = '/usr/local/bin' -def distutils_scheme(dist_name, user=False, home=None, root=None, - isolated=False, prefix=None): - # type:(str, bool, str, str, bool, str) -> dict +def distutils_scheme( + dist_name, user=False, home=None, root=None, isolated=False, prefix=None +): + # type:(str, bool, str, str, bool, str) -> Dict[str, str] """ Return a distutils install scheme """ from distutils.dist import Distribution - scheme = {} - - if isolated: - extra_dist_args = {"script_args": ["--no-user-cfg"]} - else: - extra_dist_args = {} dist_args = {'name': dist_name} # type: Dict[str, Union[str, List[str]]] - dist_args.update(extra_dist_args) + if isolated: + dist_args["script_args"] = ["--no-user-cfg"] d = Distribution(dist_args) - # Ignoring, typeshed issue reported python/typeshed/issues/2567 d.parse_config_files() - # NOTE: Ignoring type since mypy can't find attributes on 'Command' - i = d.get_command_obj('install', create=True) # type: Any - assert i is not None + obj = None # type: Optional[DistutilsCommand] + obj = d.get_command_obj('install', create=True) + assert obj is not None + i = cast(distutils_install_command, obj) # NOTE: setting user or home has the side-effect of creating the home dir # or user base for installations during finalize_options() # ideally, we'd prefer a scheme class that has no side-effects. @@ -109,6 +123,8 @@ def distutils_scheme(dist_name, user=False, home=None, root=None, i.home = home or i.home i.root = root or i.root i.finalize_options() + + scheme = {} for key in SCHEME_KEYS: scheme[key] = getattr(i, 'install_' + key) @@ -117,17 +133,15 @@ def distutils_scheme(dist_name, user=False, home=None, root=None, # platlib). Note, i.install_lib is *always* set after # finalize_options(); we only want to override here if the user # has explicitly requested it hence going back to the config - - # Ignoring, typeshed issue reported python/typeshed/issues/2567 - if 'install_lib' in d.get_option_dict('install'): # type: ignore + if 'install_lib' in d.get_option_dict('install'): scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib)) if running_under_virtualenv(): scheme['headers'] = os.path.join( - sys.prefix, + i.prefix, 'include', 'site', - 'python' + sys.version[:3], + 'python{}'.format(get_major_minor_version()), dist_name, ) @@ -140,3 +154,41 @@ def distutils_scheme(dist_name, user=False, home=None, root=None, ) return scheme + + +def get_scheme( + dist_name, # type: str + user=False, # type: bool + home=None, # type: Optional[str] + root=None, # type: Optional[str] + isolated=False, # type: bool + prefix=None, # type: Optional[str] +): + # type: (...) -> Scheme + """ + Get the "scheme" corresponding to the input parameters. The distutils + documentation provides the context for the available schemes: + https://docs.python.org/3/install/index.html#alternate-installation + + :param dist_name: the name of the package to retrieve the scheme for, used + in the headers scheme path + :param user: indicates to use the "user" scheme + :param home: indicates to use the "home" scheme and provides the base + directory for the same + :param root: root under which other directories are re-based + :param isolated: equivalent to --no-user-cfg, i.e. do not consider + ~/.pydistutils.cfg (posix) or ~/pydistutils.cfg (non-posix) for + scheme paths + :param prefix: indicates to use the "prefix" scheme and provides the + base directory for the same + """ + scheme = distutils_scheme( + dist_name, user, home, root, isolated, prefix + ) + return Scheme( + platlib=scheme["platlib"], + purelib=scheme["purelib"], + headers=scheme["headers"], + scripts=scheme["scripts"], + data=scheme["data"], + ) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/__init__.cpython-38.pyc index 9fe42a4356a74f6d5b1f2ab0acae344746f2b2b2..2f3f0dd048fedac084147d294a42d227969545d2 100644 GIT binary patch delta 91 zcmcc1*u=yW%FD~e00f%<cEwNRsdrA+&&bbB)i0_nEzQc*FD^>fPf5(nOwCEoFDgkb t)~l$j(l1NRE7Q-(Owuo?EXl~vGuE@vFU~AU)h$R&&Q45EEuOg21ORP6AW;AS delta 54 zcmZo-y35ED%FD~e00hs=HpETjsh6|UFUc*?FUTy=&CDw<NzBR7HOeq4tuW3{1PM+& GX957W`Vrj# diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/candidate.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/candidate.cpython-38.pyc index 02d28d24a27e3bf70b46b9813d5c2552bc960fe1..5c3d147b448c8c10b46814b0dd67098b9eb726f9 100644 GIT binary patch delta 626 zcmZ8eO=}b}7*1v~o0**%wA8h&SOgVhm3AnC6crIK-UPK?A{fR^Y{$+Q$?W3RV;6c5 z(IvmYW9h-W|HFgx7yJhv)Hg%vih(={@AL3J&zpP=zlZUQIPN1@!{6Wd$vj@iJM&vN zlZOHclB0q$iV@ts+%EzaVDuP?o}e=%s3eCj>kI!m8V2*vJM*8H9^HjL5-}_ga|C9t zaD*$!uFJ>~dV_^0dNZGSf(n0zSWg6^4<|iB1TottYzO9(J221iy+KRLw2&>GNTsu? zY)PJ#`{pBVZYUpI+PF@Ymi&}f0o0V8qxJN-mP%2x<y=gybip0tHsE}er&@D<jDCq^ zuPS7srsMJ3EYWI|h_uXPKB`nB_2#?jK{Ao$B+0YaNj+`$s`B>ccA~RJZq(^$Ki!qu z96Hy$bKtUMPMj~v|9<Mc4X}I$7vR?VoGV!?&M%wy?uR=A%dVVBI&r6?oa+W;SAo;r zA2|dQcr5bgU>zQ6m3H(nFfYl*D?6Ibs|H3>HjrAium;e^r$diqo&&pxvt%XKOHqIj zcIV?`;`W^=^m|?X34DzCL9XN2T=CY-iuZK8tN+tz5!%0BRAQXV2iSIt03s*C5hMq6 F{{qT1k;ni5 delta 608 zcmZ8eJ#Q2-5cRCRyT04qC_x<JLlg)K4me#z=z>70A|!-_fC3ko)7gOy-o2H*7m<o0 zC#9e|xuQf=5e57gMB_ief1tu%<x5QQ{5*d1W;Fht{m6<}MbSq-{_OpHvs@O};qCJ7 zoz15L38GMyvJ{Z#v7%Lv^*WxYewDEd&^8jOpbI3ZBnOz~qW1y~`^&}4*F$i4tKOdm z<MV-!FJ|2ni5LjPA^{8^q8$*CzzfQVAR=BM7K=or{!9)LK`iyw)D7$w9@r<aX}>`G z$)$~+?aFEEie{pX<a<(^a#p+agb-EMA6#tajnta@o{n-})@952kT_zb+R>R$>mtC4 zha+%3&ZlZ(4ChDa@8fY>HRGmiMrCc<iBhBc?;p%RZp<cQ?6dZJbTeM{b*uJQ^mY8d zmtG6L7f)f}Sr|dfMst46e#4*dT?((4PbHnW)1{o7*2`}AH`DzQSVnFGwFhMMT!*gu zN`R{#TyZ@0R4U~gob|jAB*Cy-K<<eNo1j2&p3$VsJ{uOyuEe(>w;S>9woBUmrmWxT f^rY;Z-`RllVKozTB_BaB4cp739P)^ON67I%Mu&v* diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/format_control.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/format_control.cpython-38.pyc index 62e7023d46650c32670feee9ec1cc3485352df1e..a17b624ec34193e3aec74a2a5f990e82ce39e9f1 100644 GIT binary patch literal 2747 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 delta 1101 zcmZuvOHUL*5bnpkcGv}Z7|;b16QbEDi=qdkU}D4=JrIMMm`SuVZZ$A4JG1l*BDy{j z@Zw1_e_%OsFyX8>Z+h}P{s8}jC#z>ckvNmC$JbR~S9RCt<6rxGA66<Z!SCm@y(izC z?cPy3yM3-&mt0){0z5RDre`)S&uZG9P04Kn2AEp}OzCWLuLRb8QnR<;j%|Ou^I#5n zB=IN^j{)^K^aBTDi+Y#>))w(hu)#rXK?z*cwsfEe%3EZUB2@)?5p$srj-l=WhSUSu zJbjdXp%3rnr6?9pgUDAKc~2aL8~aX;=SCvK1*O|iJt%gGs-XHcJDE0HldYgN5kyJq zhvCH3(&e@1mttRo*=u%@R<b=d<1viBi7P3iXp?2qrpsgnk5>)?HJUp@K+s5q*kww` z<Yt^MNmU%v6}=j@gpjL345OWBPC~QC#*L{ii5f&e^=qN4`!_9;LYzeOAnm)+xSN-R zXoP-}2%!sz{3Zq+>XH_v93{g@C0j~}F-=!IEzQ==t8d<;-zFUbbcep;z}kGpQgdzA zp*w_P$A2^fwnGu&fUAR%I~4dZdB<k(?J>(%E|B|V)ot@x@_6c%(Kf(XVQT4sV|6}7 zY?I;+>zHk$U>l$v)-_k>b$ZR5%RX2m)XF|tSE~b9T+So8o*TN)!%by<cGVr%&749( zvT6IrcomJBQ9QOfjdpP>d1*n#FJzR+w8m9AyXK6JAGztlMVSg5gm_(oScp~APm?Rz zOJ{wiVC3q|0a=%OM7u{g`XNXPithXcGP#vamag!!8qStWXW#VcoZ_vAv~>bSUdHiD zgGN)POEGj0Ij=V-wD`+kSbCC_jiQ7r(HG-TgS)Q7@wXXu2c1f>KUZ_}Dh_g8Jd+W` zs^0P&D}FZY9!pLZa1f<ZMSfUcOM@_}ryH#xT2vevb8Fu*&{3uqRsqLPmt`X@=>Jz& X?o2mhSPSKKis6YK>@q7egAVcEp%?Y< diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/index.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/index.cpython-38.pyc index eb396b20a24e114249d18da32fcb106c0459fa15..8197db5197edc5ecfacd04f964af9cd0ad76dc46 100644 GIT binary patch delta 407 zcmX9&%SyvQ6rD$2eT0G_D2NJzQlyO_sNlkt8&`se5Re!%(>66GVJ0oM8#l!wuF8Bx zf5An6!A)2B4ngR`dQ<P>+<VS_ogZsnvTtp>j3Da2pWge#9$xANgODcx9J!bwmoV&7 zMi^xp)0xrMU2Tk7n3>EPS+34XtUN-lF-974%^Os&OlEg>PJ1HCjhJUq5~w*oRO|TT zRcLTFuR<#dAHCEUlIIpMnMPqIis!lQ0ry&ofOggq257=8zyhe#T$4O%t?sOpDb7ot z7ev04o;O8{2d9%fb4Lt%y>9485jf0`LmmZ*$oRf&z6^#=pT~U%3^?f^>m>1U^URT9 z#v7?0Jo#-d)dktntMIO(0&-uop~_8g)lI@!XzGjX>NU_d)HgZ6mfE6?wZepqk_=3U sVpG)AH9e{prG+(WVX{<j^c1FN^c=ftLHDq&wzaF;Ccy-er9uDm9|ACL-~a#s delta 313 zcmX9%y-LGS7`=b_lY~sVbWl*xBB4bK9lCUO6)8mY5}SlXu1&Z%6{%~XL#J{dLOSV# zI6B?c!AB5W^b4NheBU{o!};*O-QX$+b`ap}@$L3#6D)?bRRDDYl%W`>C?+Y6=?djI zB`ICHF-uu$Em3T(5JRzjiMsaYeWI`NdSK{W3gZKb@{ZSuRGD!>salkcv1eH$s;LP$ zSUj&JB$`6^@#(lr4O5xOr3<?<1lnTbaXuA^Qk-wmct)V;c_qjIL2M2P6D7|fr} ztE4scn(SK+)Li{aZbA<}<G{*&RnDZVJM_Tv!Q0hidW;=i(8!T(T>AQj_HDauV*N>n bIMf|B!bVTnA@=k$y9oCPCW!pn^#A?=p$SwN diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/link.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/link.cpython-38.pyc index 0158fbc1f25ea84ddc6bfcc48113f70dba8fcdfb..068adde597c0fd40e40d49cd309a4950a9ec2ce3 100644 GIT binary patch literal 7193 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 delta 2970 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-38.pyc index be25041a4b1d1d20920088ecd789f51a2a6683dd..bdab8d65731f555c7d4b385809da1340602914d2 100644 GIT binary patch delta 1059 zcmZWo&2Jk;6yG;H`{DK4Q9htJEy#8$&8lq{wW_GviV7MbfdY+0%fUdct!HYlv-UbO zlc<SorBWjGgitgR2QD}gcMfpkAK))Qs{A)_Mcf+Rtb6N9@B8=my_xsskJ`Vh)kl>| zVBr_N`m_Dx(n<9nub0TS%A^KZ4p#(cNk_GlUDea?!zZ8KMJTsgz^oQw(6Sj}c9*m$ zcNk^Pv2_G3m$}S4wpt$ZSqY`j0#-&@V&T_TRMEe{BmJHI&iRgQ>c0LwloaVcl6<Zg z$US;wNu{^Q#l=k(PAkkl1+c){Q9GOZn7j-`8KELXrj<Q$=a&A@zIneJ_woUc#s2PY zKaHj6#4H)6JnQ5_ak>6%{~+Gu!@W35pTwhm)ys!B)^Ei!Rs7m0>1-!mF7+4m+UmQe zmk*Fx3lw|^kV2pkQdghQZ<iM^5ZN;-dG_>mGy05PfY0;=Cq8sB>LV2g`W2O~H31|t zw)&P3hAZfkE^OO#Ys32f*2Gr!*gk>@Rdni%=_yQ{vD0_u7IIH+DSujGfPMnjm`nqM zz$<BvVHz+pEi-!>j>##U!l4OZk&5`a2-10wIm|sS{2Mqb12j11VH#>U9{;O@+YfuZ zo(>s*R^Js_y?IGC>yq<<MCV?TrR-{bl<`FJ`bgw^DdY8|E;~Iw;Ohr(Z|3=SI_%c< z-_DXgaUVdW8}1dz^q20&;S7SPT8vDXS<eEQ4)9lPEF;VUh;zp4qbWyOszlA0?vSf2 z?}$|cIB(cW;eMKnL84}~pQpp(`Xg6dG7%?Bhg{B<=c~(EyEqFLX=GAF2C?);D4Wp{ zmerfyTJ!)R@+vZmP#pIP1jM%k&y1b`c|~bReDKd)`}ZHbBY+R}VyS`0yivMd-Z!b$ zB2|w{FZ|1>Mj-C$vr-LS=vwgkduCxHQgkZrpe`D7hk01yj(#3AD?6x4b3v9LR`qYe z8U*@fu)bDmw`G<q*>2Cuoh*@Zz;St*xM)(%o{F1>eXK{}IeohvTsNKggi@an2-f_P p-xTJpM>X*likX+?-7XGGESj{BkhQcbH=w0|D*pxd^yBcG{{dGA0?7aX delta 868 zcmY*YO>fgc5cSv_+i{Yn6$R2lA^iXnN(ucE5D=))15~953RDURD|Fq|tz#!^7pl_I zLnCqF0NOv0f`r5Y2?_oJaN>^4g<CHixNt7BZb4vs-tN44v!0!`e|3K7Xt|wA84_Mw z58vJIO}}XQp<Nl9Hg8Q%bAUaq8D`P)Y+%;PzW>N$lxJbAID&FZDgl*BGKG?25h_!q zA#Fe@MhT5Iq>@Tis^O?noyKw0sWC0(6Z{q2=B;ukJmLNFMcHTEm3!MJf@CvAl}!K% zq&lll@R#z}OlZv6E;Sw7UGzf(r`EE$#2lYDlr^;lOJHfPk<mk!3PH72sM)mv+x3I8 z;|vVVk1Q<@du2iLbus`4_*;?z!atF_r&5@iS3=@j&K%oWMy%ES7kY3O>ZWPCc3_(0 z{6?&>E+eO-T}JaAgo?BVtI~qRiUI>zkSnmLpa)HbLK7R(j8TP>h9u(S*qY7g2H~sh zL8OcA>eOAG`mc^^&DbjDVB7Srsg-?`p0{Ybm8|XJgT1i)V)pUcihLr=U#n-~4gaq8 z!%d#l#`$ygy2FlPl`JRV|E;lp<Yv%(f<Qo)LNM|gOAD!>Lc_PKHOCUoX6=Gd=R8&| z2O(MTY&YszUS>x`B!;JB`TVDr>$rx#e-J^E3A6)&79iXDHX-lF^bLRl{}}Iv<9sVV zl%PT?S}y_bGoJQ{D)Ye3;ILC{bOgqE$M%C+uUflM=U<GgIZ@&6i`nTvS|p;ph=}qs zyq?IU@1Y>tp`<5MD}DT%(Wgx1<NR6TWLIL=!OyvB1@j(dy<(-K0tN*X`Cw{)k%?bo yFPfi3&}BkoFmifaPe+k_2NS_ibG%9g4~4a%$A$&PN0Z$U@|omkIL8mC?)(OI3d!RD diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-38.pyc index 8fcc83f71fe1d616cfdb9494bca79aaf07a97d3a..3792be4627057fe919101948d2fc3629f2a4d813 100644 GIT binary patch delta 215 zcmdnVGlQ2ml$V!_0SGkz?TY_1k#~hTE0E&=#KjswB9$SEF@+(DDTOhLIfW^OIfW&K zHH9smHHsyLJB2fatA#O&HH9OXL6c|Vy_(5dEHRs-7%wnQ?qiXh+{U8moTZ<UpPQ;* zR9RY@m8oA`l&qhUn3tKFlbl~vl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2(- zkeHmEn4VfZ`7DbOqv#}78%DOtwye6Gw>abDi*xcziYI5VstSkz-N?bn!pg?T#K82Q Kg=_Lu)+GRm@H~A0 delta 143 zcmbQiyOW1El$V!_0SKO#ZHOzG$h$(51;}v#;$kTvk;)Lon8Fanl)@OroWhpElET`; z7{!vp9L%7}KJiV><|B+3m?md1#!OzzqABO9Uy@s(Uyxa#o0(T!l9-dDYm{M9T49`@ o2ojtu$!f$XJlTiUhLLr0C#&w{gRIINJU}}*m{@owe_>q$02k6Fi2wiq diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/target_python.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/models/__pycache__/target_python.cpython-38.pyc index fa47f7398c81376871bf34c344a8de847328fe67..3a76a1a84b1ebca6ef484a6aca606b0720635ab1 100644 GIT binary patch delta 744 zcmZ8f&1(}u9G&0nXR^CVN@J^0L@&k_k`)9MtWb+s5j==WVLha2W}9rg$;O#&G?Jpw zh`rXic~eiGJ?TmO4+<ViZsOgmXz^oaBeZ0OeZP-+JM;F<{yzG)l)LXZStN%0=VR@2 zeka$SwcC#G09r)EAm$JeGstZzetzfWvt{L8z1fiL!^058ym;80fB^YGkdF!Y3c*An zD$$58cWN5GN(v-PtReUsv57N8zD{x^FQP#*cab~AS7DpK)=K=Fw#dK3Hk98#!b>>U zh}+$I60U?%nDlG>i~4-BRnrzUY6$`SgLd{QwM9l92{{RQ2?YsL0$hEhvLIR=uchq+ zzNEfG^tcGWT3#z|2OjNjY^;SIqYaPLJ7EwtVwwc3`ndnZ>jj;j7lkWcx1Y4)&V}k_ zkA+qeRJ!%Xdc7Gi{!l*;r}-QG2Tb!<##K1R_Y4>AaBN;Fq~d0zuCV}q+k8=eAZn%y zP(cUtuRH!OIxA`E3;((M=5@Hm=QB&?n__8z))0YplP-u1Hemp1b&|j)?wAQ4z!v|M z*}Y-(0?NX;bFkG&4cpzwHBxU<52+&0!V?FI(p70mb_;wjTP`k(l*t+ySw%<%9h-dG zs({I_S(VHvQ>(EkP8g4@bC;ye?34f#t2%~5^QUSfNaudmHD{>&9o+&wBEskl|7sN{ p?|Rn?PK-+3uv@JO`$<fzW3$6fvzpYKj9;|pEY$`Zt5C$Y@(+n6sNetq delta 570 zcmZ8e&ubJh6wb@cWU@2aX{&2@yMhNnYlLk}Z4agE#TJ$dg7|~N6fBFG*3sGNkQs}I zEeKs{uiN|w>cyMlU*f^b(xc$TyHN2*GOY+E@V)Q7y!X8%?@jY(BY0S?dPuLYyYC-; z3x+|j4m}n!KpiApK?g|CsJd^3!SLv%U%4A)3-gN)y4#P36H{~7bzOu)5Gcd~LQ7PH zCF}u&wr~U)pwKy$2#LV=5%-jYL$!eqq5km;UdJRW)zq5v>MuQZZmAP!sw?EGI)~Rf zoQ&)|O19*rZY3KAY6dPCsB3tK<V9^xR%VM{Hk-v+D^ByGn<TCICkxMC+}P=wp!!Va z;JhO4cVOz5dsFi^<*=f*=<;|eJ#GX~rPT*|Fnve+IniJP0s5OeGB6nv2Fil7+|9}= zwAI_nI=`)t`sgVV@Qlh;&0r7uP<odH?BUcaa3A(zTV3`(b?9y+^LQuC|EZ1axR)i| zl~blk+0HTy|JPHy+?GufZKx%Gx^_>~-1x}#EPY!b*i(hy0$08ETWaKATV^K3ypdwt vMNsY^9;cJi44;q5F>OW-{Z%uYaau$&?Its4<Jn-5I%aJj7%*%@4Vd)@!4iA= diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/candidate.py b/venv/lib/python3.8/site-packages/pip/_internal/models/candidate.py index 1b99690..9149e0f 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/models/candidate.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/models/candidate.py @@ -6,31 +6,33 @@ from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: from pip._vendor.packaging.version import _BaseVersion from pip._internal.models.link import Link - from typing import Any class InstallationCandidate(KeyBasedCompareMixin): """Represents a potential "candidate" for installation. """ - def __init__(self, project, version, link): - # type: (Any, str, Link) -> None - self.project = project + __slots__ = ["name", "version", "link"] + + def __init__(self, name, version, link): + # type: (str, str, Link) -> None + self.name = name self.version = parse_version(version) # type: _BaseVersion self.link = link super(InstallationCandidate, self).__init__( - key=(self.project, self.version, self.link), + key=(self.name, self.version, self.link), defining_class=InstallationCandidate ) def __repr__(self): # type: () -> str return "<InstallationCandidate({!r}, {!r}, {!r})>".format( - self.project, self.version, self.link, + self.name, self.version, self.link, ) def __str__(self): + # type: () -> str return '{!r} candidate (version {} at {})'.format( - self.project, self.version, self.link, + self.name, self.version, self.link, ) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/format_control.py b/venv/lib/python3.8/site-packages/pip/_internal/models/format_control.py index 53138e4..c6275e7 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/models/format_control.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/models/format_control.py @@ -1,5 +1,6 @@ from pip._vendor.packaging.utils import canonicalize_name +from pip._internal.exceptions import CommandError from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: @@ -10,8 +11,10 @@ class FormatControl(object): """Helper for managing formats from which a package can be installed. """ + __slots__ = ["no_binary", "only_binary"] + def __init__(self, no_binary=None, only_binary=None): - # type: (Optional[Set], Optional[Set]) -> None + # type: (Optional[Set[str]], Optional[Set[str]]) -> None if no_binary is None: no_binary = set() if only_binary is None: @@ -21,12 +24,24 @@ class FormatControl(object): self.only_binary = only_binary def __eq__(self, other): - return self.__dict__ == other.__dict__ + # type: (object) -> bool + if not isinstance(other, self.__class__): + return NotImplemented + + if self.__slots__ != other.__slots__: + return False + + return all( + getattr(self, k) == getattr(other, k) + for k in self.__slots__ + ) def __ne__(self, other): + # type: (object) -> bool return not self.__eq__(other) def __repr__(self): + # type: () -> str return "{}({}, {})".format( self.__class__.__name__, self.no_binary, @@ -35,7 +50,11 @@ class FormatControl(object): @staticmethod def handle_mutual_excludes(value, target, other): - # type: (str, Optional[Set], Optional[Set]) -> None + # type: (str, Set[str], Set[str]) -> None + if value.startswith('-'): + raise CommandError( + "--no-binary / --only-binary option requires 1 argument." + ) new = value.split(',') while ':all:' in new: other.clear() @@ -54,7 +73,7 @@ class FormatControl(object): target.add(name) def get_allowed_formats(self, canonical_name): - # type: (str) -> FrozenSet + # type: (str) -> FrozenSet[str] result = {"binary", "source"} if canonical_name in self.only_binary: result.discard('source') diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/index.py b/venv/lib/python3.8/site-packages/pip/_internal/models/index.py index ead1efb..5b4a1fe 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/models/index.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/models/index.py @@ -5,6 +5,9 @@ class PackageIndex(object): """Represents a Package Index and provides easier access to endpoints """ + __slots__ = ['url', 'netloc', 'simple_url', 'pypi_url', + 'file_storage_domain'] + def __init__(self, url, file_storage_domain): # type: (str, str) -> None super(PackageIndex, self).__init__() diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/link.py b/venv/lib/python3.8/site-packages/pip/_internal/models/link.py index d42be28..c0d278a 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/models/link.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/models/link.py @@ -1,18 +1,22 @@ +import os import posixpath import re from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._internal.utils.filetypes import WHEEL_EXTENSION from pip._internal.utils.misc import ( - WHEEL_EXTENSION, path_to_url, redact_password_from_url, - split_auth_from_netloc, splitext, + redact_auth_from_url, + split_auth_from_netloc, + splitext, ) from pip._internal.utils.models import KeyBasedCompareMixin from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import path_to_url, url_to_path if MYPY_CHECK_RUNNING: from typing import Optional, Text, Tuple, Union - from pip._internal.index import HTMLPage + from pip._internal.index.collector import HTMLPage from pip._internal.utils.hashes import Hashes @@ -20,12 +24,22 @@ class Link(KeyBasedCompareMixin): """Represents a parsed link from a Package Index's simple URL """ + __slots__ = [ + "_parsed_url", + "_url", + "comes_from", + "requires_python", + "yanked_reason", + "cache_link_parsing", + ] + def __init__( self, url, # type: str comes_from=None, # type: Optional[Union[str, HTMLPage]] requires_python=None, # type: Optional[str] yanked_reason=None, # type: Optional[Text] + cache_link_parsing=True, # type: bool ): # type: (...) -> None """ @@ -42,6 +56,11 @@ class Link(KeyBasedCompareMixin): a simple repository HTML link. If the file has been yanked but no reason was provided, this should be the empty string. See PEP 592 for more information and the specification. + :param cache_link_parsing: A flag that is used elsewhere to determine + whether resources retrieved from this link + should be cached. PyPI index urls should + generally have this set to False, for + example. """ # url can be a UNC windows share @@ -59,19 +78,23 @@ class Link(KeyBasedCompareMixin): super(Link, self).__init__(key=url, defining_class=Link) + self.cache_link_parsing = cache_link_parsing + def __str__(self): + # type: () -> str if self.requires_python: - rp = ' (requires-python:%s)' % self.requires_python + rp = ' (requires-python:{})'.format(self.requires_python) else: rp = '' if self.comes_from: - return '%s (from %s)%s' % (redact_password_from_url(self._url), - self.comes_from, rp) + return '{} (from {}){}'.format( + redact_auth_from_url(self._url), self.comes_from, rp) else: - return redact_password_from_url(str(self._url)) + return redact_auth_from_url(str(self._url)) def __repr__(self): - return '<Link %s>' % self + # type: () -> str + return '<Link {}>'.format(self) @property def url(self): @@ -90,9 +113,15 @@ class Link(KeyBasedCompareMixin): return netloc name = urllib_parse.unquote(name) - assert name, ('URL %r produced no filename' % self._url) + assert name, ( + 'URL {self._url!r} produced no filename'.format(**locals())) return name + @property + def file_path(self): + # type: () -> str + return url_to_path(self.url) + @property def scheme(self): # type: () -> str @@ -168,27 +197,29 @@ class Link(KeyBasedCompareMixin): @property def show_url(self): - # type: () -> Optional[str] + # type: () -> str return posixpath.basename(self._url.split('#', 1)[0].split('?', 1)[0]) + @property + def is_file(self): + # type: () -> bool + return self.scheme == 'file' + + def is_existing_dir(self): + # type: () -> bool + return self.is_file and os.path.isdir(self.file_path) + @property def is_wheel(self): # type: () -> bool return self.ext == WHEEL_EXTENSION @property - def is_artifact(self): + def is_vcs(self): # type: () -> bool - """ - Determines if this points to an actual artifact (e.g. a tarball) or if - it points to an "abstract" thing like a path or a VCS location. - """ from pip._internal.vcs import vcs - if self.scheme in vcs.all_schemes: - return False - - return True + return self.scheme in vcs.all_schemes @property def is_yanked(self): @@ -197,6 +228,7 @@ class Link(KeyBasedCompareMixin): @property def has_hash(self): + # type: () -> bool return self.hash_name is not None def is_hash_allowed(self, hashes): diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/search_scope.py b/venv/lib/python3.8/site-packages/pip/_internal/models/search_scope.py index 6215244..d732504 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/models/search_scope.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/models/search_scope.py @@ -7,8 +7,8 @@ from pip._vendor.packaging.utils import canonicalize_name from pip._vendor.six.moves.urllib import parse as urllib_parse from pip._internal.models.index import PyPI -from pip._internal.utils.compat import HAS_TLS -from pip._internal.utils.misc import normalize_path, redact_password_from_url +from pip._internal.utils.compat import has_tls +from pip._internal.utils.misc import normalize_path, redact_auth_from_url from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: @@ -24,6 +24,8 @@ class SearchScope(object): Encapsulates the locations that pip is configured to search. """ + __slots__ = ["find_links", "index_urls"] + @classmethod def create( cls, @@ -49,7 +51,7 @@ class SearchScope(object): # If we don't have TLS enabled, then WARN if anyplace we're looking # relies on TLS. - if not HAS_TLS: + if not has_tls(): for link in itertools.chain(index_urls, built_find_links): parsed = urllib_parse.urlparse(link) if parsed.scheme == 'https': @@ -77,15 +79,34 @@ class SearchScope(object): def get_formatted_locations(self): # type: () -> str lines = [] + redacted_index_urls = [] if self.index_urls and self.index_urls != [PyPI.simple_url]: - lines.append( - 'Looking in indexes: {}'.format(', '.join( - redact_password_from_url(url) for url in self.index_urls)) - ) + for url in self.index_urls: + + redacted_index_url = redact_auth_from_url(url) + + # Parse the URL + purl = urllib_parse.urlsplit(redacted_index_url) + + # URL is generally invalid if scheme and netloc is missing + # there are issues with Python and URL parsing, so this test + # is a bit crude. See bpo-20271, bpo-23505. Python doesn't + # always parse invalid URLs correctly - it should raise + # exceptions for malformed URLs + if not purl.scheme and not purl.netloc: + logger.warning( + 'The index url "%s" seems invalid, ' + 'please provide a scheme.', redacted_index_url) + + redacted_index_urls.append(redacted_index_url) + + lines.append('Looking in indexes: {}'.format( + ', '.join(redacted_index_urls))) + if self.find_links: lines.append( 'Looking in links: {}'.format(', '.join( - redact_password_from_url(url) for url in self.find_links)) + redact_auth_from_url(url) for url in self.find_links)) ) return '\n'.join(lines) @@ -98,6 +119,7 @@ class SearchScope(object): """ def mkurl_pypi_url(url): + # type: (str) -> str loc = posixpath.join( url, urllib_parse.quote(canonicalize_name(project_name))) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/selection_prefs.py b/venv/lib/python3.8/site-packages/pip/_internal/models/selection_prefs.py index f58fdce..5db3ca9 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/models/selection_prefs.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/models/selection_prefs.py @@ -6,12 +6,14 @@ if MYPY_CHECK_RUNNING: class SelectionPreferences(object): - """ Encapsulates the candidate selection preferences for downloading and installing files. """ + __slots__ = ['allow_yanked', 'allow_all_prereleases', 'format_control', + 'prefer_binary', 'ignore_requires_python'] + # Don't include an allow_yanked default value to make sure each call # site considers whether yanked releases are allowed. This also causes # that decision to be made explicit in the calling code, which helps diff --git a/venv/lib/python3.8/site-packages/pip/_internal/models/target_python.py b/venv/lib/python3.8/site-packages/pip/_internal/models/target_python.py index a23b79c..6d1ca79 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/models/target_python.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/models/target_python.py @@ -1,12 +1,16 @@ import sys -from pip._internal.pep425tags import get_supported, version_info_to_nodot +from pip._internal.utils.compatibility_tags import ( + get_supported, + version_info_to_nodot, +) from pip._internal.utils.misc import normalize_version_info from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: from typing import List, Optional, Tuple - from pip._internal.pep425tags import Pep425Tag + + from pip._vendor.packaging.tags import Tag class TargetPython(object): @@ -16,6 +20,16 @@ class TargetPython(object): for a package install, download, etc. """ + __slots__ = [ + "_given_py_version_info", + "abi", + "implementation", + "platform", + "py_version", + "py_version_info", + "_valid_tags", + ] + def __init__( self, platform=None, # type: Optional[str] @@ -33,10 +47,10 @@ class TargetPython(object): :param py_version_info: An optional tuple of ints representing the Python version information to use (e.g. `sys.version_info[:3]`). This can have length 1, 2, or 3 when provided. - :param abi: A string or None. This is passed to pep425tags.py's + :param abi: A string or None. This is passed to compatibility_tags.py's get_supported() function as is. :param implementation: A string or None. This is passed to - pep425tags.py's get_supported() function as is. + compatibility_tags.py's get_supported() function as is. """ # Store the given py_version_info for when we call get_supported(). self._given_py_version_info = py_version_info @@ -55,7 +69,7 @@ class TargetPython(object): self.py_version_info = py_version_info # This is used to cache the return value of get_tags(). - self._valid_tags = None # type: Optional[List[Pep425Tag]] + self._valid_tags = None # type: Optional[List[Tag]] def format_given(self): # type: () -> str @@ -80,7 +94,7 @@ class TargetPython(object): ) def get_tags(self): - # type: () -> List[Pep425Tag] + # type: () -> List[Tag] """ Return the supported PEP 425 tags to check wheel candidates against. @@ -91,12 +105,12 @@ class TargetPython(object): # versions=None uses special default logic. py_version_info = self._given_py_version_info if py_version_info is None: - versions = None + version = None else: - versions = [version_info_to_nodot(py_version_info)] + version = version_info_to_nodot(py_version_info) tags = get_supported( - versions=versions, + version=version, platform=self.platform, abi=self.abi, impl=self.implementation, diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-38.pyc index 5cdba669f0fd02d1bdd735a7429a0461394bbc56..1ced638cdfe13ba2834e91967cc18c04e989ad3d 100644 GIT binary patch delta 91 zcmbQsc!-fFl$V!_0SGkz?TVksW9^)-pOK%Ns$W!DTAG!qUtE-|pOToDnVOTFUsRG> ttXEN4rC*ksSEiqnnWSG(S(1^TXRK$TUz}Nzs#}nloSm4ST0Ak;0svXtAJ6~* delta 54 zcmX@aIG2$pl$V!_0SKO#ZHSx5V=d>TUy@s(Uyxa#o0(T!l9-dDYm{M9T49`@2ojvw GWdQ)K`4L<I diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/check.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/check.cpython-38.pyc index 43331db250a788385a7dd8150c564d6657346e0d..db7cae8d6273b39888c3b9ae38db5315b7bada2f 100644 GIT binary patch delta 1257 zcmYjQ-D@0G6u<Y*_v}ZTX7kleLSoY<lcwF$#t+gEshf)QAy#5RS7f`{dv|wsCp+n# zN!p}$DRleTis3#9J|rL(LG(cs5%DijMDS^zeb5&X`YxV3iPag-@1FZRXXczazdJvV ze?FeOmCLyZF7NN}s`vJD6L?|&JjH+Qf7maNv2ixtAY-WV0@G-QW@)ZT`lND(=IMz? zs4_!G=}9{92v^S1Q*;oRbF@H*V4bDIbOhG9uWsOXG5$b)Lgw&o`4gEh#8!iJT>cQF zo`KQcaBLqq($bz{SAMC@4ky-|>(@CCIoF}7#0<h_lX3Z*wpym8R=CMZe0O`h?Uy26 zFVR}pXF)yWF^ewV+ubYeu<lMN@Ha|ZyKyV*Ub*;6De_}>VXIc})S4`kuj|+GS@~E$ zZ5K!$k77P8ztATh{0g;v)FWV;K&$BeA9{L>`p{yEroen&V4?S6y^|G4=wqmjAus4z zF%ec<>*Jm+Y=Jr!-=VnY0H;&ZarlPv4va$toWmD|abQ9o4B-%CbY~IXWskjw+E&kn zM7!+>mtv|tA<?2R(^TLa+HtbMzlmL8#2KnTA%X~f83~hTfisUeO>xj75n6++BhQdu z8y}s1d(Fd1W{We<0#=Jy1Y51ccD<~8X5Jbss!`{nR=6F|s^9E}oXNMW8+cNFY!xp| zspvqx#p<2v@gS=ai<f|oE&(80$2zfziA|D~zgshSQReJFuXvbGLi977ICop1Lf}U+ z9|VR^0VMWvP}|&~wUr&%Jp)5~p8Ulbk!5GdUVyEqgF3gJ%Z0^slelqM^}A7A3j$u0 zpE^_KOAz2w@<(SJH{>5q@xiM=)Cs`9mj#XiRtAgS0Z8>Esm5>gv=|GeoG$bO0ty+z zpt$2i^Rf02$GR}u21L!+1kVEH>_gNia1KluJ2`NKnabh{HE6Q;T3Oz8uNiBe%V*^G z?%c~s{#q0<9{XYU=tyhO06(MPq=EqjrxeTrcott)eo<yJb4wG-RpUFF*z>V*HTL^p zk$MoBre<TfNfx`fK(d4{$xfy__aekRgU`TnR3R;$zAvq1@D&v*N}L^OmXv#0L0aa& zT33PF2Ro_-602GSew;j1vk6ym53hM%VpXd&tXHdvrG8ky+e|X`FbG&(eSE}~Bo%o- z`>nx8!If8YH}QG-ICpcsa-tk|8-ZVsS6N*1gXm~9(~!lL?p#Tleso&xe;qz=6Hd}* cNVfyFf+07$Bq#IdayU!!nmyz$*hBX4Kces@SpWb4 delta 1338 zcmZuxU1%It6u$S)-<{cP+_XtI#zfaPCcBX&(x$E2HK}$L5e>oGg26hhbN6Smlb!U= zL`%419ya<Q6dEt$>*h%cf`uZ8FTVLC2);Sb1s?<-1wpOn&hA4*2kv*zJ?GqW&Ybhj zd^!E&bpBdC?;v=7dH>$K?Zf;GE*(D2@PorUy^9*lu@RPUksjGR%|_WH2WayQn`8wx zc7Qi$*$H+MG*7W{HUaw_JH?8y&)>g}-^Tb8d5@IwJMw3;Q0O@PLyQswqrFqH)u*zk zeSvNHoi;zpb;zAsLD*{f-In}Qt3AH99B=O|@Ax~5em9EiL9lqXy|R1jTv%61+0$P> zGYglZNmaH%u|ssM<5BEjf+ul-i~{nK{8gXXe*hi=Gu)xPzzEY0P=aIBLkY=H6R3u6 ze4FSo2Az?iDX`Fcm_L8BB#_V_MOy@Xg2ak7VQqmWp@It3vG~VKPi)W`5Z~rpNqzGO zfzIYNVe~DrPleSaM;N1<H3&u_7)=~-w6`4LFr68<NmLUixKaW7rZ)67`1f&681V=* zZxca;UPZ#>CD55eou+h9A`x1XTtyXY@AE6|hSw?i%~HLzQ};UcRzv=7e6+vrVb!SN zqhz(N!irSy8HU?r{S|%^4tFu1fi05<@B|#weAEti1LpdzZpa%if+`{a2=A3WmDC;P zbE8JQR1HF}9z?54gG+RH>n)j>MJu1`%=cpXnR(5gf(ZOHfc(pR?G2STHMjjJYA`;g zOsb$`MU4F?)pOtwtpFg4Vyc<gB$Q+*?^v_=y!_hwZJs{~_PaQ>KWO`LBk-g6SWH?C z>f7(J`sywD1HC|1F%=!S<Jf1%&u53!i9>hDLp~)p?9$prFz~D|#X(6!v+IT3W&m#& zwZS7g0f0=0IGUpope8}iL;Y`lS$<{Dy!krV21Lv#SWUDT3k}Gn3%yT(L<Z2!$mnLq z21uqN)Dh|tpr;9JAbl##j4h5(^T%?*sp%D)&&kLs&vOkDaP^t+f`Y7}sv=$is95|3 zB~Qtpobt2NO8lR(^GjezU_~kfGEEJ-j45&OI2j@Ql3dAkZ(ION#o%+W@hpCpIE$8L zGWeP@sadCELz+Zxz1eJdF%0?{Wjv?g-_zz*(0wW&<{n#6QU$M9%BkhLEc9HL7eSTg zyf6qLiXV0(uIQM`S4X~~sj2=Y4K9uR240lc^BXS>T2KNPu7=7lD^M?&WjU5Pt09{# et!{^GH)yP?ZzWoif8^(KWK^RQ&N7{#6aN5AU^4#z diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-38.pyc index 2117e82372fba15b71dcf76c91a06c0c2c09e126..746dd14b1122e745cd036ba4424360953dbb0935 100644 GIT binary patch delta 2894 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 Xk674JO<0zie0}O<{xf5MG=25Is_eG` delta 2667 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 AvH$=8 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-38.pyc index 53048fb77dc9b4afa13759b598dc2d60ae85dae9..1d156767a6bbacf09b56d9f82c6f45c75e3a0e2d 100644 GIT binary patch literal 11508 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 literal 5744 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/check.py b/venv/lib/python3.8/site-packages/pip/_internal/operations/check.py index 7b8b369..0d59632 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/operations/check.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/operations/check.py @@ -29,6 +29,7 @@ if MYPY_CHECK_RUNNING: MissingDict = Dict[str, List[Missing]] ConflictingDict = Dict[str, List[Conflicting]] CheckResult = Tuple[MissingDict, ConflictingDict] + ConflictDetails = Tuple[PackageSet, CheckResult] PackageDetails = namedtuple('PackageDetails', ['version', 'requires']) @@ -47,9 +48,9 @@ def create_package_set_from_installed(**kwargs): name = canonicalize_name(dist.project_name) try: package_set[name] = PackageDetails(dist.version, dist.requires()) - except RequirementParseError as e: - # Don't crash on broken metadata - logging.warning("Error parsing requirements for %s: %s", name, e) + except (OSError, RequirementParseError) as e: + # Don't crash on unreadable or broken metadata + logger.warning("Error parsing requirements for %s: %s", name, e) problems = True return package_set, problems @@ -61,19 +62,16 @@ def check_package_set(package_set, should_ignore=None): If should_ignore is passed, it should be a callable that takes a package name and returns a boolean. """ - if should_ignore is None: - def should_ignore(name): - return False - missing = dict() - conflicting = dict() + missing = {} + conflicting = {} for package_name in package_set: # Info about dependencies of package_name missing_deps = set() # type: Set[Missing] conflicting_deps = set() # type: Set[Conflicting] - if should_ignore(package_name): + if should_ignore and should_ignore(package_name): continue for req in package_set[package_name].requires: @@ -102,7 +100,7 @@ def check_package_set(package_set, should_ignore=None): def check_install_conflicts(to_install): - # type: (List[InstallRequirement]) -> Tuple[PackageSet, CheckResult] + # type: (List[InstallRequirement]) -> ConflictDetails """For checking if the dependency graph would be consistent after \ installing given requirements """ @@ -135,6 +133,7 @@ def _simulate_installation_of(to_install, package_set): abstract_dist = make_distribution_for_install_requirement(inst_req) dist = abstract_dist.get_pkg_resources_distribution() + assert dist is not None name = canonicalize_name(dist.key) package_set[name] = PackageDetails(dist.version, dist.requires()) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/freeze.py b/venv/lib/python3.8/site-packages/pip/_internal/operations/freeze.py index 6f5a3dd..ddb9cb2 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/operations/freeze.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/operations/freeze.py @@ -3,7 +3,6 @@ from __future__ import absolute_import import collections import logging import os -import re from pip._vendor import six from pip._vendor.packaging.utils import canonicalize_name @@ -11,11 +10,17 @@ from pip._vendor.pkg_resources import RequirementParseError from pip._internal.exceptions import BadCommand, InstallationError from pip._internal.req.constructors import ( - install_req_from_editable, install_req_from_line, + install_req_from_editable, + install_req_from_line, ) from pip._internal.req.req_file import COMMENT_RE +from pip._internal.utils.direct_url_helpers import ( + direct_url_as_pep440_direct_reference, + dist_get_direct_url, +) from pip._internal.utils.misc import ( - dist_is_editable, get_installed_distributions, + dist_is_editable, + get_installed_distributions, ) from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -37,10 +42,9 @@ logger = logging.getLogger(__name__) def freeze( requirement=None, # type: Optional[List[str]] find_links=None, # type: Optional[List[str]] - local_only=None, # type: Optional[bool] - user_only=None, # type: Optional[bool] + local_only=False, # type: bool + user_only=False, # type: bool paths=None, # type: Optional[List[str]] - skip_regex=None, # type: Optional[str] isolated=False, # type: bool wheel_cache=None, # type: Optional[WheelCache] exclude_editable=False, # type: bool @@ -48,18 +52,17 @@ def freeze( ): # type: (...) -> Iterator[str] find_links = find_links or [] - skip_match = None - - if skip_regex: - skip_match = re.compile(skip_regex).search for link in find_links: - yield '-f %s' % link + yield '-f {}'.format(link) installations = {} # type: Dict[str, FrozenRequirement] - for dist in get_installed_distributions(local_only=local_only, - skip=(), - user_only=user_only, - paths=paths): + + for dist in get_installed_distributions( + local_only=local_only, + skip=(), + user_only=user_only, + paths=paths + ): try: req = FrozenRequirement.from_dist(dist) except RequirementParseError as exc: @@ -74,7 +77,7 @@ def freeze( continue if exclude_editable and req.editable: continue - installations[req.name] = req + installations[req.canonical_name] = req if requirement: # the options that don't get turned into an InstallRequirement @@ -90,16 +93,15 @@ def freeze( for line in req_file: if (not line.strip() or line.strip().startswith('#') or - (skip_match and skip_match(line)) or line.startswith(( '-r', '--requirement', - '-Z', '--always-unzip', '-f', '--find-links', '-i', '--index-url', '--pre', '--trusted-host', '--process-dependency-links', - '--extra-index-url'))): + '--extra-index-url', + '--use-feature'))): line = line.rstrip() if line not in emitted_options: emitted_options.add(line) @@ -114,13 +116,11 @@ def freeze( line_req = install_req_from_editable( line, isolated=isolated, - wheel_cache=wheel_cache, ) else: line_req = install_req_from_line( COMMENT_RE.sub('', line).strip(), isolated=isolated, - wheel_cache=wheel_cache, ) if not line_req.name: @@ -133,22 +133,27 @@ def freeze( " (add #egg=PackageName to the URL to avoid" " this warning)" ) - elif line_req.name not in installations: - # either it's not installed, or it is installed - # but has been processed already - if not req_files[line_req.name]: - logger.warning( - "Requirement file [%s] contains %s, but " - "package %r is not installed", - req_file_path, - COMMENT_RE.sub('', line).strip(), line_req.name - ) - else: - req_files[line_req.name].append(req_file_path) else: - yield str(installations[line_req.name]).rstrip() - del installations[line_req.name] - req_files[line_req.name].append(req_file_path) + line_req_canonical_name = canonicalize_name( + line_req.name) + if line_req_canonical_name not in installations: + # either it's not installed, or it is installed + # but has been processed already + if not req_files[line_req.name]: + logger.warning( + "Requirement file [%s] contains %s, but " + "package %r is not installed", + req_file_path, + COMMENT_RE.sub('', line).strip(), + line_req.name + ) + else: + req_files[line_req.name].append(req_file_path) + else: + yield str(installations[ + line_req_canonical_name]).rstrip() + del installations[line_req_canonical_name] + req_files[line_req.name].append(req_file_path) # Warn about requirements that were included multiple times (in a # single requirements file or in different requirements files). @@ -163,7 +168,7 @@ def freeze( ) for installation in sorted( installations.values(), key=lambda x: x.name.lower()): - if canonicalize_name(installation.name) not in skip: + if installation.canonical_name not in skip: yield str(installation).rstrip() @@ -233,6 +238,7 @@ class FrozenRequirement(object): def __init__(self, name, req, editable, comments=()): # type: (str, Union[str, Requirement], bool, Iterable[str]) -> None self.name = name + self.canonical_name = canonicalize_name(name) self.req = req self.editable = editable self.comments = comments @@ -240,14 +246,27 @@ class FrozenRequirement(object): @classmethod def from_dist(cls, dist): # type: (Distribution) -> FrozenRequirement + # TODO `get_requirement_info` is taking care of editable requirements. + # TODO This should be refactored when we will add detection of + # editable that provide .dist-info metadata. req, editable, comments = get_requirement_info(dist) + if req is None and not editable: + # if PEP 610 metadata is present, attempt to use it + direct_url = dist_get_direct_url(dist) + if direct_url: + req = direct_url_as_pep440_direct_reference( + direct_url, dist.project_name + ) + comments = [] if req is None: + # name==version requirement req = dist.as_requirement() return cls(dist.project_name, req, editable, comments=comments) def __str__(self): + # type: () -> str req = self.req if self.editable: - req = '-e %s' % req + req = '-e {}'.format(req) return '\n'.join(list(self.comments) + [str(req)]) + '\n' diff --git a/venv/lib/python3.8/site-packages/pip/_internal/operations/prepare.py b/venv/lib/python3.8/site-packages/pip/_internal/operations/prepare.py index 6cf5f0e..a5455fc 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/operations/prepare.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/operations/prepare.py @@ -1,40 +1,319 @@ """Prepares a distribution for installation """ -import logging -import os +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False -from pip._vendor import requests +import logging +import mimetypes +import os +import shutil + +from pip._vendor.six import PY2 from pip._internal.distributions import ( make_distribution_for_install_requirement, ) from pip._internal.distributions.installed import InstalledDistribution -from pip._internal.download import ( - is_dir_url, is_file_url, is_vcs_url, unpack_url, url_to_path, -) from pip._internal.exceptions import ( - DirectoryUrlHashUnsupported, HashUnpinned, InstallationError, - PreviousBuildDirError, VcsHashUnsupported, + DirectoryUrlHashUnsupported, + HashMismatch, + HashUnpinned, + InstallationError, + NetworkConnectionError, + PreviousBuildDirError, + VcsHashUnsupported, ) -from pip._internal.utils.compat import expanduser +from pip._internal.utils.filesystem import copy2_fixed from pip._internal.utils.hashes import MissingHashes from pip._internal.utils.logging import indent_log -from pip._internal.utils.misc import display_path, normalize_path +from pip._internal.utils.misc import ( + display_path, + hide_url, + path_to_display, + rmtree, +) +from pip._internal.utils.temp_dir import TempDirectory from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.unpacking import unpack_file +from pip._internal.vcs import vcs if MYPY_CHECK_RUNNING: - from typing import Optional + from typing import ( + Callable, List, Optional, Tuple, + ) + + from mypy_extensions import TypedDict from pip._internal.distributions import AbstractDistribution - from pip._internal.download import PipSession - from pip._internal.index import PackageFinder + from pip._internal.index.package_finder import PackageFinder + from pip._internal.models.link import Link + from pip._internal.network.download import Downloader from pip._internal.req.req_install import InstallRequirement from pip._internal.req.req_tracker import RequirementTracker + from pip._internal.utils.hashes import Hashes + + if PY2: + CopytreeKwargs = TypedDict( + 'CopytreeKwargs', + { + 'ignore': Callable[[str, List[str]], List[str]], + 'symlinks': bool, + }, + total=False, + ) + else: + CopytreeKwargs = TypedDict( + 'CopytreeKwargs', + { + 'copy_function': Callable[[str, str], None], + 'ignore': Callable[[str, List[str]], List[str]], + 'ignore_dangling_symlinks': bool, + 'symlinks': bool, + }, + total=False, + ) logger = logging.getLogger(__name__) +def _get_prepared_distribution( + req, # type: InstallRequirement + req_tracker, # type: RequirementTracker + finder, # type: PackageFinder + build_isolation # type: bool +): + # type: (...) -> AbstractDistribution + """Prepare a distribution for installation. + """ + abstract_dist = make_distribution_for_install_requirement(req) + with req_tracker.track(req): + abstract_dist.prepare_distribution_metadata(finder, build_isolation) + return abstract_dist + + +def unpack_vcs_link(link, location): + # type: (Link, str) -> None + vcs_backend = vcs.get_backend_for_scheme(link.scheme) + assert vcs_backend is not None + vcs_backend.unpack(location, url=hide_url(link.url)) + + +class File(object): + def __init__(self, path, content_type): + # type: (str, str) -> None + self.path = path + self.content_type = content_type + + +def get_http_url( + link, # type: Link + downloader, # type: Downloader + download_dir=None, # type: Optional[str] + hashes=None, # type: Optional[Hashes] +): + # type: (...) -> File + temp_dir = TempDirectory(kind="unpack", globally_managed=True) + # If a download dir is specified, is the file already downloaded there? + already_downloaded_path = None + if download_dir: + already_downloaded_path = _check_download_dir( + link, download_dir, hashes + ) + + if already_downloaded_path: + from_path = already_downloaded_path + content_type = mimetypes.guess_type(from_path)[0] + else: + # let's download to a tmp dir + from_path, content_type = _download_http_url( + link, downloader, temp_dir.path, hashes + ) + + return File(from_path, content_type) + + +def _copy2_ignoring_special_files(src, dest): + # type: (str, str) -> None + """Copying special files is not supported, but as a convenience to users + we skip errors copying them. This supports tools that may create e.g. + socket files in the project source directory. + """ + try: + copy2_fixed(src, dest) + except shutil.SpecialFileError as e: + # SpecialFileError may be raised due to either the source or + # destination. If the destination was the cause then we would actually + # care, but since the destination directory is deleted prior to + # copy we ignore all of them assuming it is caused by the source. + logger.warning( + "Ignoring special file error '%s' encountered copying %s to %s.", + str(e), + path_to_display(src), + path_to_display(dest), + ) + + +def _copy_source_tree(source, target): + # type: (str, str) -> None + target_abspath = os.path.abspath(target) + target_basename = os.path.basename(target_abspath) + target_dirname = os.path.dirname(target_abspath) + + def ignore(d, names): + # type: (str, List[str]) -> List[str] + skipped = [] # type: List[str] + if d == source: + # Pulling in those directories can potentially be very slow, + # exclude the following directories if they appear in the top + # level dir (and only it). + # See discussion at https://github.com/pypa/pip/pull/6770 + skipped += ['.tox', '.nox'] + if os.path.abspath(d) == target_dirname: + # Prevent an infinite recursion if the target is in source. + # This can happen when TMPDIR is set to ${PWD}/... + # and we copy PWD to TMPDIR. + skipped += [target_basename] + return skipped + + kwargs = dict(ignore=ignore, symlinks=True) # type: CopytreeKwargs + + if not PY2: + # Python 2 does not support copy_function, so we only ignore + # errors on special file copy in Python 3. + kwargs['copy_function'] = _copy2_ignoring_special_files + + shutil.copytree(source, target, **kwargs) + + +def get_file_url( + link, # type: Link + download_dir=None, # type: Optional[str] + hashes=None # type: Optional[Hashes] +): + # type: (...) -> File + """Get file and optionally check its hash. + """ + # If a download dir is specified, is the file already there and valid? + already_downloaded_path = None + if download_dir: + already_downloaded_path = _check_download_dir( + link, download_dir, hashes + ) + + if already_downloaded_path: + from_path = already_downloaded_path + else: + from_path = link.file_path + + # If --require-hashes is off, `hashes` is either empty, the + # link's embedded hash, or MissingHashes; it is required to + # match. If --require-hashes is on, we are satisfied by any + # hash in `hashes` matching: a URL-based or an option-based + # one; no internet-sourced hash will be in `hashes`. + if hashes: + hashes.check_against_path(from_path) + + content_type = mimetypes.guess_type(from_path)[0] + + return File(from_path, content_type) + + +def unpack_url( + link, # type: Link + location, # type: str + downloader, # type: Downloader + download_dir=None, # type: Optional[str] + hashes=None, # type: Optional[Hashes] +): + # type: (...) -> Optional[File] + """Unpack link into location, downloading if required. + + :param hashes: A Hashes object, one of whose embedded hashes must match, + or HashMismatch will be raised. If the Hashes is empty, no matches are + required, and unhashable types of requirements (like VCS ones, which + would ordinarily raise HashUnsupported) are allowed. + """ + # non-editable vcs urls + if link.is_vcs: + unpack_vcs_link(link, location) + return None + + # If it's a url to a local directory + if link.is_existing_dir(): + if os.path.isdir(location): + rmtree(location) + _copy_source_tree(link.file_path, location) + return None + + # file urls + if link.is_file: + file = get_file_url(link, download_dir, hashes=hashes) + + # http urls + else: + file = get_http_url( + link, + downloader, + download_dir, + hashes=hashes, + ) + + # unpack the archive to the build dir location. even when only downloading + # archives, they have to be unpacked to parse dependencies, except wheels + if not link.is_wheel: + unpack_file(file.path, location, file.content_type) + + return file + + +def _download_http_url( + link, # type: Link + downloader, # type: Downloader + temp_dir, # type: str + hashes, # type: Optional[Hashes] +): + # type: (...) -> Tuple[str, str] + """Download link url into temp_dir using provided session""" + download = downloader(link) + + file_path = os.path.join(temp_dir, download.filename) + with open(file_path, 'wb') as content_file: + for chunk in download.chunks: + content_file.write(chunk) + + if hashes: + hashes.check_against_path(file_path) + + return file_path, download.response.headers.get('content-type', '') + + +def _check_download_dir(link, download_dir, hashes): + # type: (Link, str, Optional[Hashes]) -> Optional[str] + """ Check download_dir for previously downloaded file with correct hash + If a correct file is found return its path else None + """ + download_path = os.path.join(download_dir, link.filename) + + if not os.path.exists(download_path): + return None + + # If already downloaded, does its hash match? + logger.info('File was already downloaded %s', download_path) + if hashes: + try: + hashes.check_against_path(download_path) + except HashMismatch: + logger.warning( + 'Previously-downloaded file %s has bad hash. ' + 'Re-downloading.', + download_path + ) + os.unlink(download_path) + return None + return download_path + + class RequirementPreparer(object): """Prepares a Requirement """ @@ -45,9 +324,12 @@ class RequirementPreparer(object): download_dir, # type: Optional[str] src_dir, # type: str wheel_download_dir, # type: Optional[str] - progress_bar, # type: str build_isolation, # type: bool - req_tracker # type: RequirementTracker + req_tracker, # type: RequirementTracker + downloader, # type: Downloader + finder, # type: PackageFinder + require_hashes, # type: bool + use_user_site, # type: bool ): # type: (...) -> None super(RequirementPreparer, self).__init__() @@ -55,16 +337,16 @@ class RequirementPreparer(object): self.src_dir = src_dir self.build_dir = build_dir self.req_tracker = req_tracker + self.downloader = downloader + self.finder = finder - # Where still packed archives should be written to. If None, they are + # Where still-packed archives should be written to. If None, they are # not saved, and are deleted immediately after unpacking. self.download_dir = download_dir # Where still-packed .whl files should be written to. If None, they are # written to the download_dir parameter. Separate to download_dir to # permit only keeping wheel archives for pip wheel. - if wheel_download_dir: - wheel_download_dir = normalize_path(wheel_download_dir) self.wheel_download_dir = wheel_download_dir # NOTE @@ -72,160 +354,156 @@ class RequirementPreparer(object): # be combined if we're willing to have non-wheel archives present in # the wheelhouse output by 'pip wheel'. - self.progress_bar = progress_bar - # Is build isolation allowed? self.build_isolation = build_isolation + # Should hash-checking be required? + self.require_hashes = require_hashes + + # Should install in user site-packages? + self.use_user_site = use_user_site + @property def _download_should_save(self): # type: () -> bool - # TODO: Modify to reduce indentation needed - if self.download_dir: - self.download_dir = expanduser(self.download_dir) - if os.path.exists(self.download_dir): - return True - else: - logger.critical('Could not find download directory') - raise InstallationError( - "Could not find or access download directory '%s'" - % display_path(self.download_dir)) - return False + if not self.download_dir: + return False - def prepare_linked_requirement( - self, - req, # type: InstallRequirement - session, # type: PipSession - finder, # type: PackageFinder - upgrade_allowed, # type: bool - require_hashes # type: bool - ): - # type: (...) -> AbstractDistribution - """Prepare a requirement that would be obtained from req.link - """ - # TODO: Breakup into smaller functions - if req.link and req.link.scheme == 'file': - path = url_to_path(req.link.url) + if os.path.exists(self.download_dir): + return True + + logger.critical('Could not find download directory') + raise InstallationError( + "Could not find or access download directory '{}'" + .format(self.download_dir)) + + def _log_preparing_link(self, req): + # type: (InstallRequirement) -> None + """Log the way the link prepared.""" + if req.link.is_file: + path = req.link.file_path logger.info('Processing %s', display_path(path)) else: - logger.info('Collecting %s', req) + logger.info('Collecting %s', req.req or req) + + def _ensure_link_req_src_dir(self, req, download_dir, parallel_builds): + # type: (InstallRequirement, Optional[str], bool) -> None + """Ensure source_dir of a linked InstallRequirement.""" + # Since source_dir is only set for editable requirements. + if req.link.is_wheel: + # We don't need to unpack wheels, so no need for a source + # directory. + return + assert req.source_dir is None + # We always delete unpacked sdists after pip runs. + req.ensure_has_source_dir( + self.build_dir, + autodelete=True, + parallel_builds=parallel_builds, + ) + + # If a checkout exists, it's unwise to keep going. version + # inconsistencies are logged later, but do not fail the + # installation. + # FIXME: this won't upgrade when there's an existing + # package unpacked in `req.source_dir` + if os.path.exists(os.path.join(req.source_dir, 'setup.py')): + raise PreviousBuildDirError( + "pip can't proceed with requirements '{}' due to a" + "pre-existing build directory ({}). This is likely " + "due to a previous installation that failed . pip is " + "being responsible and not assuming it can delete this. " + "Please delete it and try again.".format(req, req.source_dir) + ) + + def _get_linked_req_hashes(self, req): + # type: (InstallRequirement) -> Hashes + # By the time this is called, the requirement's link should have + # been checked so we can tell what kind of requirements req is + # and raise some more informative errors than otherwise. + # (For example, we can raise VcsHashUnsupported for a VCS URL + # rather than HashMissing.) + if not self.require_hashes: + return req.hashes(trust_internet=True) + + # We could check these first 2 conditions inside unpack_url + # and save repetition of conditions, but then we would + # report less-useful error messages for unhashable + # requirements, complaining that there's no hash provided. + if req.link.is_vcs: + raise VcsHashUnsupported() + if req.link.is_existing_dir(): + raise DirectoryUrlHashUnsupported() + + # Unpinned packages are asking for trouble when a new version + # is uploaded. This isn't a security check, but it saves users + # a surprising hash mismatch in the future. + # file:/// URLs aren't pinnable, so don't complain about them + # not being pinned. + if req.original_link is None and not req.is_pinned: + raise HashUnpinned() + + # If known-good hashes are missing for this requirement, + # shim it with a facade object that will provoke hash + # computation and then raise a HashMissing exception + # showing the user what the hash should be. + return req.hashes(trust_internet=False) or MissingHashes() + + def prepare_linked_requirement(self, req, parallel_builds=False): + # type: (InstallRequirement, bool) -> AbstractDistribution + """Prepare a requirement to be obtained from req.link.""" + assert req.link + link = req.link + self._log_preparing_link(req) + if link.is_wheel and self.wheel_download_dir: + # Download wheels to a dedicated dir when doing `pip wheel`. + download_dir = self.wheel_download_dir + else: + download_dir = self.download_dir with indent_log(): - # @@ if filesystem packages are not marked - # editable in a req, a non deterministic error - # occurs when the script attempts to unpack the - # build directory - req.ensure_has_source_dir(self.build_dir) - # If a checkout exists, it's unwise to keep going. version - # inconsistencies are logged later, but do not fail the - # installation. - # FIXME: this won't upgrade when there's an existing - # package unpacked in `req.source_dir` - # package unpacked in `req.source_dir` - if os.path.exists(os.path.join(req.source_dir, 'setup.py')): - raise PreviousBuildDirError( - "pip can't proceed with requirements '%s' due to a" - " pre-existing build directory (%s). This is " - "likely due to a previous installation that failed" - ". pip is being responsible and not assuming it " - "can delete this. Please delete it and try again." - % (req, req.source_dir) - ) - req.populate_link(finder, upgrade_allowed, require_hashes) - - # We can't hit this spot and have populate_link return None. - # req.satisfied_by is None here (because we're - # guarded) and upgrade has no impact except when satisfied_by - # is not None. - # Then inside find_requirement existing_applicable -> False - # If no new versions are found, DistributionNotFound is raised, - # otherwise a result is guaranteed. - assert req.link - link = req.link - - # Now that we have the real link, we can tell what kind of - # requirements we have and raise some more informative errors - # than otherwise. (For example, we can raise VcsHashUnsupported - # for a VCS URL rather than HashMissing.) - if require_hashes: - # We could check these first 2 conditions inside - # unpack_url and save repetition of conditions, but then - # we would report less-useful error messages for - # unhashable requirements, complaining that there's no - # hash provided. - if is_vcs_url(link): - raise VcsHashUnsupported() - elif is_file_url(link) and is_dir_url(link): - raise DirectoryUrlHashUnsupported() - if not req.original_link and not req.is_pinned: - # Unpinned packages are asking for trouble when a new - # version is uploaded. This isn't a security check, but - # it saves users a surprising hash mismatch in the - # future. - # - # file:/// URLs aren't pinnable, so don't complain - # about them not being pinned. - raise HashUnpinned() - - hashes = req.hashes(trust_internet=not require_hashes) - if require_hashes and not hashes: - # Known-good hashes are missing for this requirement, so - # shim it with a facade object that will provoke hash - # computation and then raise a HashMissing exception - # showing the user what the hash should be. - hashes = MissingHashes() - + self._ensure_link_req_src_dir(req, download_dir, parallel_builds) try: - download_dir = self.download_dir - # We always delete unpacked sdists after pip ran. - autodelete_unpacked = True - if req.link.is_wheel and self.wheel_download_dir: - # when doing 'pip wheel` we download wheels to a - # dedicated dir. - download_dir = self.wheel_download_dir - if req.link.is_wheel: - if download_dir: - # When downloading, we only unpack wheels to get - # metadata. - autodelete_unpacked = True - else: - # When installing a wheel, we use the unpacked - # wheel. - autodelete_unpacked = False - unpack_url( - req.link, req.source_dir, - download_dir, autodelete_unpacked, - session=session, hashes=hashes, - progress_bar=self.progress_bar - ) - except requests.HTTPError as exc: - logger.critical( - 'Could not install requirement %s because of error %s', - req, - exc, + local_file = unpack_url( + link, req.source_dir, self.downloader, download_dir, + hashes=self._get_linked_req_hashes(req) ) + except NetworkConnectionError as exc: raise InstallationError( - 'Could not install requirement %s because of HTTP ' - 'error %s for URL %s' % - (req, exc, req.link) - ) - abstract_dist = make_distribution_for_install_requirement(req) - with self.req_tracker.track(req): - abstract_dist.prepare_distribution_metadata( - finder, self.build_isolation, + 'Could not install requirement {} because of HTTP ' + 'error {} for URL {}'.format(req, exc, link) ) + + # For use in later processing, preserve the file path on the + # requirement. + if local_file: + req.local_file_path = local_file.path + + abstract_dist = _get_prepared_distribution( + req, self.req_tracker, self.finder, self.build_isolation, + ) + + if download_dir: + if link.is_existing_dir(): + logger.info('Link is a directory, ignoring download_dir') + elif local_file: + download_location = os.path.join( + download_dir, link.filename + ) + if not os.path.exists(download_location): + shutil.copy(local_file.path, download_location) + download_path = display_path(download_location) + logger.info('Saved %s', download_path) + if self._download_should_save: # Make a .zip of the source_dir we already created. - if not req.link.is_artifact: + if link.is_vcs: req.archive(self.download_dir) return abstract_dist def prepare_editable_requirement( self, req, # type: InstallRequirement - require_hashes, # type: bool - use_user_site, # type: bool - finder # type: PackageFinder ): # type: (...) -> AbstractDistribution """Prepare an editable requirement @@ -235,31 +513,28 @@ class RequirementPreparer(object): logger.info('Obtaining %s', req) with indent_log(): - if require_hashes: + if self.require_hashes: raise InstallationError( - 'The editable requirement %s cannot be installed when ' + 'The editable requirement {} cannot be installed when ' 'requiring hashes, because there is no single file to ' - 'hash.' % req + 'hash.'.format(req) ) req.ensure_has_source_dir(self.src_dir) req.update_editable(not self._download_should_save) - abstract_dist = make_distribution_for_install_requirement(req) - with self.req_tracker.track(req): - abstract_dist.prepare_distribution_metadata( - finder, self.build_isolation, - ) + abstract_dist = _get_prepared_distribution( + req, self.req_tracker, self.finder, self.build_isolation, + ) if self._download_should_save: req.archive(self.download_dir) - req.check_if_exists(use_user_site) + req.check_if_exists(self.use_user_site) return abstract_dist def prepare_installed_requirement( self, req, # type: InstallRequirement - require_hashes, # type: bool skip_reason # type: str ): # type: (...) -> AbstractDistribution @@ -268,14 +543,14 @@ class RequirementPreparer(object): assert req.satisfied_by, "req should have been satisfied but isn't" assert skip_reason is not None, ( "did not get skip reason skipped but req.satisfied_by " - "is set to %r" % (req.satisfied_by,) + "is set to {}".format(req.satisfied_by) ) logger.info( 'Requirement %s: %s (%s)', skip_reason, req, req.satisfied_by.version ) with indent_log(): - if require_hashes: + if self.require_hashes: logger.debug( 'Since it is already installed, we are trusting this ' 'package without checking its hash. To ensure a ' diff --git a/venv/lib/python3.8/site-packages/pip/_internal/pep425tags.py b/venv/lib/python3.8/site-packages/pip/_internal/pep425tags.py deleted file mode 100644 index c6e58bf..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/pep425tags.py +++ /dev/null @@ -1,384 +0,0 @@ -"""Generate and work with PEP 425 Compatibility Tags.""" -from __future__ import absolute_import - -import distutils.util -import logging -import platform -import re -import sys -import sysconfig -import warnings -from collections import OrderedDict - -import pip._internal.utils.glibc -from pip._internal.utils.compat import get_extension_suffixes -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import ( - Tuple, Callable, List, Optional, Union, Dict - ) - - Pep425Tag = Tuple[str, str, str] - -logger = logging.getLogger(__name__) - -_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') - - -def get_config_var(var): - # type: (str) -> Optional[str] - try: - return sysconfig.get_config_var(var) - except IOError as e: # Issue #1074 - warnings.warn("{}".format(e), RuntimeWarning) - return None - - -def get_abbr_impl(): - # type: () -> str - """Return abbreviated implementation name.""" - if hasattr(sys, 'pypy_version_info'): - pyimpl = 'pp' - elif sys.platform.startswith('java'): - pyimpl = 'jy' - elif sys.platform == 'cli': - pyimpl = 'ip' - else: - pyimpl = 'cp' - return pyimpl - - -def version_info_to_nodot(version_info): - # type: (Tuple[int, ...]) -> str - # Only use up to the first two numbers. - return ''.join(map(str, version_info[:2])) - - -def get_impl_ver(): - # type: () -> str - """Return implementation version.""" - impl_ver = get_config_var("py_version_nodot") - if not impl_ver or get_abbr_impl() == 'pp': - impl_ver = ''.join(map(str, get_impl_version_info())) - return impl_ver - - -def get_impl_version_info(): - # type: () -> Tuple[int, ...] - """Return sys.version_info-like tuple for use in decrementing the minor - version.""" - if get_abbr_impl() == 'pp': - # as per https://github.com/pypa/pip/issues/2882 - # attrs exist only on pypy - return (sys.version_info[0], - sys.pypy_version_info.major, # type: ignore - sys.pypy_version_info.minor) # type: ignore - else: - return sys.version_info[0], sys.version_info[1] - - -def get_impl_tag(): - # type: () -> str - """ - Returns the Tag for this specific implementation. - """ - return "{}{}".format(get_abbr_impl(), get_impl_ver()) - - -def get_flag(var, fallback, expected=True, warn=True): - # type: (str, Callable[..., bool], Union[bool, int], bool) -> bool - """Use a fallback method for determining SOABI flags if the needed config - var is unset or unavailable.""" - val = get_config_var(var) - if val is None: - if warn: - logger.debug("Config variable '%s' is unset, Python ABI tag may " - "be incorrect", var) - return fallback() - return val == expected - - -def get_abi_tag(): - # type: () -> Optional[str] - """Return the ABI tag based on SOABI (if available) or emulate SOABI - (CPython 2, PyPy).""" - soabi = get_config_var('SOABI') - impl = get_abbr_impl() - if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'): - d = '' - m = '' - u = '' - is_cpython = (impl == 'cp') - if get_flag( - 'Py_DEBUG', lambda: hasattr(sys, 'gettotalrefcount'), - warn=is_cpython): - d = 'd' - if sys.version_info < (3, 8) and get_flag( - 'WITH_PYMALLOC', lambda: is_cpython, warn=is_cpython): - m = 'm' - if sys.version_info < (3, 3) and get_flag( - 'Py_UNICODE_SIZE', lambda: sys.maxunicode == 0x10ffff, - expected=4, warn=is_cpython): - u = 'u' - abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u) - elif soabi and soabi.startswith('cpython-'): - abi = 'cp' + soabi.split('-')[1] - elif soabi: - abi = soabi.replace('.', '_').replace('-', '_') - else: - abi = None - return abi - - -def _is_running_32bit(): - # type: () -> bool - return sys.maxsize == 2147483647 - - -def get_platform(): - # type: () -> str - """Return our platform name 'win32', 'linux_x86_64'""" - if sys.platform == 'darwin': - # distutils.util.get_platform() returns the release based on the value - # of MACOSX_DEPLOYMENT_TARGET on which Python was built, which may - # be significantly older than the user's current machine. - release, _, machine = platform.mac_ver() - split_ver = release.split('.') - - if machine == "x86_64" and _is_running_32bit(): - machine = "i386" - elif machine == "ppc64" and _is_running_32bit(): - machine = "ppc" - - return 'macosx_{}_{}_{}'.format(split_ver[0], split_ver[1], machine) - - # XXX remove distutils dependency - result = distutils.util.get_platform().replace('.', '_').replace('-', '_') - if result == "linux_x86_64" and _is_running_32bit(): - # 32 bit Python program (running on a 64 bit Linux): pip should only - # install and run 32 bit compiled extensions in that case. - result = "linux_i686" - - return result - - -def is_manylinux1_compatible(): - # type: () -> bool - # Only Linux, and only x86-64 / i686 - if get_platform() not in {"linux_x86_64", "linux_i686"}: - return False - - # Check for presence of _manylinux module - try: - import _manylinux - return bool(_manylinux.manylinux1_compatible) - except (ImportError, AttributeError): - # Fall through to heuristic check below - pass - - # Check glibc version. CentOS 5 uses glibc 2.5. - return pip._internal.utils.glibc.have_compatible_glibc(2, 5) - - -def is_manylinux2010_compatible(): - # type: () -> bool - # Only Linux, and only x86-64 / i686 - if get_platform() not in {"linux_x86_64", "linux_i686"}: - return False - - # Check for presence of _manylinux module - try: - import _manylinux - return bool(_manylinux.manylinux2010_compatible) - except (ImportError, AttributeError): - # Fall through to heuristic check below - pass - - # Check glibc version. CentOS 6 uses glibc 2.12. - return pip._internal.utils.glibc.have_compatible_glibc(2, 12) - - -def get_darwin_arches(major, minor, machine): - # type: (int, int, str) -> List[str] - """Return a list of supported arches (including group arches) for - the given major, minor and machine architecture of an macOS machine. - """ - arches = [] - - def _supports_arch(major, minor, arch): - # type: (int, int, str) -> bool - # Looking at the application support for macOS versions in the chart - # provided by https://en.wikipedia.org/wiki/OS_X#Versions it appears - # our timeline looks roughly like: - # - # 10.0 - Introduces ppc support. - # 10.4 - Introduces ppc64, i386, and x86_64 support, however the ppc64 - # and x86_64 support is CLI only, and cannot be used for GUI - # applications. - # 10.5 - Extends ppc64 and x86_64 support to cover GUI applications. - # 10.6 - Drops support for ppc64 - # 10.7 - Drops support for ppc - # - # Given that we do not know if we're installing a CLI or a GUI - # application, we must be conservative and assume it might be a GUI - # application and behave as if ppc64 and x86_64 support did not occur - # until 10.5. - # - # Note: The above information is taken from the "Application support" - # column in the chart not the "Processor support" since I believe - # that we care about what instruction sets an application can use - # not which processors the OS supports. - if arch == 'ppc': - return (major, minor) <= (10, 5) - if arch == 'ppc64': - return (major, minor) == (10, 5) - if arch == 'i386': - return (major, minor) >= (10, 4) - if arch == 'x86_64': - return (major, minor) >= (10, 5) - if arch in groups: - for garch in groups[arch]: - if _supports_arch(major, minor, garch): - return True - return False - - groups = OrderedDict([ - ("fat", ("i386", "ppc")), - ("intel", ("x86_64", "i386")), - ("fat64", ("x86_64", "ppc64")), - ("fat32", ("x86_64", "i386", "ppc")), - ]) # type: Dict[str, Tuple[str, ...]] - - if _supports_arch(major, minor, machine): - arches.append(machine) - - for garch in groups: - if machine in groups[garch] and _supports_arch(major, minor, garch): - arches.append(garch) - - arches.append('universal') - - return arches - - -def get_all_minor_versions_as_strings(version_info): - # type: (Tuple[int, ...]) -> List[str] - versions = [] - major = version_info[:-1] - # Support all previous minor Python versions. - for minor in range(version_info[-1], -1, -1): - versions.append(''.join(map(str, major + (minor,)))) - return versions - - -def get_supported( - versions=None, # type: Optional[List[str]] - noarch=False, # type: bool - platform=None, # type: Optional[str] - impl=None, # type: Optional[str] - abi=None # type: Optional[str] -): - # type: (...) -> List[Pep425Tag] - """Return a list of supported tags for each version specified in - `versions`. - - :param versions: a list of string versions, of the form ["33", "32"], - or None. The first version will be assumed to support our ABI. - :param platform: specify the exact platform you want valid - tags for, or None. If None, use the local system platform. - :param impl: specify the exact implementation you want valid - tags for, or None. If None, use the local interpreter impl. - :param abi: specify the exact abi you want valid - tags for, or None. If None, use the local interpreter abi. - """ - supported = [] - - # Versions must be given with respect to the preference - if versions is None: - version_info = get_impl_version_info() - versions = get_all_minor_versions_as_strings(version_info) - - impl = impl or get_abbr_impl() - - abis = [] # type: List[str] - - abi = abi or get_abi_tag() - if abi: - abis[0:0] = [abi] - - abi3s = set() - for suffix in get_extension_suffixes(): - if suffix.startswith('.abi'): - abi3s.add(suffix.split('.', 2)[1]) - - abis.extend(sorted(list(abi3s))) - - abis.append('none') - - if not noarch: - arch = platform or get_platform() - arch_prefix, arch_sep, arch_suffix = arch.partition('_') - if arch.startswith('macosx'): - # support macosx-10.6-intel on macosx-10.9-x86_64 - match = _osx_arch_pat.match(arch) - if match: - name, major, minor, actual_arch = match.groups() - tpl = '{}_{}_%i_%s'.format(name, major) - arches = [] - for m in reversed(range(int(minor) + 1)): - for a in get_darwin_arches(int(major), m, actual_arch): - arches.append(tpl % (m, a)) - else: - # arch pattern didn't match (?!) - arches = [arch] - elif arch_prefix == 'manylinux2010': - # manylinux1 wheels run on most manylinux2010 systems with the - # exception of wheels depending on ncurses. PEP 571 states - # manylinux1 wheels should be considered manylinux2010 wheels: - # https://www.python.org/dev/peps/pep-0571/#backwards-compatibility-with-manylinux1-wheels - arches = [arch, 'manylinux1' + arch_sep + arch_suffix] - elif platform is None: - arches = [] - if is_manylinux2010_compatible(): - arches.append('manylinux2010' + arch_sep + arch_suffix) - if is_manylinux1_compatible(): - arches.append('manylinux1' + arch_sep + arch_suffix) - arches.append(arch) - else: - arches = [arch] - - # Current version, current API (built specifically for our Python): - for abi in abis: - for arch in arches: - supported.append(('%s%s' % (impl, versions[0]), abi, arch)) - - # abi3 modules compatible with older version of Python - for version in versions[1:]: - # abi3 was introduced in Python 3.2 - if version in {'31', '30'}: - break - for abi in abi3s: # empty set if not Python 3 - for arch in arches: - supported.append(("%s%s" % (impl, version), abi, arch)) - - # Has binaries, does not use the Python API: - for arch in arches: - supported.append(('py%s' % (versions[0][0]), 'none', arch)) - - # No abi / arch, but requires our implementation: - supported.append(('%s%s' % (impl, versions[0]), 'none', 'any')) - # Tagged specifically as being cross-version compatible - # (with just the major version specified) - supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any')) - - # No abi / arch, generic Python - for i, version in enumerate(versions): - supported.append(('py%s' % (version,), 'none', 'any')) - if i == 0: - supported.append(('py%s' % (version[0]), 'none', 'any')) - - return supported - - -implementation_tag = get_impl_tag() diff --git a/venv/lib/python3.8/site-packages/pip/_internal/pyproject.py b/venv/lib/python3.8/site-packages/pip/_internal/pyproject.py index 43efbed..6b4faf7 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/pyproject.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/pyproject.py @@ -3,14 +3,16 @@ from __future__ import absolute_import import io import os import sys +from collections import namedtuple -from pip._vendor import pytoml, six +from pip._vendor import six, toml +from pip._vendor.packaging.requirements import InvalidRequirement, Requirement from pip._internal.exceptions import InstallationError from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: - from typing import Any, Tuple, Optional, List + from typing import Any, Optional, List def _is_list_of_str(obj): @@ -21,9 +23,9 @@ def _is_list_of_str(obj): ) -def make_pyproject_path(setup_py_dir): +def make_pyproject_path(unpacked_source_directory): # type: (str) -> str - path = os.path.join(setup_py_dir, 'pyproject.toml') + path = os.path.join(unpacked_source_directory, 'pyproject.toml') # Python2 __file__ should not be unicode if six.PY2 and isinstance(path, six.text_type): @@ -32,13 +34,18 @@ def make_pyproject_path(setup_py_dir): return path +BuildSystemDetails = namedtuple('BuildSystemDetails', [ + 'requires', 'backend', 'check', 'backend_path' +]) + + def load_pyproject_toml( use_pep517, # type: Optional[bool] pyproject_toml, # type: str setup_py, # type: str req_name # type: str ): - # type: (...) -> Optional[Tuple[List[str], str, List[str]]] + # type: (...) -> Optional[BuildSystemDetails] """Load the pyproject.toml file. Parameters: @@ -56,6 +63,8 @@ def load_pyproject_toml( name of PEP 517 backend, requirements we should check are installed after setting up the build environment + directory paths to import the backend from (backend-path), + relative to the project root. ) """ has_pyproject = os.path.isfile(pyproject_toml) @@ -63,7 +72,7 @@ def load_pyproject_toml( if has_pyproject: with io.open(pyproject_toml, encoding="utf-8") as f: - pp_toml = pytoml.load(f) + pp_toml = toml.load(f) build_system = pp_toml.get("build-system") else: build_system = None @@ -150,7 +159,23 @@ def load_pyproject_toml( reason="'build-system.requires' is not a list of strings.", )) + # Each requirement must be valid as per PEP 508 + for requirement in requires: + try: + Requirement(requirement) + except InvalidRequirement: + raise InstallationError( + error_template.format( + package=req_name, + reason=( + "'build-system.requires' contains an invalid " + "requirement: {!r}".format(requirement) + ), + ) + ) + backend = build_system.get("build-backend") + backend_path = build_system.get("backend-path", []) check = [] # type: List[str] if backend is None: # If the user didn't specify a backend, we assume they want to use @@ -168,4 +193,4 @@ def load_pyproject_toml( backend = "setuptools.build_meta:__legacy__" check = ["setuptools>=40.8.0", "wheel"] - return (requires, backend, check) + return BuildSystemDetails(requires, backend, check, backend_path) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__init__.py b/venv/lib/python3.8/site-packages/pip/_internal/req/__init__.py index c39f63f..8568d3f 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/req/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/req/__init__.py @@ -1,15 +1,17 @@ from __future__ import absolute_import +import collections import logging -from .req_install import InstallRequirement -from .req_set import RequirementSet -from .req_file import parse_requirements from pip._internal.utils.logging import indent_log from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from .req_file import parse_requirements +from .req_install import InstallRequirement +from .req_set import RequirementSet + if MYPY_CHECK_RUNNING: - from typing import Any, List, Sequence + from typing import Iterator, List, Optional, Sequence, Tuple __all__ = [ "RequirementSet", "InstallRequirement", @@ -19,60 +21,83 @@ __all__ = [ logger = logging.getLogger(__name__) -def install_given_reqs( - to_install, # type: List[InstallRequirement] - install_options, # type: List[str] - global_options=(), # type: Sequence[str] - *args, # type: Any - **kwargs # type: Any +class InstallationResult(object): + def __init__(self, name): + # type: (str) -> None + self.name = name + + def __repr__(self): + # type: () -> str + return "InstallationResult(name={!r})".format(self.name) + + +def _validate_requirements( + requirements, # type: List[InstallRequirement] ): - # type: (...) -> List[InstallRequirement] + # type: (...) -> Iterator[Tuple[str, InstallRequirement]] + for req in requirements: + assert req.name, "invalid to-be-installed requirement: {}".format(req) + yield req.name, req + + +def install_given_reqs( + requirements, # type: List[InstallRequirement] + install_options, # type: List[str] + global_options, # type: Sequence[str] + root, # type: Optional[str] + home, # type: Optional[str] + prefix, # type: Optional[str] + warn_script_location, # type: bool + use_user_site, # type: bool + pycompile, # type: bool +): + # type: (...) -> List[InstallationResult] """ Install everything in the given list. (to be called after having downloaded and unpacked the packages) """ + to_install = collections.OrderedDict(_validate_requirements(requirements)) if to_install: logger.info( 'Installing collected packages: %s', - ', '.join([req.name for req in to_install]), + ', '.join(to_install.keys()), ) + installed = [] + with indent_log(): - for requirement in to_install: - if requirement.conflicts_with: - logger.info( - 'Found existing installation: %s', - requirement.conflicts_with, - ) + for req_name, requirement in to_install.items(): + if requirement.should_reinstall: + logger.info('Attempting uninstall: %s', req_name) with indent_log(): uninstalled_pathset = requirement.uninstall( auto_confirm=True ) + else: + uninstalled_pathset = None + try: requirement.install( install_options, global_options, - *args, - **kwargs + root=root, + home=home, + prefix=prefix, + warn_script_location=warn_script_location, + use_user_site=use_user_site, + pycompile=pycompile, ) except Exception: - should_rollback = ( - requirement.conflicts_with and - not requirement.install_succeeded - ) # if install did not succeed, rollback previous uninstall - if should_rollback: + if uninstalled_pathset and not requirement.install_succeeded: uninstalled_pathset.rollback() raise else: - should_commit = ( - requirement.conflicts_with and - requirement.install_succeeded - ) - if should_commit: + if uninstalled_pathset and requirement.install_succeeded: uninstalled_pathset.commit() - requirement.remove_temporary_source() - return to_install + installed.append(InstallationResult(req_name)) + + return installed diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/__init__.cpython-38.pyc index 9047918e4ae6c946cdd16db4ce47f1395398f735..152a0a49bdd69cfcc8246ad8f3479b74964ccffc 100644 GIT binary patch literal 2476 zcmaJ?&2tn*6z`s$-JPBNNU{mvpo>D0EoJv$S!GdRK>;Eq1`QxEr8Q2bdp8s2E8RUI z39}c%mGWQMT&(iy!2>7%2v2?W#MP7K0ex?>8v<JPRKMwd{kmVj-}~r$&8AJDbzi-3 zFEt4H9VZ8y36smv<<CGEVKgKWbtuKL5gLwB{7X&={-w~2%1*ghGs8+$b*eBfvr1@1 zHK$gLtDzm$oq930!ba3|nw0RW*o6JHuocZXGtsOw8_hX$QQK)p^UgfT+N{nRtT{BD z1zs8-;)i#sbL0kLEjIIvuo-@Ir{o-Cvuy4eagMV#Yr_8oGwzV?{7bku=~6x8t;i(I z6nBFtO@vwko*l%D$I1<pA<WueKK$yTd-e0{SHEzV?=3CeT)Od+?rm<To{-!Xd_4;U zk6@3)4L4({yf9pT%?57k!1NAR-LkfBDlR;g2yNa9q|(;yR0T=wh1$9UTY2nrUA~*8 zAr}_t6ICP?Ai5pwX>f<Z29Hs{^nw3IGhlWZx;zPl6NfSaUZKnY3`(rTO!%9u3|Lh5 zZ|tG|WiGQ&`M7`DaE$#bbcunH)10{AYuHT@F*Eie-Ziu-c{mWWAn_9sZTS85eSbBH zcwcN~*;>$-!tXOL4tVGT)?D^Bx3>FW!bU#~R{H6dT211QdY|-Vp!oUJ^B;LbF8gVa z_T3-`v;dqwSlf4D8YtK8rCZvXPLAR2ifbF&Cni2PU{P->=cD(g4aX(ug=rA!5Xxhc zlQp_a!8l`S`_#WrT10CvJvl8#U9h<_NJQkR!s;#+b8tps`W~5wDPB?VRJiUbnEn41 z_vDr^JX{y`xURNcH%eF*;<(|u>zNnst%wCwcKA(=2)jVFVg|@j=n}KlqLx{3-Y_5G zDnrNckv$+exkkP_Gom?NgV0eF;4pFkV~0L1csU&y-w;aH&BFTt(77Pq@WOy~RC0cW zpPz }|VG%YT4o{YMs0wUeIA|)3XY1f5Fgg69R0mjAwaj8o%dmF{WZlTA6Ts<iJ z9$p>Of|wRvpaL=WYdD{@7W~n(g^T}yfg)q7jGXL%U87oF6N{=eHZeEG<-9ho?2=u& zYfv&IBU@E>$Pd3z0(@&1vH9^^V^kkC^2S<CY!v%Sc^#z-$u>wf)@%lu^_-5H_sPfP zYqCrpkl19EQFHqpSgk|$7<nl-^KxFvtGUIh&n-&slX%f2s`1DczfwRLPHKu5Am5ZP z^5(d;3!JCqA&D0r;L2~f0<<}v!Ij(|&#Jk+jy8dJF22^B+Yrdsc4l{=O@g_@H@JXo z3*uoXh&yVPcZyQd384`6>_T)=C7l)C@u8A|Gra+%UuV_Zz%49!9EXX=kRP*77GtWy z1kagfZMQgN`}9O3Zu1j3%2yyb6}r$lE4PggJKIOED8(bFe;}5{lNiF)yHH&kUZxV) zPvSu!q9v$TrbrT{O{^@sk_tWuHub_|PsFbDMUZ0U_KVEd%?#=@bm3x2(Y18TPogvk zdAF_Wllwp<N?pG#7#Eyf3w%|Ckgh=aA95(pK|Dybxt0X6HXrdVDX?DXGMpDlJu6p} zEMyRolS}K`{{3}zpLc!J=S6kba}%B`GvDVNFw~X+U{(M^U4h$0fzlN(O?k|UeC@Wx z2~;>U-Ix>yN!=QT$%+@cleu^oq(leFX(X5z;(a7%fM^>a+`rCbQ0V6CMV-<014*Ul z_l@ApO+B?Lxq2%f1?JTU(B)@9$Xv@XsYwmmcx9GN!=kgaLL1aV-rsH0G>l@^0EzwY zPup%8Hpo~=jpIi5Bo@0trZNG=PGEHsXMyM{Is<}3pMb}pxBnRQG8KffH(A_s%<=z{ zP+KYN7FY-YZZLTOF|hZTqTN$uiZ@nQk%I=~v#TqUy;xENK7OK(1S^VY0?}31g&cv} zTpMzAs|Xr#1Xs`DY9(1&gP<>5Sp-&r+W{>1>$SEn?v?pZ@llfKwFcm584cRN4%DP4 RO9lb_hyf_urCHmm{R3+poHGCb literal 1697 zcmZuyOK%)S5bo~jot+);!`_&H!hzwyW2Iyr@wk9xfkJ?YU`R}qc%;x8PxtPQJ&$!y zk6#*JNRB+jg(F%^TtFN+@eBABEp8l8{sJO~>e*e}67;HTs;aB1tG}x5z1M2F2*#g# zzkI&hK<E!6TpSdHcVOmU0^x|`7$w-p*zhDKKH(Opv6WDtg3jW#xR%(yUGa8YPaNN= zZ0m6&aecSqop>Q>`b~^PQ;r}`BW@*aznygaPO|7Pf{n`;c$2q=)L#;0(iN9Zu)oX~ zd55<iWB(aWHc)Tr31ozNSa*W0Jc|n@Sd@%2sn(z1=|cBbnyVm=?~2_bk|GhQ0`v9- zaYGnQcO1xEFnMm4gVv2w4jwGdhQ{XO%}+PkjSp|$_=w%Tx4wRB{ezyRt#{KyO>alJ z(#{6Bi!>Cn2D?jxo3w%GZZyq;4Wm7gnqBfAQE0)^d;sof0p=$#^WTA#NO}rQFvpxs zDuf?{?mhGfpWqXMk+L44Z+^y=?&0LPR@Szu+^Re({>-KeHnr^<w|V_5d~DxGZ=yTs zE_#5Do&&vI;*tzVX?;&h`Zd(_K1#1sr0P4a{0SrTGm*3JfI3ZdTrcbLhti%jPGIE= zw29Iy52hBs8jEA6bmVWa?wa+oHd!#=-K*!jmI&(R92KqyV^$nb><M|OMo~KSqSR9( z;Z;C+F`(LaE7Mn1=4}Ztgjx#j1p_6dHwyNQ3(xk`I19MZr`#*jaS-l+VB#1y7>c}C z1vz?gwxe+iGYAzbFq|8`<-L?2k*i*4nrA);Fs4!)F!L^uAz=Q{J;o*8M&FWMx`AX1 z)X*R_4HD5Kn)I)03yNInEArRdD=HbUjHB_jSu0$7ZS+QQ@Ol;)Wi?rp!lBY2UIEt? z24bWb>yHn$yJ~<4vt+#Xipjz>mW>EHdilS7)nAP>04ZMsX6|(K!uweP$cO{bOhK+L zMWCWAHHZETl5Ylu%2=4CgGeU5rnaH!heB!^rGre<?JP=V9X8f&V-rWA%GrLTM!Hd? zvov&l&NOZwgko&M>!o>)c@c&}K$Wy30s1YdjJDxWNu>0%a5b|%!IUu9H;{)c&k7le zUPHT()jVux9xJP2=ej+Nv#lUzbD0Kmm}`4yzxpm*xX$|0S(<{gaiB)IP`Z<kvLfc} zETPs+G0p3|fN}|rE}K9u!_3!#pf<%66Wl$eH3vJ`t|WR&sbjc*7A;a~$SJYNQ$oq# zj@>3Uwogfog1uvb$0?zPUnV^~?V`)tWo%HWLJG#DX+B*ym4LEobDlXC)$5|`Mgs?_ z9vr|Gq(Kym>8tZRbXNbYtNMkC;=DhLH7(_p|FcksW7teOW@~#UnCD5Fe+g+GDP3m_ z?jd8kF%;_dv`-wyO#4I9%f`+?bpbweLn;ilvzlbQh{c+@WVr{VNgUF|vmc>&*&>Kw Lm;kJ6qo@A@L!{h+ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/constructors.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/constructors.cpython-38.pyc index 94eed9c23e15f260eb45465c87e8c78686251186..3ae73f3f9dab2ca2ccc2bc0a763ff16144ef7269 100644 GIT binary patch literal 11262 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 Nq~E`_UgFsQ{vW+h;3fb7 delta 4294 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 Hu7C1B`(*~^ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_file.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_file.cpython-38.pyc index 7f45de88b93f60ba03161939422b44f39dc4a254..7c3717ea40b083d63a356021fc66f4b004423d94 100644 GIT binary patch literal 13228 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 literal 9374 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 Fe*wNfU335d diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_install.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_install.cpython-38.pyc index 7ae4ee6194e784c47d27b4a4f1adf418149c85a7..03be2c7a3156fe4c9775a93848e887ae938f77bc 100644 GIT binary patch literal 21487 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 H|F{1?{>KO^ literal 25727 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_set.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_set.cpython-38.pyc index ac68ddc34162aecb4833c35a22ee3761f8f7944c..ade8ce0c0f562c179446b081cf1698517f7fe40e 100644 GIT binary patch literal 5860 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 To{EJ(gf;wGj(O3n*k${Fsl^Yp literal 5690 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-38.pyc index 09d0b2d7e1d5b138d9aaee9bda985b8751c5f8f3..7ccf6919ddffbdf29f6c6cecca4c262fb17456e3 100644 GIT binary patch literal 4118 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 XISr(<2GUuBw=mG0x*m@%V$A#>%18qQ literal 3222 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 Hs`mc@_(>FM diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-38.pyc index 1705189b6eae81b9cbc105a019b1b0cc14e243cb..b92d7c8364d8ef3da45069df413cea3822716986 100644 GIT binary patch delta 1899 zcmYLJYiv|i5I%G6WA8q?EcCT4-Lj=Ec6saqRpe1hkwy{J6oHf`1zdW!?QXZbc=l51 za+fAnEtp`T2ZacMT?Bs^#E^?G65}5shzSYm53@#tKMa3-p#Bj|sB>-$+|8MtGjnFn z%y(wy${2ie0K8jEN?ZiL(EZCh-|fEW{aaoai}a@lV-YsIXHOy?$*`V?9!<q#$(}Sb zVwv#X;cR3mmKusA<GUiehmHPpsyVzol8GC!MZ2Rt1JS-%hSw@f;W55R`4iUgwQ3Kn zw$7<1C~UCSI-L}fe4~2;c3D5WyC~%Na_<=!;XitFFv`1ToQDHk^_g%OX(uoG%3*@v z@!f$T>zA1+39efm<rM&@tiFna0N?Y!D%U^VjtOKv1~Fk2a<r4AYGq=;fQ!usB7O$d zL8pgM*F{ov8!@R#5|SY&l)P#}0a{R!Q24n2Q`N!B&>7!SwY~BuWHKHk#6iIWUhu&z znq9~zE35dgRg2&<FRgBYH+V;N`$F_5o3w=(BmsGc2_`MjoMI~MlBoz;LK~3SC0py{ z*Q(Eeix13h;>Tw<tK)b9o8UKR*Q>vY8|U(Svje=UrgcQdtyt@XIElozry}CC-{vL3 zdq|F&l+8CuUKabDlyV`jOz{|*YDXmX(gFZx%63fqkqRLAyk;VYC^<21X_Vp_X)_4{ z%^u=6YT8HEM^kz-7R(F}CgZ7rOfZ@W_QsR3OwdRNqeJPq9vn>T@!sKhsxN5tKRg&T zqO31wWWuiC^cQlmI?RI2MN(Aa89mO5YCI#nvcp30jv!-#G}uSjARggu0o5<FgF<Xu zx_3v7{+;p6PNCcs2nIAjd}g7ZDAgc?hq|Z_e5wmvkPYB-`T5zvhcJ#1muhNHdT=mq z)bhdF4RDozR@?B*@ot)<IVrovfV`w5ln94}a7>j4f|lv9c?Ui!ux>*}z-%Z}WwzXD z%Xjn2If1HAfaGK#*&6g!qD!I-&=dOQ&(FD($YY418Fq$6HJR?~i?N~{PxYpYiXPjw zr|%IwEQ?3kaU?}`Ps&E<n2?kTB2r~<37rySEX~+y<U`67L_37?1WyMWE9MDYYH&{^ z7x<_bC>F7we-JzbEBW%eUf(0oPYSEk{6gL0@|(!oXlfu+&8f}MYP1ULpSm%Cb$nm_ zzp&9V8lD6=%Fj0jU<<$AI0^mM^?7$eEeJ1X_}5J@z)9{8nZT^KLvKEmH!f&_W7e(( zO8_RUqYGQ1+%`BTtQrORV#@yZqNQ+=SBF1RMPlp#kFF_I1pB3RJNzB>=G~^(goId7 zkgRJ<J_opIz1qAL;I8$<<BNgr%W>DTdCq;gU{llx;%>#Vq3P(XkCz!#{YpS{gGW}3 zdt^$n%jElXQdaoY6-VGS-?lOgZG3Fy>->+o&U!!IjGaMt;zN!S{HMC0l1?@g7Di=A z<`b))nz@0ZPZjrss-Qu(h97Ay<Ir-Yv_oh#TjOz+;Vj8k+PdFc0wXSr1bYy4ydg1F zE>c3q?iD-8gi)trQBLc`orXi~bnMjevK*L@*9!Ioz?ht!<O#BgyhyeY!==l*@*4Jg zI~m2f$dbB>lR?%UIV?+d%A~qhMe-wVQ_6dEX8{LCW?J|_Qi;a8hQpC0O4`Zx)|{Me zutRm3vZ!m5=DntDN|oe+2Oyo~<+C_^XW;O?H8p&@P_hlzbl7eT+h>RE6MZvFm^_GC zWEb-Ad#i)|xmAmKb!$JQ_-Jci(@bVp%6kYQ`%jQMLBuq$8>Q%YCCXAbfB3!D{r;B( z+TvXZ^-5kG2>8B}vLsutt?@y%?Z_@U+mY?^mT=_e7uxD!KmWFEc;>SY9!vvG)qGkl z?_N9CS#*e=#cQn5weJHI`22Ny>)k#aI4UfZaO_B0g;qkrRjHL}O<J=r?HeH@#Qi^b CZ0%eC delta 1780 zcmZ8heQZ-z6u;-bkG^(YS4P)$AC+y4L7lKUwxVMW#%4nNSd@WmDlCQ9Z7o|{Z{Ox@ zUbo=TiSjjW48|qcPB2DIM4ySlfbk<F3TiYa{;@v{{6#cIiT<I+Kjyiw1B`9%dFP&c z&ON_#?m6em3vg)`JiCgET?BvEC(iBddi*`l@A4g6n~bqkQ!18PA4{Z-$mr<$mXX%+ z$&JZ~5b|!N1#0+&@*CX4ht&NLwl1sl6uPY;r;|dIr;1L(6PDy2pfJJrcotytWJwlG zK2`D#9OR8&6AmNY&6m7o@DeXuaRZW;TAGmHb8EcJ4{*vl;y(=VHTMU$KeiL0WqbxP zVFt3)q&dhFAiGJTK_&)0;9~87dmx6SgHDhBM`wT}Xg@KjN#e4h#MPX`ggkVhB(Cx^ zfe$?z^Wo)->V6iD7*QUn*yH~J1!*r5;-H{`8$93w5C68}LHLYUS9ZWLK2X`ynsW#c zrYx>DX$LV#9CDfoCe72VVk+!{sR&uzc|c+p>{A#2vT^~6_-NHS%8v25s<3(j-7wBS ztzXHnR(YGQ3*Ys^x9Wyckf{a~y=#a;1)t=$c^CD77yp^H{6;Xq+p4RlCA5%nb>m9! zLt^`*B3KqMNlp@6mL^=t%LN{BD>+r*9in-_<O%!*i=E3n${F&Qw1S2m-3-O3X&(te zrl-${q(`FZ8opTFQ5kZwTJ+57kSr>(v>sz@P6$r%gTcxz5<7hBR7*sk9!y1y5!NVV zHo40-!%|C+$Z+!oWH-2}i+Ulze+qsDCq$w&b$@bfEM^4wcXvDhAMxr{^_!18NwYL7 zWwskqPS&wROers6Oob;GaXexu_&RnR37;)@iXGGW?5beJTR^htHB*iD#kwTkP?S?n z<`-9eF#Q@r3ze{0fzUCU93GA(h8N{nVko(&ifxoFDtdI^`0(unu#8Yv#}lKm!~ymS zZrDmeN(DJC&Xg!)NybhiA5sdr*((lT6~xXVjZWIB;lI@Qu-Ty22X5}KJqoS-Ozn`j zkXxZWFUV<LS=U^48QHXOqKV>hYAdv$=CcOtW&!Tw*H`}q_gh!%HvzoN0}Vmw<>7`U z*k^^;{tfDaxFyfqLcK804~0w^wcySdZ^`ExJ7CWGrtxloBk!;8gfd(ItT0+5$i;$r z--Z@=n?JwdT{z9BYRgqS!1GpL)A!V4dQ6Cm1w)dbSgkGR0j^lTZrla%ht<>840KJJ zPlOwsYtl9AB1R4F&W0zJfmyYi461%CO5-x0zxTLC!M#M6WSNKC=g`>~?Hiz-|JnZB zR?!T0BQzs(yR6dzF&|9ulNopxza|;PnJ`1}tLlO}bb@6~d-?XxW`9Wg-(xb-U;NF@ z+x*=WF?euCs2kf;U6LggG@k4#=OrDNiXRroTH#pX*E%*$|BM@KBS7yYzFb;@)9DO7 z?!&PNIXO?nWJ46nZqh~`B|AtzF;rdB<wMwRJ&1V**h9LKl@hY9X0b%slu30*g=kMH zr|DWATRgoiyD2G0TYcJr1CPX=J!DU3R?gJhP@JYLY8;2D3ul;APHtWy2J2IYaIhBP zVEv>pSO-wjkIRs3*e-<awPCvp9d#SBox-BtOmIhZEIEOFQj;=xxU-Z`c8<Uxzt%bI zEoOG*ypBm>{~+P1EmQ7(k+eEHX&y`6>V-;M$u2LU#BBAef^+fauGNs_JG-7)u}zqX pTx+1Yv?8sX|JYThupCM(=e9Qh7WldDNsxJ{r^=D?PLpZk`WMNWx@Z6Z diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/constructors.py b/venv/lib/python3.8/site-packages/pip/_internal/req/constructors.py index cd0ab50..7a4641e 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/req/constructors.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/req/constructors.py @@ -17,22 +17,24 @@ from pip._vendor.packaging.requirements import InvalidRequirement, Requirement from pip._vendor.packaging.specifiers import Specifier from pip._vendor.pkg_resources import RequirementParseError, parse_requirements -from pip._internal.download import is_archive_file, is_url, url_to_path from pip._internal.exceptions import InstallationError from pip._internal.models.index import PyPI, TestPyPI from pip._internal.models.link import Link +from pip._internal.models.wheel import Wheel from pip._internal.pyproject import make_pyproject_path from pip._internal.req.req_install import InstallRequirement -from pip._internal.utils.misc import is_installable_dir, path_to_url +from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.filetypes import ARCHIVE_EXTENSIONS +from pip._internal.utils.misc import is_installable_dir, splitext from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.vcs import vcs -from pip._internal.wheel import Wheel +from pip._internal.utils.urls import path_to_url +from pip._internal.vcs import is_url, vcs if MYPY_CHECK_RUNNING: from typing import ( Any, Dict, Optional, Set, Tuple, Union, ) - from pip._internal.cache import WheelCache + from pip._internal.req.req_file import ParsedRequirement __all__ = [ @@ -44,6 +46,15 @@ logger = logging.getLogger(__name__) operators = Specifier._operators.keys() +def is_archive_file(name): + # type: (str) -> bool + """Return True if `name` is a considered as an archive file.""" + ext = splitext(name)[1].lower() + if ext in ARCHIVE_EXTENSIONS: + return True + return False + + def _strip_extras(path): # type: (str) -> Tuple[str, Optional[str]] m = re.match(r'^(.+)(\[[^\]]+\])$', path) @@ -57,8 +68,15 @@ def _strip_extras(path): return path_no_extras, extras +def convert_extras(extras): + # type: (Optional[str]) -> Set[str] + if not extras: + return set() + return Requirement("placeholder" + extras.lower()).extras + + def parse_editable(editable_req): - # type: (str) -> Tuple[Optional[str], str, Optional[Set[str]]] + # type: (str) -> Tuple[Optional[str], str, Set[str]] """Parses an editable requirement into: - a requirement name - an URL @@ -100,11 +118,11 @@ def parse_editable(editable_req): Requirement("placeholder" + extras.lower()).extras, ) else: - return package_name, url_no_extras, None + return package_name, url_no_extras, set() for version_control in vcs: - if url.lower().startswith('%s:' % version_control): - url = '%s+%s' % (version_control, url) + if url.lower().startswith('{}:'.format(version_control)): + url = '{}+{}'.format(version_control, url) break if '+' not in url: @@ -117,18 +135,19 @@ def parse_editable(editable_req): vc_type = url.split('+', 1)[0].lower() if not vcs.get_backend(vc_type): - error_message = 'For --editable=%s only ' % editable_req + \ - ', '.join([backend.name + '+URL' for backend in vcs.backends]) + \ - ' is currently supported' + backends = ", ".join([bends.name + '+URL' for bends in vcs.backends]) + error_message = "For --editable={}, " \ + "only {} are currently supported".format( + editable_req, backends) raise InstallationError(error_message) package_name = Link(url).egg_fragment if not package_name: raise InstallationError( - "Could not detect requirement name for '%s', please specify one " - "with #egg=your_package_name" % editable_req + "Could not detect requirement name for '{}', please specify one " + "with #egg=your_package_name".format(editable_req) ) - return package_name, url, None + return package_name, url, set() def deduce_helpful_msg(req): @@ -146,75 +165,141 @@ def deduce_helpful_msg(req): with open(req, 'r') as fp: # parse first line only next(parse_requirements(fp.read())) - msg += " The argument you provided " + \ - "(%s) appears to be a" % (req) + \ - " requirements file. If that is the" + \ - " case, use the '-r' flag to install" + \ + msg += ( + "The argument you provided " + "({}) appears to be a" + " requirements file. If that is the" + " case, use the '-r' flag to install" " the packages specified within it." + ).format(req) except RequirementParseError: - logger.debug("Cannot parse '%s' as requirements \ - file" % (req), exc_info=True) + logger.debug( + "Cannot parse '%s' as requirements file", req, exc_info=True + ) else: - msg += " File '%s' does not exist." % (req) + msg += " File '{}' does not exist.".format(req) return msg +class RequirementParts(object): + def __init__( + self, + requirement, # type: Optional[Requirement] + link, # type: Optional[Link] + markers, # type: Optional[Marker] + extras, # type: Set[str] + ): + self.requirement = requirement + self.link = link + self.markers = markers + self.extras = extras + + +def parse_req_from_editable(editable_req): + # type: (str) -> RequirementParts + name, url, extras_override = parse_editable(editable_req) + + if name is not None: + try: + req = Requirement(name) + except InvalidRequirement: + raise InstallationError("Invalid requirement: '{}'".format(name)) + else: + req = None + + link = Link(url) + + return RequirementParts(req, link, None, extras_override) + + # ---- The actual constructors follow ---- def install_req_from_editable( editable_req, # type: str - comes_from=None, # type: Optional[str] + comes_from=None, # type: Optional[Union[InstallRequirement, str]] use_pep517=None, # type: Optional[bool] isolated=False, # type: bool options=None, # type: Optional[Dict[str, Any]] - wheel_cache=None, # type: Optional[WheelCache] - constraint=False # type: bool + constraint=False, # type: bool + user_supplied=False, # type: bool ): # type: (...) -> InstallRequirement - name, url, extras_override = parse_editable(editable_req) - if url.startswith('file:'): - source_dir = url_to_path(url) - else: - source_dir = None - if name is not None: - try: - req = Requirement(name) - except InvalidRequirement: - raise InstallationError("Invalid requirement: '%s'" % name) - else: - req = None + parts = parse_req_from_editable(editable_req) + return InstallRequirement( - req, comes_from, source_dir=source_dir, + parts.requirement, + comes_from=comes_from, + user_supplied=user_supplied, editable=True, - link=Link(url), + link=parts.link, constraint=constraint, use_pep517=use_pep517, isolated=isolated, - options=options if options else {}, - wheel_cache=wheel_cache, - extras=extras_override or (), + install_options=options.get("install_options", []) if options else [], + global_options=options.get("global_options", []) if options else [], + hash_options=options.get("hashes", {}) if options else {}, + extras=parts.extras, ) -def install_req_from_line( - name, # type: str - comes_from=None, # type: Optional[Union[str, InstallRequirement]] - use_pep517=None, # type: Optional[bool] - isolated=False, # type: bool - options=None, # type: Optional[Dict[str, Any]] - wheel_cache=None, # type: Optional[WheelCache] - constraint=False, # type: bool - line_source=None, # type: Optional[str] -): - # type: (...) -> InstallRequirement - """Creates an InstallRequirement from a name, which might be a - requirement, directory containing 'setup.py', filename, or URL. +def _looks_like_path(name): + # type: (str) -> bool + """Checks whether the string "looks like" a path on the filesystem. - :param line_source: An optional string describing where the line is from, - for logging purposes in case of an error. + This does not check whether the target actually exists, only judge from the + appearance. + + Returns true if any of the following conditions is true: + * a path separator is found (either os.path.sep or os.path.altsep); + * a dot is found (which represents the current directory). """ + if os.path.sep in name: + return True + if os.path.altsep is not None and os.path.altsep in name: + return True + if name.startswith("."): + return True + return False + + +def _get_url_from_path(path, name): + # type: (str, str) -> Optional[str] + """ + First, it checks whether a provided path is an installable directory + (e.g. it has a setup.py). If it is, returns the path. + + If false, check if the path is an archive file (such as a .whl). + The function checks if the path is a file. If false, if the path has + an @, it will treat it as a PEP 440 URL requirement and return the path. + """ + if _looks_like_path(name) and os.path.isdir(path): + if is_installable_dir(path): + return path_to_url(path) + raise InstallationError( + "Directory {name!r} is not installable. Neither 'setup.py' " + "nor 'pyproject.toml' found.".format(**locals()) + ) + if not is_archive_file(path): + return None + if os.path.isfile(path): + return path_to_url(path) + urlreq_parts = name.split('@', 1) + if len(urlreq_parts) >= 2 and not _looks_like_path(urlreq_parts[0]): + # If the path contains '@' and the part before it does not look + # like a path, try to treat it as a PEP 440 URL req instead. + return None + logger.warning( + 'Requirement %r looks like a filename, but the ' + 'file does not exist', + name + ) + return path_to_url(path) + + +def parse_req_from_line(name, line_source): + # type: (str, Optional[str]) -> RequirementParts if is_url(name): marker_sep = '; ' else: @@ -238,26 +323,9 @@ def install_req_from_line( link = Link(name) else: p, extras_as_string = _strip_extras(path) - looks_like_dir = os.path.isdir(p) and ( - os.path.sep in name or - (os.path.altsep is not None and os.path.altsep in name) or - name.startswith('.') - ) - if looks_like_dir: - if not is_installable_dir(p): - raise InstallationError( - "Directory %r is not installable. Neither 'setup.py' " - "nor 'pyproject.toml' found." % name - ) - link = Link(path_to_url(p)) - elif is_archive_file(p): - if not os.path.isfile(p): - logger.warning( - 'Requirement %r looks like a filename, but the ' - 'file does not exist', - name - ) - link = Link(path_to_url(p)) + url = _get_url_from_path(p, name) + if url is not None: + link = Link(url) # it's a local file, dir, or url if link: @@ -268,7 +336,7 @@ def install_req_from_line( # wheel file if link.is_wheel: wheel = Wheel(link.filename) # can raise InvalidWheelFilename - req_as_string = "%s==%s" % (wheel.name, wheel.version) + req_as_string = "{wheel.name}=={wheel.version}".format(**locals()) else: # set the req to the egg fragment. when it's not there, this # will become an 'unnamed' requirement @@ -278,10 +346,14 @@ def install_req_from_line( else: req_as_string = name - if extras_as_string: - extras = Requirement("placeholder" + extras_as_string.lower()).extras - else: - extras = () + extras = convert_extras(extras_as_string) + + def with_source(text): + # type: (str) -> str + if not line_source: + return text + return '{} (from {})'.format(text, line_source) + if req_as_string is not None: try: req = Requirement(req_as_string) @@ -294,26 +366,57 @@ def install_req_from_line( add_msg = "= is not a valid operator. Did you mean == ?" else: add_msg = '' - if line_source is None: - source = '' - else: - source = ' (from {})'.format(line_source) - msg = ( - 'Invalid requirement: {!r}{}'.format(req_as_string, source) + msg = with_source( + 'Invalid requirement: {!r}'.format(req_as_string) ) if add_msg: msg += '\nHint: {}'.format(add_msg) raise InstallationError(msg) + else: + # Deprecate extras after specifiers: "name>=1.0[extras]" + # This currently works by accident because _strip_extras() parses + # any extras in the end of the string and those are saved in + # RequirementParts + for spec in req.specifier: + spec_str = str(spec) + if spec_str.endswith(']'): + msg = "Extras after version '{}'.".format(spec_str) + replace = "moving the extras before version specifiers" + deprecated(msg, replacement=replace, gone_in="21.0") else: req = None + return RequirementParts(req, link, markers, extras) + + +def install_req_from_line( + name, # type: str + comes_from=None, # type: Optional[Union[str, InstallRequirement]] + use_pep517=None, # type: Optional[bool] + isolated=False, # type: bool + options=None, # type: Optional[Dict[str, Any]] + constraint=False, # type: bool + line_source=None, # type: Optional[str] + user_supplied=False, # type: bool +): + # type: (...) -> InstallRequirement + """Creates an InstallRequirement from a name, which might be a + requirement, directory containing 'setup.py', filename, or URL. + + :param line_source: An optional string describing where the line is from, + for logging purposes in case of an error. + """ + parts = parse_req_from_line(name, line_source) + return InstallRequirement( - req, comes_from, link=link, markers=markers, + parts.requirement, comes_from, link=parts.link, markers=parts.markers, use_pep517=use_pep517, isolated=isolated, - options=options if options else {}, - wheel_cache=wheel_cache, + install_options=options.get("install_options", []) if options else [], + global_options=options.get("global_options", []) if options else [], + hash_options=options.get("hashes", {}) if options else {}, constraint=constraint, - extras=extras, + extras=parts.extras, + user_supplied=user_supplied, ) @@ -321,14 +424,14 @@ def install_req_from_req_string( req_string, # type: str comes_from=None, # type: Optional[InstallRequirement] isolated=False, # type: bool - wheel_cache=None, # type: Optional[WheelCache] - use_pep517=None # type: Optional[bool] + use_pep517=None, # type: Optional[bool] + user_supplied=False, # type: bool ): # type: (...) -> InstallRequirement try: req = Requirement(req_string) except InvalidRequirement: - raise InstallationError("Invalid requirement: '%s'" % req_string) + raise InstallationError("Invalid requirement: '{}'".format(req_string)) domains_not_allowed = [ PyPI.file_storage_domain, @@ -340,10 +443,44 @@ def install_req_from_req_string( raise InstallationError( "Packages installed from PyPI cannot depend on packages " "which are not also hosted on PyPI.\n" - "%s depends on %s " % (comes_from.name, req) + "{} depends on {} ".format(comes_from.name, req) ) return InstallRequirement( - req, comes_from, isolated=isolated, wheel_cache=wheel_cache, - use_pep517=use_pep517 + req, + comes_from, + isolated=isolated, + use_pep517=use_pep517, + user_supplied=user_supplied, ) + + +def install_req_from_parsed_requirement( + parsed_req, # type: ParsedRequirement + isolated=False, # type: bool + use_pep517=None, # type: Optional[bool] + user_supplied=False, # type: bool +): + # type: (...) -> InstallRequirement + if parsed_req.is_editable: + req = install_req_from_editable( + parsed_req.requirement, + comes_from=parsed_req.comes_from, + use_pep517=use_pep517, + constraint=parsed_req.constraint, + isolated=isolated, + user_supplied=user_supplied, + ) + + else: + req = install_req_from_line( + parsed_req.requirement, + comes_from=parsed_req.comes_from, + use_pep517=use_pep517, + isolated=isolated, + options=parsed_req.options, + constraint=parsed_req.constraint, + line_source=parsed_req.line_source, + user_supplied=user_supplied, + ) + return req diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/req_file.py b/venv/lib/python3.8/site-packages/pip/_internal/req/req_file.py index 5a9920f..1050582 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/req/req_file.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/req/req_file.py @@ -10,29 +10,33 @@ import re import shlex import sys -from pip._vendor.six.moves import filterfalse from pip._vendor.six.moves.urllib import parse as urllib_parse from pip._internal.cli import cmdoptions -from pip._internal.download import get_file_content -from pip._internal.exceptions import RequirementsFileParseError -from pip._internal.models.search_scope import SearchScope -from pip._internal.req.constructors import ( - install_req_from_editable, install_req_from_line, +from pip._internal.exceptions import ( + InstallationError, + RequirementsFileParseError, ) +from pip._internal.models.search_scope import SearchScope +from pip._internal.network.utils import raise_for_status +from pip._internal.utils.encoding import auto_decode from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import get_url_scheme if MYPY_CHECK_RUNNING: + from optparse import Values from typing import ( - Any, Callable, Iterator, List, NoReturn, Optional, Text, Tuple, + Any, Callable, Dict, Iterator, List, NoReturn, Optional, Text, Tuple, ) - from pip._internal.req import InstallRequirement - from pip._internal.cache import WheelCache - from pip._internal.index import PackageFinder - from pip._internal.download import PipSession + + from pip._internal.index.package_finder import PackageFinder + from pip._internal.network.session import PipSession ReqFileLines = Iterator[Tuple[int, Text]] + LineParser = Callable[[Text], Tuple[str, Values]] + + __all__ = ['parse_requirements'] SCHEME_RE = re.compile(r'^(http|https|file):', re.I) @@ -45,19 +49,20 @@ COMMENT_RE = re.compile(r'(^|\s+)#.*$') ENV_VAR_RE = re.compile(r'(?P<var>\$\{(?P<name>[A-Z0-9_]+)\})') SUPPORTED_OPTIONS = [ - cmdoptions.constraints, - cmdoptions.editable, - cmdoptions.requirements, - cmdoptions.no_index, cmdoptions.index_url, - cmdoptions.find_links, cmdoptions.extra_index_url, - cmdoptions.always_unzip, + cmdoptions.no_index, + cmdoptions.constraints, + cmdoptions.requirements, + cmdoptions.editable, + cmdoptions.find_links, cmdoptions.no_binary, cmdoptions.only_binary, + cmdoptions.prefer_binary, + cmdoptions.require_hashes, cmdoptions.pre, cmdoptions.trusted_host, - cmdoptions.require_hashes, + cmdoptions.use_new_feature, ] # type: List[Callable[..., optparse.Option]] # options to be passed to requirements @@ -71,174 +76,167 @@ SUPPORTED_OPTIONS_REQ = [ SUPPORTED_OPTIONS_REQ_DEST = [str(o().dest) for o in SUPPORTED_OPTIONS_REQ] +class ParsedRequirement(object): + def __init__( + self, + requirement, # type:str + is_editable, # type: bool + comes_from, # type: str + constraint, # type: bool + options=None, # type: Optional[Dict[str, Any]] + line_source=None, # type: Optional[str] + ): + # type: (...) -> None + self.requirement = requirement + self.is_editable = is_editable + self.comes_from = comes_from + self.options = options + self.constraint = constraint + self.line_source = line_source + + +class ParsedLine(object): + def __init__( + self, + filename, # type: str + lineno, # type: int + comes_from, # type: Optional[str] + args, # type: str + opts, # type: Values + constraint, # type: bool + ): + # type: (...) -> None + self.filename = filename + self.lineno = lineno + self.comes_from = comes_from + self.opts = opts + self.constraint = constraint + + if args: + self.is_requirement = True + self.is_editable = False + self.requirement = args + elif opts.editables: + self.is_requirement = True + self.is_editable = True + # We don't support multiple -e on one line + self.requirement = opts.editables[0] + else: + self.is_requirement = False + + def parse_requirements( filename, # type: str + session, # type: PipSession finder=None, # type: Optional[PackageFinder] comes_from=None, # type: Optional[str] options=None, # type: Optional[optparse.Values] - session=None, # type: Optional[PipSession] constraint=False, # type: bool - wheel_cache=None, # type: Optional[WheelCache] - use_pep517=None # type: Optional[bool] ): - # type: (...) -> Iterator[InstallRequirement] - """Parse a requirements file and yield InstallRequirement instances. + # type: (...) -> Iterator[ParsedRequirement] + """Parse a requirements file and yield ParsedRequirement instances. :param filename: Path or url of requirements file. + :param session: PipSession instance. :param finder: Instance of pip.index.PackageFinder. :param comes_from: Origin description of requirements. :param options: cli options. - :param session: Instance of pip.download.PipSession. :param constraint: If true, parsing a constraint file rather than requirements file. - :param wheel_cache: Instance of pip.wheel.WheelCache - :param use_pep517: Value of the --use-pep517 option. """ - if session is None: - raise TypeError( - "parse_requirements() missing 1 required keyword argument: " - "'session'" + line_parser = get_line_parser(finder) + parser = RequirementsFileParser(session, line_parser, comes_from) + + for parsed_line in parser.parse(filename, constraint): + parsed_req = handle_line( + parsed_line, + options=options, + finder=finder, + session=session ) - - _, content = get_file_content( - filename, comes_from=comes_from, session=session - ) - - lines_enum = preprocess(content, options) - - for line_number, line in lines_enum: - req_iter = process_line(line, filename, line_number, finder, - comes_from, options, session, wheel_cache, - use_pep517=use_pep517, constraint=constraint) - for req in req_iter: - yield req + if parsed_req is not None: + yield parsed_req -def preprocess(content, options): - # type: (Text, Optional[optparse.Values]) -> ReqFileLines +def preprocess(content): + # type: (Text) -> ReqFileLines """Split, filter, and join lines, and return a line iterator :param content: the content of the requirements file - :param options: cli options """ lines_enum = enumerate(content.splitlines(), start=1) # type: ReqFileLines lines_enum = join_lines(lines_enum) lines_enum = ignore_comments(lines_enum) - lines_enum = skip_regex(lines_enum, options) lines_enum = expand_env_variables(lines_enum) return lines_enum -def process_line( - line, # type: Text - filename, # type: str - line_number, # type: int - finder=None, # type: Optional[PackageFinder] - comes_from=None, # type: Optional[str] +def handle_requirement_line( + line, # type: ParsedLine options=None, # type: Optional[optparse.Values] - session=None, # type: Optional[PipSession] - wheel_cache=None, # type: Optional[WheelCache] - use_pep517=None, # type: Optional[bool] - constraint=False, # type: bool ): - # type: (...) -> Iterator[InstallRequirement] - """Process a single requirements line; This can result in creating/yielding - requirements, or updating the finder. - - For lines that contain requirements, the only options that have an effect - are from SUPPORTED_OPTIONS_REQ, and they are scoped to the - requirement. Other options from SUPPORTED_OPTIONS may be present, but are - ignored. - - For lines that do not contain requirements, the only options that have an - effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may - be present, but are ignored. These lines may contain multiple options - (although our docs imply only one is supported), and all our parsed and - affect the finder. - - :param constraint: If True, parsing a constraints file. - :param options: OptionParser options that we may update - """ - parser = build_parser(line) - defaults = parser.get_default_values() - defaults.index_url = None - if finder: - defaults.format_control = finder.format_control - args_str, options_str = break_args_options(line) - # Prior to 2.7.3, shlex cannot deal with unicode entries - if sys.version_info < (2, 7, 3): - # https://github.com/python/mypy/issues/1174 - options_str = options_str.encode('utf8') # type: ignore - # https://github.com/python/mypy/issues/1174 - opts, _ = parser.parse_args( - shlex.split(options_str), defaults) # type: ignore + # type: (...) -> ParsedRequirement # preserve for the nested code path - line_comes_from = '%s %s (line %s)' % ( - '-c' if constraint else '-r', filename, line_number, + line_comes_from = '{} {} (line {})'.format( + '-c' if line.constraint else '-r', line.filename, line.lineno, ) - # yield a line requirement - if args_str: - isolated = options.isolated_mode if options else False + assert line.is_requirement + + if line.is_editable: + # For editable requirements, we don't support per-requirement + # options, so just return the parsed requirement. + return ParsedRequirement( + requirement=line.requirement, + is_editable=line.is_editable, + comes_from=line_comes_from, + constraint=line.constraint, + ) + else: if options: - cmdoptions.check_install_build_global(options, opts) + # Disable wheels if the user has specified build options + cmdoptions.check_install_build_global(options, line.opts) + # get the options that apply to requirements req_options = {} for dest in SUPPORTED_OPTIONS_REQ_DEST: - if dest in opts.__dict__ and opts.__dict__[dest]: - req_options[dest] = opts.__dict__[dest] - line_source = 'line {} of {}'.format(line_number, filename) - yield install_req_from_line( - args_str, + if dest in line.opts.__dict__ and line.opts.__dict__[dest]: + req_options[dest] = line.opts.__dict__[dest] + + line_source = 'line {} of {}'.format(line.lineno, line.filename) + return ParsedRequirement( + requirement=line.requirement, + is_editable=line.is_editable, comes_from=line_comes_from, - use_pep517=use_pep517, - isolated=isolated, + constraint=line.constraint, options=req_options, - wheel_cache=wheel_cache, - constraint=constraint, line_source=line_source, ) - # yield an editable requirement - elif opts.editables: - isolated = options.isolated_mode if options else False - yield install_req_from_editable( - opts.editables[0], comes_from=line_comes_from, - use_pep517=use_pep517, - constraint=constraint, isolated=isolated, wheel_cache=wheel_cache - ) - # parse a nested requirements file - elif opts.requirements or opts.constraints: - if opts.requirements: - req_path = opts.requirements[0] - nested_constraint = False - else: - req_path = opts.constraints[0] - nested_constraint = True - # original file is over http - if SCHEME_RE.search(filename): - # do a url join so relative paths work - req_path = urllib_parse.urljoin(filename, req_path) - # original file and nested file are paths - elif not SCHEME_RE.search(req_path): - # do a join so relative paths work - req_path = os.path.join(os.path.dirname(filename), req_path) - # TODO: Why not use `comes_from='-r {} (line {})'` here as well? - parsed_reqs = parse_requirements( - req_path, finder, comes_from, options, session, - constraint=nested_constraint, wheel_cache=wheel_cache - ) - for req in parsed_reqs: - yield req +def handle_option_line( + opts, # type: Values + filename, # type: str + lineno, # type: int + finder=None, # type: Optional[PackageFinder] + options=None, # type: Optional[optparse.Values] + session=None, # type: Optional[PipSession] +): + # type: (...) -> None - # percolate hash-checking option upward - elif opts.require_hashes: - options.require_hashes = opts.require_hashes + if options: + # percolate options upward + if opts.require_hashes: + options.require_hashes = opts.require_hashes + if opts.features_enabled: + options.features_enabled.extend( + f for f in opts.features_enabled + if f not in options.features_enabled + ) # set finder options - elif finder: + if finder: find_links = finder.find_links index_urls = finder.index_urls if opts.index_url: @@ -266,9 +264,164 @@ def process_line( if opts.pre: finder.set_allow_all_prereleases() - for host in opts.trusted_hosts or []: - source = 'line {} of {}'.format(line_number, filename) - finder.add_trusted_host(host, source=source) + + if opts.prefer_binary: + finder.set_prefer_binary() + + if session: + for host in opts.trusted_hosts or []: + source = 'line {} of {}'.format(lineno, filename) + session.add_trusted_host(host, source=source) + + +def handle_line( + line, # type: ParsedLine + options=None, # type: Optional[optparse.Values] + finder=None, # type: Optional[PackageFinder] + session=None, # type: Optional[PipSession] +): + # type: (...) -> Optional[ParsedRequirement] + """Handle a single parsed requirements line; This can result in + creating/yielding requirements, or updating the finder. + + :param line: The parsed line to be processed. + :param options: CLI options. + :param finder: The finder - updated by non-requirement lines. + :param session: The session - updated by non-requirement lines. + + Returns a ParsedRequirement object if the line is a requirement line, + otherwise returns None. + + For lines that contain requirements, the only options that have an effect + are from SUPPORTED_OPTIONS_REQ, and they are scoped to the + requirement. Other options from SUPPORTED_OPTIONS may be present, but are + ignored. + + For lines that do not contain requirements, the only options that have an + effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may + be present, but are ignored. These lines may contain multiple options + (although our docs imply only one is supported), and all our parsed and + affect the finder. + """ + + if line.is_requirement: + parsed_req = handle_requirement_line(line, options) + return parsed_req + else: + handle_option_line( + line.opts, + line.filename, + line.lineno, + finder, + options, + session, + ) + return None + + +class RequirementsFileParser(object): + def __init__( + self, + session, # type: PipSession + line_parser, # type: LineParser + comes_from, # type: Optional[str] + ): + # type: (...) -> None + self._session = session + self._line_parser = line_parser + self._comes_from = comes_from + + def parse(self, filename, constraint): + # type: (str, bool) -> Iterator[ParsedLine] + """Parse a given file, yielding parsed lines. + """ + for line in self._parse_and_recurse(filename, constraint): + yield line + + def _parse_and_recurse(self, filename, constraint): + # type: (str, bool) -> Iterator[ParsedLine] + for line in self._parse_file(filename, constraint): + if ( + not line.is_requirement and + (line.opts.requirements or line.opts.constraints) + ): + # parse a nested requirements file + if line.opts.requirements: + req_path = line.opts.requirements[0] + nested_constraint = False + else: + req_path = line.opts.constraints[0] + nested_constraint = True + + # original file is over http + if SCHEME_RE.search(filename): + # do a url join so relative paths work + req_path = urllib_parse.urljoin(filename, req_path) + # original file and nested file are paths + elif not SCHEME_RE.search(req_path): + # do a join so relative paths work + req_path = os.path.join( + os.path.dirname(filename), req_path, + ) + + for inner_line in self._parse_and_recurse( + req_path, nested_constraint, + ): + yield inner_line + else: + yield line + + def _parse_file(self, filename, constraint): + # type: (str, bool) -> Iterator[ParsedLine] + _, content = get_file_content( + filename, self._session, comes_from=self._comes_from + ) + + lines_enum = preprocess(content) + + for line_number, line in lines_enum: + try: + args_str, opts = self._line_parser(line) + except OptionParsingError as e: + # add offending line + msg = 'Invalid requirement: {}\n{}'.format(line, e.msg) + raise RequirementsFileParseError(msg) + + yield ParsedLine( + filename, + line_number, + self._comes_from, + args_str, + opts, + constraint, + ) + + +def get_line_parser(finder): + # type: (Optional[PackageFinder]) -> LineParser + def parse_line(line): + # type: (Text) -> Tuple[str, Values] + # Build new parser for each line since it accumulates appendable + # options. + parser = build_parser() + defaults = parser.get_default_values() + defaults.index_url = None + if finder: + defaults.format_control = finder.format_control + + args_str, options_str = break_args_options(line) + # Prior to 2.7.3, shlex cannot deal with unicode entries + if sys.version_info < (2, 7, 3): + # https://github.com/python/mypy/issues/1174 + options_str = options_str.encode('utf8') # type: ignore + + # https://github.com/python/mypy/issues/1174 + opts, _ = parser.parse_args( + shlex.split(options_str), defaults) # type: ignore + + return args_str, opts + + return parse_line def break_args_options(line): @@ -289,8 +442,14 @@ def break_args_options(line): return ' '.join(args), ' '.join(options) # type: ignore -def build_parser(line): - # type: (Text) -> optparse.OptionParser +class OptionParsingError(Exception): + def __init__(self, msg): + # type: (str) -> None + self.msg = msg + + +def build_parser(): + # type: () -> optparse.OptionParser """ Return a parser for parsing requirement lines """ @@ -305,9 +464,7 @@ def build_parser(line): # that in our own exception. def parser_exit(self, msg): # type: (Any, str) -> NoReturn - # add offending line - msg = 'Invalid requirement: %s\n%s' % (line, msg) - raise RequirementsFileParseError(msg) + raise OptionParsingError(msg) # NOTE: mypy disallows assigning to a method # https://github.com/python/mypy/issues/2427 parser.exit = parser_exit # type: ignore @@ -329,6 +486,7 @@ def join_lines(lines_enum): line = ' ' + line if new_line: new_line.append(line) + assert primary_line_number is not None yield primary_line_number, ''.join(new_line) new_line = [] else: @@ -340,6 +498,7 @@ def join_lines(lines_enum): # last line contains \ if new_line: + assert primary_line_number is not None yield primary_line_number, ''.join(new_line) # TODO: handle space after '\'. @@ -357,20 +516,6 @@ def ignore_comments(lines_enum): yield line_number, line -def skip_regex(lines_enum, options): - # type: (ReqFileLines, Optional[optparse.Values]) -> ReqFileLines - """ - Skip lines that match '--skip-requirements-regex' pattern - - Note: the regex pattern is only built once - """ - skip_regex = options.skip_requirements_regex if options else None - if skip_regex: - pattern = re.compile(skip_regex) - lines_enum = filterfalse(lambda e: pattern.search(e[1]), lines_enum) - return lines_enum - - def expand_env_variables(lines_enum): # type: (ReqFileLines) -> ReqFileLines """Replace all environment variables that can be retrieved via `os.getenv`. @@ -397,3 +542,51 @@ def expand_env_variables(lines_enum): line = line.replace(env_var, value) yield line_number, line + + +def get_file_content(url, session, comes_from=None): + # type: (str, PipSession, Optional[str]) -> Tuple[str, Text] + """Gets the content of a file; it may be a filename, file: URL, or + http: URL. Returns (location, content). Content is unicode. + Respects # -*- coding: declarations on the retrieved files. + + :param url: File path or url. + :param session: PipSession instance. + :param comes_from: Origin description of requirements. + """ + scheme = get_url_scheme(url) + + if scheme in ['http', 'https']: + # FIXME: catch some errors + resp = session.get(url) + raise_for_status(resp) + return resp.url, resp.text + + elif scheme == 'file': + if comes_from and comes_from.startswith('http'): + raise InstallationError( + 'Requirements file {} references URL {}, ' + 'which is local'.format(comes_from, url) + ) + + path = url.split(':', 1)[1] + path = path.replace('\\', '/') + match = _url_slash_drive_re.match(path) + if match: + path = match.group(1) + ':' + path.split('|', 1)[1] + path = urllib_parse.unquote(path) + if path.startswith('/'): + path = '/' + path.lstrip('/') + url = path + + try: + with open(url, 'rb') as f: + content = auto_decode(f.read()) + except IOError as exc: + raise InstallationError( + 'Could not open requirements file: {}'.format(exc) + ) + return url, content + + +_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/req_install.py b/venv/lib/python3.8/site-packages/pip/_internal/req/req_install.py index f5c9350..f25cec9 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/req/req_install.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/req/req_install.py @@ -1,12 +1,14 @@ +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False + from __future__ import absolute_import import logging import os import shutil import sys -import sysconfig +import uuid import zipfile -from distutils.util import change_root from pip._vendor import pkg_resources, six from pip._vendor.packaging.requirements import Requirement @@ -15,36 +17,46 @@ from pip._vendor.packaging.version import Version from pip._vendor.packaging.version import parse as parse_version from pip._vendor.pep517.wrappers import Pep517HookCaller -from pip._internal import wheel from pip._internal.build_env import NoOpBuildEnvironment from pip._internal.exceptions import InstallationError +from pip._internal.locations import get_scheme from pip._internal.models.link import Link +from pip._internal.operations.build.metadata import generate_metadata +from pip._internal.operations.build.metadata_legacy import \ + generate_metadata as generate_metadata_legacy +from pip._internal.operations.install.editable_legacy import \ + install_editable as install_editable_legacy +from pip._internal.operations.install.legacy import LegacyInstallFailure +from pip._internal.operations.install.legacy import install as install_legacy +from pip._internal.operations.install.wheel import install_wheel from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path from pip._internal.req.req_uninstall import UninstallPathSet -from pip._internal.utils.compat import native_str +from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.direct_url_helpers import direct_url_from_link from pip._internal.utils.hashes import Hashes from pip._internal.utils.logging import indent_log -from pip._internal.utils.marker_files import PIP_DELETE_MARKER_FILENAME from pip._internal.utils.misc import ( - _make_build_dir, ask_path_exists, backup_dir, call_subprocess, - display_path, dist_in_site_packages, dist_in_usersite, ensure_dir, - get_installed_version, redact_password_from_url, rmtree, + ask_path_exists, + backup_dir, + display_path, + dist_in_site_packages, + dist_in_usersite, + get_distribution, + get_installed_version, + hide_url, + redact_auth_from_url, ) from pip._internal.utils.packaging import get_metadata -from pip._internal.utils.setuptools_build import make_setuptools_shim_args -from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.ui import open_spinner from pip._internal.utils.virtualenv import running_under_virtualenv from pip._internal.vcs import vcs if MYPY_CHECK_RUNNING: from typing import ( - Any, Dict, Iterable, List, Mapping, Optional, Sequence, Union, + Any, Dict, Iterable, List, Optional, Sequence, Union, ) from pip._internal.build_env import BuildEnvironment - from pip._internal.cache import WheelCache - from pip._internal.index import PackageFinder from pip._vendor.pkg_resources import Distribution from pip._vendor.packaging.specifiers import SpecifierSet from pip._vendor.packaging.markers import Marker @@ -53,6 +65,33 @@ if MYPY_CHECK_RUNNING: logger = logging.getLogger(__name__) +def _get_dist(metadata_directory): + # type: (str) -> Distribution + """Return a pkg_resources.Distribution for the provided + metadata directory. + """ + dist_dir = metadata_directory.rstrip(os.sep) + + # Build a PathMetadata object, from path to metadata. :wink: + base_dir, dist_dir_name = os.path.split(dist_dir) + metadata = pkg_resources.PathMetadata(base_dir, dist_dir) + + # Determine the correct Distribution object type. + if dist_dir.endswith(".egg-info"): + dist_cls = pkg_resources.Distribution + dist_name = os.path.splitext(dist_dir_name)[0] + else: + assert dist_dir.endswith(".dist-info") + dist_cls = pkg_resources.DistInfoDistribution + dist_name = os.path.splitext(dist_dir_name)[0].split("-")[0] + + return dist_cls( + base_dir, + project_name=dist_name, + metadata=metadata, + ) + + class InstallRequirement(object): """ Represents something that may be installed later on, may have information @@ -64,34 +103,49 @@ class InstallRequirement(object): self, req, # type: Optional[Requirement] comes_from, # type: Optional[Union[str, InstallRequirement]] - source_dir=None, # type: Optional[str] editable=False, # type: bool link=None, # type: Optional[Link] - update=True, # type: bool markers=None, # type: Optional[Marker] use_pep517=None, # type: Optional[bool] isolated=False, # type: bool - options=None, # type: Optional[Dict[str, Any]] - wheel_cache=None, # type: Optional[WheelCache] + install_options=None, # type: Optional[List[str]] + global_options=None, # type: Optional[List[str]] + hash_options=None, # type: Optional[Dict[str, List[str]]] constraint=False, # type: bool - extras=() # type: Iterable[str] + extras=(), # type: Iterable[str] + user_supplied=False, # type: bool ): # type: (...) -> None assert req is None or isinstance(req, Requirement), req self.req = req self.comes_from = comes_from self.constraint = constraint - if source_dir is None: - self.source_dir = None # type: Optional[str] - else: - self.source_dir = os.path.normpath(os.path.abspath(source_dir)) self.editable = editable + self.legacy_install_reason = None # type: Optional[int] + + # source_dir is the local directory where the linked requirement is + # located, or unpacked. In case unpacking is needed, creating and + # populating source_dir is done by the RequirementPreparer. Note this + # is not necessarily the directory where pyproject.toml or setup.py is + # located - that one is obtained via unpacked_source_directory. + self.source_dir = None # type: Optional[str] + if self.editable: + assert link + if link.is_file: + self.source_dir = os.path.normpath( + os.path.abspath(link.file_path) + ) - self._wheel_cache = wheel_cache if link is None and req and req.url: # PEP 508 URL requirement link = Link(req.url) self.link = self.original_link = link + self.original_link_is_in_wheel_cache = False + + # Path to any downloaded or already-existing package. + self.local_file_path = None # type: Optional[str] + if self.link and self.link.is_file: + self.local_file_path = self.link.file_path if extras: self.extras = extras @@ -105,28 +159,35 @@ class InstallRequirement(object): markers = req.marker self.markers = markers - self._egg_info_path = None # type: Optional[str] # This holds the pkg_resources.Distribution object if this requirement # is already available: - self.satisfied_by = None - # This hold the pkg_resources.Distribution object if this requirement - # conflicts with another installed distribution: - self.conflicts_with = None + self.satisfied_by = None # type: Optional[Distribution] + # Whether the installation process should try to uninstall an existing + # distribution before installing this requirement. + self.should_reinstall = False # Temporary build location - self._temp_build_dir = TempDirectory(kind="req-build") - # Used to store the global directory where the _temp_build_dir should - # have been created. Cf _correct_build_location method. - self._ideal_build_dir = None # type: Optional[str] - # True if the editable should be updated: - self.update = update + self._temp_build_dir = None # type: Optional[TempDirectory] # Set to True after successful installation self.install_succeeded = None # type: Optional[bool] - # UninstallPathSet of uninstalled distribution (for possible rollback) - self.uninstalled_pathset = None - self.options = options if options else {} + # Supplied options + self.install_options = install_options if install_options else [] + self.global_options = global_options if global_options else [] + self.hash_options = hash_options if hash_options else {} # Set to True after successful preparation of this requirement self.prepared = False - self.is_direct = False + # User supplied requirement are explicitly requested for installation + # by the user via CLI arguments or requirements files, as opposed to, + # e.g. dependencies, extras or constraints. + self.user_supplied = user_supplied + + # Set by the legacy resolver when the requirement has been downloaded + # TODO: This introduces a strong coupling between the resolver and the + # requirement (the coupling was previously between the resolver + # and the requirement set). This should be refactored to allow + # the requirement to decide for itself when it has been + # successfully downloaded - but that is more tricky to get right, + # se we are making the change in stages. + self.successfully_downloaded = False self.isolated = isolated self.build_env = NoOpBuildEnvironment() # type: BuildEnvironment @@ -158,25 +219,25 @@ class InstallRequirement(object): if self.req: s = str(self.req) if self.link: - s += ' from %s' % redact_password_from_url(self.link.url) + s += ' from {}'.format(redact_auth_from_url(self.link.url)) elif self.link: - s = redact_password_from_url(self.link.url) + s = redact_auth_from_url(self.link.url) else: s = '<InstallRequirement>' if self.satisfied_by is not None: - s += ' in %s' % display_path(self.satisfied_by.location) + s += ' in {}'.format(display_path(self.satisfied_by.location)) if self.comes_from: if isinstance(self.comes_from, six.string_types): comes_from = self.comes_from # type: Optional[str] else: comes_from = self.comes_from.from_path() if comes_from: - s += ' (from %s)' % comes_from + s += ' (from {})'.format(comes_from) return s def __repr__(self): # type: () -> str - return '<%s object: %s editable=%r>' % ( + return '<{} object: {} editable={!r}>'.format( self.__class__.__name__, str(self), self.editable) def format_debug(self): @@ -194,34 +255,13 @@ class InstallRequirement(object): state=", ".join(state), ) - def populate_link(self, finder, upgrade, require_hashes): - # type: (PackageFinder, bool, bool) -> None - """Ensure that if a link can be found for this, that it is found. - - Note that self.link may still be None - if Upgrade is False and the - requirement is already installed. - - If require_hashes is True, don't use the wheel cache, because cached - wheels, always built locally, have different hashes than the files - downloaded from the index server and thus throw false hash mismatches. - Furthermore, cached wheels at present have undeterministic contents due - to file modification times. - """ - if self.link is None: - self.link = finder.find_requirement(self, upgrade) - if self._wheel_cache is not None and not require_hashes: - old_link = self.link - self.link = self._wheel_cache.get(self.link, self.name) - if old_link != self.link: - logger.debug('Using cached wheel link: %s', self.link) - # Things that are valid for all kinds of requirements? @property def name(self): # type: () -> Optional[str] if self.req is None: return None - return native_str(pkg_resources.safe_name(self.req.name)) + return six.ensure_str(pkg_resources.safe_name(self.req.name)) @property def specifier(self): @@ -266,7 +306,7 @@ class InstallRequirement(object): URL do not. """ - return bool(self.options.get('hashes', {})) + return bool(self.hash_options) def hashes(self, trust_internet=True): # type: (bool) -> Hashes @@ -284,7 +324,7 @@ class InstallRequirement(object): downloaded from the internet, as by populate_link() """ - good_hashes = self.options.get('hashes', {}).copy() + good_hashes = self.hash_options.copy() link = self.link if trust_internet else self.original_link if link and link.hash: good_hashes.setdefault(link.hash_name, []).append(link.hash) @@ -306,130 +346,117 @@ class InstallRequirement(object): s += '->' + comes_from return s - def build_location(self, build_dir): - # type: (str) -> str + def ensure_build_location(self, build_dir, autodelete, parallel_builds): + # type: (str, bool, bool) -> str assert build_dir is not None - if self._temp_build_dir.path is not None: + if self._temp_build_dir is not None: + assert self._temp_build_dir.path return self._temp_build_dir.path if self.req is None: - # for requirement via a path to a directory: the name of the - # package is not available yet so we create a temp directory - # Once run_egg_info will have run, we'll be able - # to fix it via _correct_build_location # Some systems have /tmp as a symlink which confuses custom # builds (such as numpy). Thus, we ensure that the real path # is returned. - self._temp_build_dir.create() - self._ideal_build_dir = build_dir + self._temp_build_dir = TempDirectory( + kind=tempdir_kinds.REQ_BUILD, globally_managed=True + ) return self._temp_build_dir.path - if self.editable: - name = self.name.lower() - else: - name = self.name + + # When parallel builds are enabled, add a UUID to the build directory + # name so multiple builds do not interfere with each other. + dir_name = canonicalize_name(self.name) + if parallel_builds: + dir_name = "{}_{}".format(dir_name, uuid.uuid4().hex) + # FIXME: Is there a better place to create the build_dir? (hg and bzr # need this) if not os.path.exists(build_dir): logger.debug('Creating directory %s', build_dir) - _make_build_dir(build_dir) - return os.path.join(build_dir, name) + os.makedirs(build_dir) + actual_build_dir = os.path.join(build_dir, dir_name) + # `None` indicates that we respect the globally-configured deletion + # settings, which is what we actually want when auto-deleting. + delete_arg = None if autodelete else False + return TempDirectory( + path=actual_build_dir, + delete=delete_arg, + kind=tempdir_kinds.REQ_BUILD, + globally_managed=True, + ).path - def _correct_build_location(self): + def _set_requirement(self): # type: () -> None - """Move self._temp_build_dir to self._ideal_build_dir/self.req.name - - For some requirements (e.g. a path to a directory), the name of the - package is not available until we run egg_info, so the build_location - will return a temporary directory and store the _ideal_build_dir. - - This is only called by self.run_egg_info to fix the temporary build - directory. + """Set requirement after generating metadata. """ - if self.source_dir is not None: - return - assert self.req is not None - assert self._temp_build_dir.path - assert (self._ideal_build_dir is not None and - self._ideal_build_dir.path) # type: ignore - old_location = self._temp_build_dir.path - self._temp_build_dir.path = None + assert self.req is None + assert self.metadata is not None + assert self.source_dir is not None - new_location = self.build_location(self._ideal_build_dir) - if os.path.exists(new_location): - raise InstallationError( - 'A package already exists in %s; please remove it to continue' - % display_path(new_location)) - logger.debug( - 'Moving package %s from %s to new location %s', - self, display_path(old_location), display_path(new_location), + # Construct a Requirement object from the generated metadata + if isinstance(parse_version(self.metadata["Version"]), Version): + op = "==" + else: + op = "===" + + self.req = Requirement( + "".join([ + self.metadata["Name"], + op, + self.metadata["Version"], + ]) ) - shutil.move(old_location, new_location) - self._temp_build_dir.path = new_location - self._ideal_build_dir = None - self.source_dir = os.path.normpath(os.path.abspath(new_location)) - self._egg_info_path = None - # Correct the metadata directory, if it exists - if self.metadata_directory: - old_meta = self.metadata_directory - rel = os.path.relpath(old_meta, start=old_location) - new_meta = os.path.join(new_location, rel) - new_meta = os.path.normpath(os.path.abspath(new_meta)) - self.metadata_directory = new_meta - - def remove_temporary_source(self): + def warn_on_mismatching_name(self): # type: () -> None - """Remove the source files from this requirement, if they are marked - for deletion""" - if self.source_dir and os.path.exists( - os.path.join(self.source_dir, PIP_DELETE_MARKER_FILENAME)): - logger.debug('Removing source in %s', self.source_dir) - rmtree(self.source_dir) - self.source_dir = None - self._temp_build_dir.cleanup() - self.build_env.cleanup() + metadata_name = canonicalize_name(self.metadata["Name"]) + if canonicalize_name(self.req.name) == metadata_name: + # Everything is fine. + return + + # If we're here, there's a mismatch. Log a warning about it. + logger.warning( + 'Generating metadata for package %s ' + 'produced metadata for project name %s. Fix your ' + '#egg=%s fragments.', + self.name, metadata_name, self.name + ) + self.req = Requirement(metadata_name) def check_if_exists(self, use_user_site): - # type: (bool) -> bool + # type: (bool) -> None """Find an installed distribution that satisfies or conflicts with this requirement, and set self.satisfied_by or - self.conflicts_with appropriately. + self.should_reinstall appropriately. """ if self.req is None: - return False - try: - # get_distribution() will resolve the entire list of requirements - # anyway, and we've already determined that we need the requirement - # in question, so strip the marker so that we don't try to - # evaluate it. - no_marker = Requirement(str(self.req)) - no_marker.marker = None - self.satisfied_by = pkg_resources.get_distribution(str(no_marker)) - if self.editable and self.satisfied_by: - self.conflicts_with = self.satisfied_by - # when installing editables, nothing pre-existing should ever - # satisfy - self.satisfied_by = None - return True - except pkg_resources.DistributionNotFound: - return False - except pkg_resources.VersionConflict: - existing_dist = pkg_resources.get_distribution( - self.req.name - ) + return + existing_dist = get_distribution(self.req.name) + if not existing_dist: + return + + existing_version = existing_dist.parsed_version + if not self.req.specifier.contains(existing_version, prereleases=True): + self.satisfied_by = None if use_user_site: if dist_in_usersite(existing_dist): - self.conflicts_with = existing_dist + self.should_reinstall = True elif (running_under_virtualenv() and dist_in_site_packages(existing_dist)): raise InstallationError( "Will not install to the user site because it will " - "lack sys.path precedence to %s in %s" % - (existing_dist.project_name, existing_dist.location) + "lack sys.path precedence to {} in {}".format( + existing_dist.project_name, existing_dist.location) ) else: - self.conflicts_with = existing_dist - return True + self.should_reinstall = True + else: + if self.editable: + self.should_reinstall = True + # when installing editables, nothing pre-existing should ever + # satisfy + self.satisfied_by = None + else: + self.satisfied_by = existing_dist # Things valid for wheels @property @@ -439,31 +466,9 @@ class InstallRequirement(object): return False return self.link.is_wheel - def move_wheel_files( - self, - wheeldir, # type: str - root=None, # type: Optional[str] - home=None, # type: Optional[str] - prefix=None, # type: Optional[str] - warn_script_location=True, # type: bool - use_user_site=False, # type: bool - pycompile=True # type: bool - ): - # type: (...) -> None - wheel.move_wheel_files( - self.name, self.req, wheeldir, - user=use_user_site, - home=home, - root=root, - prefix=prefix, - pycompile=pycompile, - isolated=self.isolated, - warn_script_location=warn_script_location, - ) - # Things valid for sdists @property - def setup_py_dir(self): + def unpacked_source_directory(self): # type: () -> str return os.path.join( self.source_dir, @@ -472,9 +477,8 @@ class InstallRequirement(object): @property def setup_py_path(self): # type: () -> str - assert self.source_dir, "No source dir for %s" % self - - setup_py = os.path.join(self.setup_py_dir, 'setup.py') + assert self.source_dir, "No source dir for {}".format(self) + setup_py = os.path.join(self.unpacked_source_directory, 'setup.py') # Python2 __file__ should not be unicode if six.PY2 and isinstance(setup_py, six.text_type): @@ -485,9 +489,8 @@ class InstallRequirement(object): @property def pyproject_toml_path(self): # type: () -> str - assert self.source_dir, "No source dir for %s" % self - - return make_pyproject_path(self.setup_py_dir) + assert self.source_dir, "No source dir for {}".format(self) + return make_pyproject_path(self.unpacked_source_directory) def load_pyproject_toml(self): # type: () -> None @@ -505,35 +508,39 @@ class InstallRequirement(object): str(self) ) - self.use_pep517 = (pyproject_toml_data is not None) - - if not self.use_pep517: + if pyproject_toml_data is None: + self.use_pep517 = False return - requires, backend, check = pyproject_toml_data + self.use_pep517 = True + requires, backend, check, backend_path = pyproject_toml_data self.requirements_to_check = check self.pyproject_requires = requires - self.pep517_backend = Pep517HookCaller(self.setup_py_dir, backend) + self.pep517_backend = Pep517HookCaller( + self.unpacked_source_directory, backend, backend_path=backend_path, + ) - # Use a custom function to call subprocesses - self.spin_message = "" + def _generate_metadata(self): + # type: () -> str + """Invokes metadata generator functions, with the required arguments. + """ + if not self.use_pep517: + assert self.unpacked_source_directory - def runner( - cmd, # type: List[str] - cwd=None, # type: Optional[str] - extra_environ=None # type: Optional[Mapping[str, Any]] - ): - # type: (...) -> None - with open_spinner(self.spin_message) as spinner: - call_subprocess( - cmd, - cwd=cwd, - extra_environ=extra_environ, - spinner=spinner - ) - self.spin_message = "" + return generate_metadata_legacy( + build_env=self.build_env, + setup_py_path=self.setup_py_path, + source_dir=self.unpacked_source_directory, + isolated=self.isolated, + details=self.name or "from {}".format(self.link) + ) - self.pep517_backend._subprocess_runner = runner + assert self.pep517_backend is not None + + return generate_metadata( + build_env=self.build_env, + backend=self.pep517_backend, + ) def prepare_metadata(self): # type: () -> None @@ -545,140 +552,15 @@ class InstallRequirement(object): assert self.source_dir with indent_log(): - if self.use_pep517: - self.prepare_pep517_metadata() - else: - self.run_egg_info() + self.metadata_directory = self._generate_metadata() - if not self.req: - if isinstance(parse_version(self.metadata["Version"]), Version): - op = "==" - else: - op = "===" - self.req = Requirement( - "".join([ - self.metadata["Name"], - op, - self.metadata["Version"], - ]) - ) - self._correct_build_location() + # Act on the newly generated metadata, based on the name and version. + if not self.name: + self._set_requirement() else: - metadata_name = canonicalize_name(self.metadata["Name"]) - if canonicalize_name(self.req.name) != metadata_name: - logger.warning( - 'Generating metadata for package %s ' - 'produced metadata for project name %s. Fix your ' - '#egg=%s fragments.', - self.name, metadata_name, self.name - ) - self.req = Requirement(metadata_name) + self.warn_on_mismatching_name() - def prepare_pep517_metadata(self): - # type: () -> None - assert self.pep517_backend is not None - - metadata_dir = os.path.join( - self.setup_py_dir, - 'pip-wheel-metadata' - ) - ensure_dir(metadata_dir) - - with self.build_env: - # Note that Pep517HookCaller implements a fallback for - # prepare_metadata_for_build_wheel, so we don't have to - # consider the possibility that this hook doesn't exist. - backend = self.pep517_backend - self.spin_message = "Preparing wheel metadata" - distinfo_dir = backend.prepare_metadata_for_build_wheel( - metadata_dir - ) - - self.metadata_directory = os.path.join(metadata_dir, distinfo_dir) - - def run_egg_info(self): - # type: () -> None - if self.name: - logger.debug( - 'Running setup.py (path:%s) egg_info for package %s', - self.setup_py_path, self.name, - ) - else: - logger.debug( - 'Running setup.py (path:%s) egg_info for package from %s', - self.setup_py_path, self.link, - ) - base_cmd = make_setuptools_shim_args(self.setup_py_path) - if self.isolated: - base_cmd += ["--no-user-cfg"] - egg_info_cmd = base_cmd + ['egg_info'] - # We can't put the .egg-info files at the root, because then the - # source code will be mistaken for an installed egg, causing - # problems - if self.editable: - egg_base_option = [] # type: List[str] - else: - egg_info_dir = os.path.join(self.setup_py_dir, 'pip-egg-info') - ensure_dir(egg_info_dir) - egg_base_option = ['--egg-base', 'pip-egg-info'] - with self.build_env: - call_subprocess( - egg_info_cmd + egg_base_option, - cwd=self.setup_py_dir, - command_desc='python setup.py egg_info') - - @property - def egg_info_path(self): - # type: () -> str - if self._egg_info_path is None: - if self.editable: - base = self.source_dir - else: - base = os.path.join(self.setup_py_dir, 'pip-egg-info') - filenames = os.listdir(base) - if self.editable: - filenames = [] - for root, dirs, files in os.walk(base): - for dir in vcs.dirnames: - if dir in dirs: - dirs.remove(dir) - # Iterate over a copy of ``dirs``, since mutating - # a list while iterating over it can cause trouble. - # (See https://github.com/pypa/pip/pull/462.) - for dir in list(dirs): - # Don't search in anything that looks like a virtualenv - # environment - if ( - os.path.lexists( - os.path.join(root, dir, 'bin', 'python') - ) or - os.path.exists( - os.path.join( - root, dir, 'Scripts', 'Python.exe' - ) - )): - dirs.remove(dir) - # Also don't search through tests - elif dir == 'test' or dir == 'tests': - dirs.remove(dir) - filenames.extend([os.path.join(root, dir) - for dir in dirs]) - filenames = [f for f in filenames if f.endswith('.egg-info')] - - if not filenames: - raise InstallationError( - "Files/directories not found in %s" % base - ) - # if we have more than one match, we pick the toplevel one. This - # can easily be the case if there is a dist folder which contains - # an extracted tarball for testing purposes. - if len(filenames) > 1: - filenames.sort( - key=lambda x: x.count(os.path.sep) + - (os.path.altsep and x.count(os.path.altsep) or 0) - ) - self._egg_info_path = os.path.join(base, filenames[0]) - return self._egg_info_path + self.assert_source_matches_version() @property def metadata(self): @@ -690,26 +572,7 @@ class InstallRequirement(object): def get_dist(self): # type: () -> Distribution - """Return a pkg_resources.Distribution for this requirement""" - if self.metadata_directory: - dist_dir = self.metadata_directory - dist_cls = pkg_resources.DistInfoDistribution - else: - dist_dir = self.egg_info_path.rstrip(os.path.sep) - # https://github.com/python/mypy/issues/1174 - dist_cls = pkg_resources.Distribution # type: ignore - - # dist_dir_name can be of the form "<project>.dist-info" or - # e.g. "<project>.egg-info". - base_dir, dist_dir_name = os.path.split(dist_dir) - dist_name = os.path.splitext(dist_dir_name)[0] - metadata = pkg_resources.PathMetadata(base_dir, dist_dir) - - return dist_cls( - base_dir, - project_name=dist_name, - metadata=metadata, - ) + return _get_dist(self.metadata_directory) def assert_source_matches_version(self): # type: () -> None @@ -730,8 +593,13 @@ class InstallRequirement(object): ) # For both source distributions and editables - def ensure_has_source_dir(self, parent_dir): - # type: (str) -> str + def ensure_has_source_dir( + self, + parent_dir, + autodelete=False, + parallel_builds=False, + ): + # type: (str, bool, bool) -> None """Ensure that a source_dir is set. This will create a temporary build dir if the name of the requirement @@ -742,40 +610,13 @@ class InstallRequirement(object): :return: self.source_dir """ if self.source_dir is None: - self.source_dir = self.build_location(parent_dir) - return self.source_dir + self.source_dir = self.ensure_build_location( + parent_dir, + autodelete=autodelete, + parallel_builds=parallel_builds, + ) # For editable installations - def install_editable( - self, - install_options, # type: List[str] - global_options=(), # type: Sequence[str] - prefix=None # type: Optional[str] - ): - # type: (...) -> None - logger.info('Running setup.py develop for %s', self.name) - - if self.isolated: - global_options = list(global_options) + ["--no-user-cfg"] - - if prefix: - prefix_param = ['--prefix={}'.format(prefix)] - install_options = list(install_options) + prefix_param - - with indent_log(): - # FIXME: should we do --install-headers here too? - with self.build_env: - call_subprocess( - make_setuptools_shim_args(self.setup_py_path) + - list(global_options) + - ['develop', '--no-deps'] + - list(install_options), - - cwd=self.setup_py_dir, - ) - - self.install_succeeded = True - def update_editable(self, obtain=True): # type: (bool) -> None if not self.link: @@ -790,26 +631,38 @@ class InstallRequirement(object): if self.link.scheme == 'file': # Static paths don't get updated return - assert '+' in self.link.url, "bad url: %r" % self.link.url - if not self.update: - return + assert '+' in self.link.url, \ + "bad url: {self.link.url!r}".format(**locals()) vc_type, url = self.link.url.split('+', 1) vcs_backend = vcs.get_backend(vc_type) if vcs_backend: - url = self.link.url + if not self.link.is_vcs: + reason = ( + "This form of VCS requirement is being deprecated: {}." + ).format( + self.link.url + ) + replacement = None + if self.link.url.startswith("git+git@"): + replacement = ( + "git+https://git@example.com/..., " + "git+ssh://git@example.com/..., " + "or the insecure git+git://git@example.com/..." + ) + deprecated(reason, replacement, gone_in="21.0", issue=7554) + hidden_url = hide_url(self.link.url) if obtain: - vcs_backend.obtain(self.source_dir, url=url) + vcs_backend.obtain(self.source_dir, url=hidden_url) else: - vcs_backend.export(self.source_dir, url=url) + vcs_backend.export(self.source_dir, url=hidden_url) else: assert 0, ( - 'Unexpected version control type (in %s): %s' - % (self.link, vc_type)) + 'Unexpected version control type (in {}): {}'.format( + self.link, vc_type)) # Top-level Actions - def uninstall(self, auto_confirm=False, verbose=False, - use_user_site=False): - # type: (bool, bool, bool) -> Optional[UninstallPathSet] + def uninstall(self, auto_confirm=False, verbose=False): + # type: (bool, bool) -> Optional[UninstallPathSet] """ Uninstall the distribution currently satisfying this requirement. @@ -822,42 +675,52 @@ class InstallRequirement(object): linked to global site-packages. """ - if not self.check_if_exists(use_user_site): + assert self.req + dist = get_distribution(self.req.name) + if not dist: logger.warning("Skipping %s as it is not installed.", self.name) return None - dist = self.satisfied_by or self.conflicts_with + logger.info('Found existing installation: %s', dist) uninstalled_pathset = UninstallPathSet.from_dist(dist) uninstalled_pathset.remove(auto_confirm, verbose) return uninstalled_pathset - def _clean_zip_name(self, name, prefix): # only used by archive. - # type: (str, str) -> str - assert name.startswith(prefix + os.path.sep), ( - "name %r doesn't start with prefix %r" % (name, prefix) - ) - name = name[len(prefix) + 1:] - name = name.replace(os.path.sep, '/') - return name - def _get_archive_name(self, path, parentdir, rootdir): # type: (str, str, str) -> str + + def _clean_zip_name(name, prefix): + # type: (str, str) -> str + assert name.startswith(prefix + os.path.sep), ( + "name {name!r} doesn't start with prefix {prefix!r}" + .format(**locals()) + ) + name = name[len(prefix) + 1:] + name = name.replace(os.path.sep, '/') + return name + path = os.path.join(parentdir, path) - name = self._clean_zip_name(path, rootdir) + name = _clean_zip_name(path, rootdir) return self.name + '/' + name - # TODO: Investigate if this should be kept in InstallRequirement - # Seems to be used only when VCS + downloads def archive(self, build_dir): # type: (str) -> None + """Saves archive to provided build_dir. + + Used for saving downloaded VCS requirements as part of `pip download`. + """ assert self.source_dir + create_archive = True - archive_name = '%s-%s.zip' % (self.name, self.metadata["version"]) + archive_name = '{}-{}.zip'.format(self.name, self.metadata["version"]) archive_path = os.path.join(build_dir, archive_name) + if os.path.exists(archive_path): response = ask_path_exists( - 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)bort ' % - display_path(archive_path), ('i', 'w', 'b', 'a')) + 'The file {} exists. (i)gnore, (w)ipe, ' + '(b)ackup, (a)bort '.format( + display_path(archive_path)), + ('i', 'w', 'b', 'a')) if response == 'i': create_archive = False elif response == 'w': @@ -873,32 +736,33 @@ class InstallRequirement(object): shutil.move(archive_path, dest_file) elif response == 'a': sys.exit(-1) - if create_archive: - zip = zipfile.ZipFile( - archive_path, 'w', zipfile.ZIP_DEFLATED, - allowZip64=True + + if not create_archive: + return + + zip_output = zipfile.ZipFile( + archive_path, 'w', zipfile.ZIP_DEFLATED, allowZip64=True, + ) + with zip_output: + dir = os.path.normcase( + os.path.abspath(self.unpacked_source_directory) ) - dir = os.path.normcase(os.path.abspath(self.setup_py_dir)) for dirpath, dirnames, filenames in os.walk(dir): - if 'pip-egg-info' in dirnames: - dirnames.remove('pip-egg-info') for dirname in dirnames: - dir_arcname = self._get_archive_name(dirname, - parentdir=dirpath, - rootdir=dir) + dir_arcname = self._get_archive_name( + dirname, parentdir=dirpath, rootdir=dir, + ) zipdir = zipfile.ZipInfo(dir_arcname + '/') zipdir.external_attr = 0x1ED << 16 # 0o755 - zip.writestr(zipdir, '') + zip_output.writestr(zipdir, '') for filename in filenames: - if filename == PIP_DELETE_MARKER_FILENAME: - continue - file_arcname = self._get_archive_name(filename, - parentdir=dirpath, - rootdir=dir) + file_arcname = self._get_archive_name( + filename, parentdir=dirpath, rootdir=dir, + ) filename = os.path.join(dirpath, filename) - zip.write(filename, file_arcname) - zip.close() - logger.info('Saved %s', display_path(archive_path)) + zip_output.write(filename, file_arcname) + + logger.info('Saved %s', display_path(archive_path)) def install( self, @@ -912,124 +776,130 @@ class InstallRequirement(object): pycompile=True # type: bool ): # type: (...) -> None + scheme = get_scheme( + self.name, + user=use_user_site, + home=home, + root=root, + isolated=self.isolated, + prefix=prefix, + ) + global_options = global_options if global_options is not None else [] if self.editable: - self.install_editable( - install_options, global_options, prefix=prefix, - ) - return - if self.is_wheel: - version = wheel.wheel_version(self.source_dir) - wheel.check_compatibility(version, self.name) - - self.move_wheel_files( - self.source_dir, root=root, prefix=prefix, home=home, - warn_script_location=warn_script_location, - use_user_site=use_user_site, pycompile=pycompile, + install_editable_legacy( + install_options, + global_options, + prefix=prefix, + home=home, + use_user_site=use_user_site, + name=self.name, + setup_py_path=self.setup_py_path, + isolated=self.isolated, + build_env=self.build_env, + unpacked_source_directory=self.unpacked_source_directory, ) self.install_succeeded = True return + if self.is_wheel: + assert self.local_file_path + direct_url = None + if self.original_link: + direct_url = direct_url_from_link( + self.original_link, + self.source_dir, + self.original_link_is_in_wheel_cache, + ) + install_wheel( + self.name, + self.local_file_path, + scheme=scheme, + req_description=str(self.req), + pycompile=pycompile, + warn_script_location=warn_script_location, + direct_url=direct_url, + requested=self.user_supplied, + ) + self.install_succeeded = True + return + + # TODO: Why don't we do this for editable installs? + # Extend the list of global and install options passed on to # the setup.py call with the ones from the requirements file. # Options specified in requirements file override those # specified on the command line, since the last option given # to setup.py is the one that is used. - global_options = list(global_options) + \ - self.options.get('global_options', []) - install_options = list(install_options) + \ - self.options.get('install_options', []) + global_options = list(global_options) + self.global_options + install_options = list(install_options) + self.install_options - if self.isolated: - # https://github.com/python/mypy/issues/1174 - global_options = global_options + ["--no-user-cfg"] # type: ignore - - with TempDirectory(kind="record") as temp_dir: - record_filename = os.path.join(temp_dir.path, 'install-record.txt') - install_args = self.get_install_args( - global_options, record_filename, root, prefix, pycompile, + try: + success = install_legacy( + install_options=install_options, + global_options=global_options, + root=root, + home=home, + prefix=prefix, + use_user_site=use_user_site, + pycompile=pycompile, + scheme=scheme, + setup_py_path=self.setup_py_path, + isolated=self.isolated, + req_name=self.name, + build_env=self.build_env, + unpacked_source_directory=self.unpacked_source_directory, + req_description=str(self.req), ) - msg = 'Running setup.py install for %s' % (self.name,) - with open_spinner(msg) as spinner: - with indent_log(): - with self.build_env: - call_subprocess( - install_args + install_options, - cwd=self.setup_py_dir, - spinner=spinner, - ) - - if not os.path.exists(record_filename): - logger.debug('Record file %s not found', record_filename) - return + except LegacyInstallFailure as exc: + self.install_succeeded = False + six.reraise(*exc.parent) + except Exception: self.install_succeeded = True + raise - def prepend_root(path): - # type: (str) -> str - if root is None or not os.path.isabs(path): - return path - else: - return change_root(root, path) + self.install_succeeded = success - with open(record_filename) as f: - for line in f: - directory = os.path.dirname(line) - if directory.endswith('.egg-info'): - egg_info_dir = prepend_root(directory) - break - else: - logger.warning( - 'Could not find .egg-info directory in install record' - ' for %s', - self, - ) - # FIXME: put the record somewhere - # FIXME: should this be an error? - return - new_lines = [] - with open(record_filename) as f: - for line in f: - filename = line.strip() - if os.path.isdir(filename): - filename += os.path.sep - new_lines.append( - os.path.relpath(prepend_root(filename), egg_info_dir) - ) - new_lines.sort() - ensure_dir(egg_info_dir) - inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt') - with open(inst_files_path, 'w') as f: - f.write('\n'.join(new_lines) + '\n') + if success and self.legacy_install_reason == 8368: + deprecated( + reason=( + "{} was installed using the legacy 'setup.py install' " + "method, because a wheel could not be built for it.". + format(self.name) + ), + replacement="to fix the wheel build issue reported above", + gone_in="21.0", + issue=8368, + ) - def get_install_args( - self, - global_options, # type: Sequence[str] - record_filename, # type: str - root, # type: Optional[str] - prefix, # type: Optional[str] - pycompile # type: bool - ): - # type: (...) -> List[str] - install_args = make_setuptools_shim_args(self.setup_py_path, - unbuffered_output=True) - install_args += list(global_options) + \ - ['install', '--record', record_filename] - install_args += ['--single-version-externally-managed'] - if root is not None: - install_args += ['--root', root] - if prefix is not None: - install_args += ['--prefix', prefix] +def check_invalid_constraint_type(req): + # type: (InstallRequirement) -> str - if pycompile: - install_args += ["--compile"] - else: - install_args += ["--no-compile"] + # Check for unsupported forms + problem = "" + if not req.name: + problem = "Unnamed requirements are not allowed as constraints" + elif req.link: + problem = "Links are not allowed as constraints" + elif req.extras: + problem = "Constraints cannot have extras" - if running_under_virtualenv(): - py_ver_str = 'python' + sysconfig.get_python_version() - install_args += ['--install-headers', - os.path.join(sys.prefix, 'include', 'site', - py_ver_str, self.name)] + if problem: + deprecated( + reason=( + "Constraints are only allowed to take the form of a package " + "name and a version specifier. Other forms were originally " + "permitted as an accident of the implementation, but were " + "undocumented. The new implementation of the resolver no " + "longer supports these forms." + ), + replacement=( + "replacing the constraint with a requirement." + ), + # No plan yet for when the new resolver becomes default + gone_in=None, + issue=8210 + ) - return install_args + return problem diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/req_set.py b/venv/lib/python3.8/site-packages/pip/_internal/req/req_set.py index d1966a4..ab4b6f8 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/req/req_set.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/req/req_set.py @@ -3,10 +3,12 @@ from __future__ import absolute_import import logging from collections import OrderedDict +from pip._vendor.packaging.utils import canonicalize_name + from pip._internal.exceptions import InstallationError -from pip._internal.utils.logging import indent_log +from pip._internal.models.wheel import Wheel +from pip._internal.utils import compatibility_tags from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.wheel import Wheel if MYPY_CHECK_RUNNING: from typing import Dict, Iterable, List, Optional, Tuple @@ -18,35 +20,49 @@ logger = logging.getLogger(__name__) class RequirementSet(object): - def __init__(self, require_hashes=False, check_supported_wheels=True): - # type: (bool, bool) -> None + def __init__(self, check_supported_wheels=True): + # type: (bool) -> None """Create a RequirementSet. """ self.requirements = OrderedDict() # type: Dict[str, InstallRequirement] # noqa: E501 - self.require_hashes = require_hashes self.check_supported_wheels = check_supported_wheels - # Mapping of alias: real_name - self.requirement_aliases = {} # type: Dict[str, str] self.unnamed_requirements = [] # type: List[InstallRequirement] - self.successfully_downloaded = [] # type: List[InstallRequirement] - self.reqs_to_cleanup = [] # type: List[InstallRequirement] def __str__(self): # type: () -> str - reqs = [req for req in self.requirements.values() - if not req.comes_from] - reqs.sort(key=lambda req: req.name.lower()) - return ' '.join([str(req.req) for req in reqs]) + requirements = sorted( + (req for req in self.requirements.values() if not req.comes_from), + key=lambda req: canonicalize_name(req.name), + ) + return ' '.join(str(req.req) for req in requirements) def __repr__(self): # type: () -> str - reqs = [req for req in self.requirements.values()] - reqs.sort(key=lambda req: req.name.lower()) - reqs_str = ', '.join([str(req.req) for req in reqs]) - return ('<%s object; %d requirement(s): %s>' - % (self.__class__.__name__, len(reqs), reqs_str)) + requirements = sorted( + self.requirements.values(), + key=lambda req: canonicalize_name(req.name), + ) + + format_string = '<{classname} object; {count} requirement(s): {reqs}>' + return format_string.format( + classname=self.__class__.__name__, + count=len(requirements), + reqs=', '.join(str(req.req) for req in requirements), + ) + + def add_unnamed_requirement(self, install_req): + # type: (InstallRequirement) -> None + assert not install_req.name + self.unnamed_requirements.append(install_req) + + def add_named_requirement(self, install_req): + # type: (InstallRequirement) -> None + assert install_req.name + + project_name = canonicalize_name(install_req.name) + self.requirements[project_name] = install_req def add_requirement( self, @@ -69,13 +85,11 @@ class RequirementSet(object): the requirement is not applicable, or [install_req] if the requirement is applicable and has just been added. """ - name = install_req.name - # If the markers do not match, ignore this requirement. if not install_req.match_markers(extras_requested): logger.info( "Ignoring %s: markers '%s' don't match your environment", - name, install_req.markers, + install_req.name, install_req.markers, ) return [], None @@ -85,27 +99,27 @@ class RequirementSet(object): # single requirements file. if install_req.link and install_req.link.is_wheel: wheel = Wheel(install_req.link.filename) - if self.check_supported_wheels and not wheel.supported(): + tags = compatibility_tags.get_supported() + if (self.check_supported_wheels and not wheel.supported(tags)): raise InstallationError( - "%s is not a supported wheel on this platform." % - wheel.filename + "{} is not a supported wheel on this platform.".format( + wheel.filename) ) # This next bit is really a sanity check. - assert install_req.is_direct == (parent_req_name is None), ( - "a direct req shouldn't have a parent and also, " - "a non direct req should have a parent" + assert not install_req.user_supplied or parent_req_name is None, ( + "a user supplied req shouldn't have a parent" ) # Unnamed requirements are scanned again and the requirement won't be # added as a dependency until after scanning. - if not name: - # url or path requirement w/o an egg fragment - self.unnamed_requirements.append(install_req) + if not install_req.name: + self.add_unnamed_requirement(install_req) return [install_req], None try: - existing_req = self.get_requirement(name) + existing_req = self.get_requirement( + install_req.name) # type: Optional[InstallRequirement] except KeyError: existing_req = None @@ -118,18 +132,15 @@ class RequirementSet(object): ) if has_conflicting_requirement: raise InstallationError( - "Double requirement given: %s (already in %s, name=%r)" - % (install_req, existing_req, name) + "Double requirement given: {} (already in {}, name={!r})" + .format(install_req, existing_req, install_req.name) ) # When no existing requirement exists, add the requirement as a # dependency and it will be scanned again after. if not existing_req: - self.requirements[name] = install_req - # FIXME: what about other normalizations? E.g., _ vs. -? - if name.lower() != name: - self.requirement_aliases[name.lower()] = name - # We'd want to rescan this requirements later + self.add_named_requirement(install_req) + # We'd want to rescan this requirement later return [install_req], install_req # Assume there's no need to scan, and that we've already @@ -145,15 +156,18 @@ class RequirementSet(object): ) ) if does_not_satisfy_constraint: - self.reqs_to_cleanup.append(install_req) raise InstallationError( - "Could not satisfy constraints for '%s': " + "Could not satisfy constraints for '{}': " "installation from path or url cannot be " - "constrained to a version" % name, + "constrained to a version".format(install_req.name) ) # If we're now installing a constraint, mark the existing # object for real installation. existing_req.constraint = False + # If we're now installing a user supplied requirement, + # mark the existing object as such. + if install_req.user_supplied: + existing_req.user_supplied = True existing_req.extras = tuple(sorted( set(existing_req.extras) | set(install_req.extras) )) @@ -165,29 +179,25 @@ class RequirementSet(object): # scanning again. return [existing_req], existing_req - def has_requirement(self, project_name): + def has_requirement(self, name): # type: (str) -> bool - name = project_name.lower() - if (name in self.requirements and - not self.requirements[name].constraint or - name in self.requirement_aliases and - not self.requirements[self.requirement_aliases[name]].constraint): - return True - return False + project_name = canonicalize_name(name) - def get_requirement(self, project_name): + return ( + project_name in self.requirements and + not self.requirements[project_name].constraint + ) + + def get_requirement(self, name): # type: (str) -> InstallRequirement - for name in project_name, project_name.lower(): - if name in self.requirements: - return self.requirements[name] - if name in self.requirement_aliases: - return self.requirements[self.requirement_aliases[name]] - raise KeyError("No project with the name %r" % project_name) + project_name = canonicalize_name(name) - def cleanup_files(self): - # type: () -> None - """Clean up files, remove builds.""" - logger.debug('Cleaning up...') - with indent_log(): - for req in self.reqs_to_cleanup: - req.remove_temporary_source() + if project_name in self.requirements: + return self.requirements[project_name] + + raise KeyError("No project with the name {name!r}".format(**locals())) + + @property + def all_requirements(self): + # type: () -> List[InstallRequirement] + return self.unnamed_requirements + list(self.requirements.values()) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/req_tracker.py b/venv/lib/python3.8/site-packages/pip/_internal/req/req_tracker.py index e36a3f6..13fb245 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/req/req_tracker.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/req/req_tracker.py @@ -6,35 +6,74 @@ import hashlib import logging import os +from pip._vendor import contextlib2 + from pip._internal.utils.temp_dir import TempDirectory from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: from types import TracebackType - from typing import Iterator, Optional, Set, Type + from typing import Dict, Iterator, Optional, Set, Type, Union from pip._internal.req.req_install import InstallRequirement from pip._internal.models.link import Link logger = logging.getLogger(__name__) +@contextlib.contextmanager +def update_env_context_manager(**changes): + # type: (str) -> Iterator[None] + target = os.environ + + # Save values from the target and change them. + non_existent_marker = object() + saved_values = {} # type: Dict[str, Union[object, str]] + for name, new_value in changes.items(): + try: + saved_values[name] = target[name] + except KeyError: + saved_values[name] = non_existent_marker + target[name] = new_value + + try: + yield + finally: + # Restore original values in the target. + for name, original_value in saved_values.items(): + if original_value is non_existent_marker: + del target[name] + else: + assert isinstance(original_value, str) # for mypy + target[name] = original_value + + +@contextlib.contextmanager +def get_requirement_tracker(): + # type: () -> Iterator[RequirementTracker] + root = os.environ.get('PIP_REQ_TRACKER') + with contextlib2.ExitStack() as ctx: + if root is None: + root = ctx.enter_context( + TempDirectory(kind='req-tracker') + ).path + ctx.enter_context(update_env_context_manager(PIP_REQ_TRACKER=root)) + logger.debug("Initialized build tracking at %s", root) + + with RequirementTracker(root) as tracker: + yield tracker + + class RequirementTracker(object): - def __init__(self): - # type: () -> None - self._root = os.environ.get('PIP_REQ_TRACKER') - if self._root is None: - self._temp_dir = TempDirectory(delete=False, kind='req-tracker') - self._temp_dir.create() - self._root = os.environ['PIP_REQ_TRACKER'] = self._temp_dir.path - logger.debug('Created requirements tracker %r', self._root) - else: - self._temp_dir = None - logger.debug('Re-using requirements tracker %r', self._root) + def __init__(self, root): + # type: (str) -> None + self._root = root self._entries = set() # type: Set[InstallRequirement] + logger.debug("Created build tracker: %s", self._root) def __enter__(self): # type: () -> RequirementTracker + logger.debug("Entered build tracker: %s", self._root) return self def __exit__( @@ -53,40 +92,55 @@ class RequirementTracker(object): def add(self, req): # type: (InstallRequirement) -> None - link = req.link - info = str(req) - entry_path = self._entry_path(link) + """Add an InstallRequirement to build tracking. + """ + + assert req.link + # Get the file to write information about this requirement. + entry_path = self._entry_path(req.link) + + # Try reading from the file. If it exists and can be read from, a build + # is already in progress, so a LookupError is raised. try: with open(entry_path) as fp: - # Error, these's already a build in progress. - raise LookupError('%s is already being built: %s' - % (link, fp.read())) + contents = fp.read() except IOError as e: + # if the error is anything other than "file does not exist", raise. if e.errno != errno.ENOENT: raise - assert req not in self._entries - with open(entry_path, 'w') as fp: - fp.write(info) - self._entries.add(req) - logger.debug('Added %s to build tracker %r', req, self._root) + else: + message = '{} is already being built: {}'.format( + req.link, contents) + raise LookupError(message) + + # If we're here, req should really not be building already. + assert req not in self._entries + + # Start tracking this requirement. + with open(entry_path, 'w') as fp: + fp.write(str(req)) + self._entries.add(req) + + logger.debug('Added %s to build tracker %r', req, self._root) def remove(self, req): # type: (InstallRequirement) -> None - link = req.link + """Remove an InstallRequirement from build tracking. + """ + + assert req.link + # Delete the created file and the corresponding entries. + os.unlink(self._entry_path(req.link)) self._entries.remove(req) - os.unlink(self._entry_path(link)) + logger.debug('Removed %s from build tracker %r', req, self._root) def cleanup(self): # type: () -> None for req in set(self._entries): self.remove(req) - remove = self._temp_dir is not None - if remove: - self._temp_dir.cleanup() - logger.debug('%s build tracker %r', - 'Removed' if remove else 'Cleaned', - self._root) + + logger.debug("Removed build tracker: %r", self._root) @contextlib.contextmanager def track(self, req): diff --git a/venv/lib/python3.8/site-packages/pip/_internal/req/req_uninstall.py b/venv/lib/python3.8/site-packages/pip/_internal/req/req_uninstall.py index 733301c..69719d3 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/req/req_uninstall.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/req/req_uninstall.py @@ -14,8 +14,15 @@ from pip._internal.locations import bin_py, bin_user from pip._internal.utils.compat import WINDOWS, cache_from_source, uses_pycache from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import ( - FakeFile, ask, dist_in_usersite, dist_is_local, egg_link_path, is_local, - normalize_path, renames, rmtree, + FakeFile, + ask, + dist_in_usersite, + dist_is_local, + egg_link_path, + is_local, + normalize_path, + renames, + rmtree, ) from pip._internal.utils.temp_dir import AdjacentTempDirectory, TempDirectory from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -52,7 +59,7 @@ def _script_names(dist, script_name, is_gui): def _unique(fn): - # type: (Callable) -> Callable[..., Iterator[Any]] + # type: (Callable[..., Iterator[Any]]) -> Callable[..., Iterator[Any]] @functools.wraps(fn) def unique(*args, **kw): # type: (Any, Any) -> Iterator[Any] @@ -220,10 +227,8 @@ class StashedUninstallPathSet(object): try: save_dir = AdjacentTempDirectory(path) # type: TempDirectory - save_dir.create() except OSError: save_dir = TempDirectory(kind="uninstall") - save_dir.create() self._save_dirs[os.path.normcase(path)] = save_dir return save_dir.path @@ -249,7 +254,6 @@ class StashedUninstallPathSet(object): # Did not find any suitable root head = os.path.dirname(path) save_dir = TempDirectory(kind='uninstall') - save_dir.create() self._save_dirs[head] = save_dir relpath = os.path.relpath(path, head) @@ -260,14 +264,16 @@ class StashedUninstallPathSet(object): def stash(self, path): # type: (str) -> str """Stashes the directory or file and returns its new location. + Handle symlinks as files to avoid modifying the symlink targets. """ - if os.path.isdir(path): + path_is_dir = os.path.isdir(path) and not os.path.islink(path) + if path_is_dir: new_path = self._get_directory_stash(path) else: new_path = self._get_file_stash(path) self._moves.append((path, new_path)) - if os.path.isdir(path) and os.path.isdir(new_path): + if (path_is_dir and os.path.isdir(new_path)): # If we're moving a directory, we need to # remove the destination first or else it will be # moved to inside the existing directory. @@ -289,12 +295,12 @@ class StashedUninstallPathSet(object): # type: () -> None """Undoes the uninstall by moving stashed files back.""" for p in self._moves: - logging.info("Moving to %s\n from %s", *p) + logger.info("Moving to %s\n from %s", *p) for new_path, path in self._moves: try: logger.debug('Replacing %s from %s', new_path, path) - if os.path.isfile(new_path): + if os.path.isfile(new_path) or os.path.islink(new_path): os.unlink(new_path) elif os.path.isdir(new_path): rmtree(new_path) @@ -534,8 +540,9 @@ class UninstallPathSet(object): with open(develop_egg_link, 'r') as fh: link_pointer = os.path.normcase(fh.readline().strip()) assert (link_pointer == dist.location), ( - 'Egg-link %s does not match installed location of %s ' - '(at %s)' % (link_pointer, dist.project_name, dist.location) + 'Egg-link {} does not match installed location of {} ' + '(at {})'.format( + link_pointer, dist.project_name, dist.location) ) paths_to_remove.add(develop_egg_link) easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), @@ -578,10 +585,6 @@ class UninstallPathSet(object): class UninstallPthEntries(object): def __init__(self, pth_file): # type: (str) -> None - if not os.path.isfile(pth_file): - raise UninstallationError( - "Cannot remove entries from nonexistent file %s" % pth_file - ) self.file = pth_file self.entries = set() # type: Set[str] self._saved_lines = None # type: Optional[List[bytes]] @@ -593,6 +596,11 @@ class UninstallPthEntries(object): # backslashes. This is correct for entries that describe absolute # paths outside of site-packages, but all the others use forward # slashes. + # os.path.splitdrive is used instead of os.path.isabs because isabs + # treats non-absolute paths with drive letter markings like c:foo\bar + # as absolute paths. It also does not recognize UNC paths if they don't + # have more than "\\sever\share". Valid examples: "\\server\share\" or + # "\\server\share\folder". Python 2.7.8+ support UNC in splitdrive. if WINDOWS and not os.path.splitdrive(entry)[0]: entry = entry.replace('\\', '/') self.entries.add(entry) @@ -600,6 +608,13 @@ class UninstallPthEntries(object): def remove(self): # type: () -> None logger.debug('Removing pth entries from %s:', self.file) + + # If the file doesn't exist, log a warning and return + if not os.path.isfile(self.file): + logger.warning( + "Cannot remove entries from nonexistent file %s", self.file + ) + return with open(self.file, 'rb') as fh: # windows uses '\r\n' with py3k, but uses '\n' with py2.x lines = fh.readlines() diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-38.pyc index 93a52b2eb89ba735ce06fbeb16f37f9b898b584e..245ef0be1f762e3c01ee4f5d40ead6fc42ef60ac 100644 GIT binary patch delta 91 zcmbQixR;S9l$V!_0SGkz?TVksW9^)zpOK%Ns$W!DTAG!qUtE-|pOToDnVOTFUsRG> ttXEN4rC*ksSEiqnnWSG(S(1^TXRK$TUz}Nzs#}nloSm4ST0Ak;7ywlCAG`nn delta 54 zcmdnXID?TVl$V!_0SKO#ZHSx5V=ZT^Uy@s(Uyxa#o0(T!l9-dDYm{M9T49`@2ojvw GWefnTJrPI% diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-38.pyc index be17a4801816a940768de424433943c84a144568..e8f3b9e52edd3787b400d86c34f08db348ae38de 100644 GIT binary patch literal 1379 zcmZ8h&2HO95aupPiKZplHP9AFFMBE=z!iby(nC=MaFeEJDin=#hz=#z+_kha|1i6> zBSYya*Ste~%q!$kc+IJg&>o7;kW!Img&obz&d$#_vwS`t#~!ZfKkw5=q33-d;p63_ z@DR8C9f|T5o??pUtl$gIi1%}U;p2ah2SvCTbh<Df7SSSNo{r!lo(=MYB3{IJHdN7T zZ*iz5DprTD*<z$dYK)q(@}GIrquamY^Odn8tCSWuAZsh!N{ee<stU9cvaXc@D~d`r zxfZSxw(2ZEy9P>eE%QcOAwkDkRn*d%3pBf|pfk!E09`s!o4Sv1A+4Up7*Y#UIy^E} zDKI?x1$_g?X|cc4Sh+;cOOUFOdA>OnS6bJmTy~zFw$6%LT6-GHQVES2yUtE1sA{x9 zukzAq5O`VaoMD<GTgh^%)hzxK;q|7hJ(3r;${VLsQ`8l>IqHVHx{*Ek<;AZr(z7Rz z&VEjRdp@84H2)E`!Bb;h#>mBP5g*__!)+%>oVRA%u6b`bLha8V<GllPEE~6~V9MJl z-Gyl<jn$B5GF#~s@!n-n%0j>MfX3x-nXIZpC$MRnwMi^wiISz!d4?HlJA1jgO%Q_X zBsUjHy}<zGgW0!<MMS@;Wp+haCfJ4~CETHudD1wO+hmu)tlmI`aXzQ)ITDX|@_E(? zq`*a^i6h(B_yn1KjawYiH~uS*GFSc;haa534&H`ae#dOj4^(i+Uh%EBI~#71zvHMO zbV5Xj!vI~jL#SkdeQpOz!i_0!<3EyFR+X1#nM@-XlFd<%SEnSv+JW6zr;C<XwheF$ zS8Zr49mM)&jRQjVZLqFPIrZTHUBHOQXG93!o*WWKy}O6ol7+{Q*%xfY0ybgY$^Uvz z*!+jbeH8Y1C`1AAU>zR8)eug%?5*#Db$G{AxMW{?&%7;LGOT<se|)|#{h(-aXDEG~ zju2~qa399#_BKeg%cg@}@zm9{M}&%pBQ$A4Tj$2XG4VrkVRemusa8bN0KU{uDs7KH zab&+nV@qQ|Wyk!4!B@yn+4*$R4%1XsS(>(SnqD^e_;s2B0nmp$#NnEy{dWUsPWoK$ zb?W`h&AOSJxedKzpx4q4b^^iJO<ad^7x$xdyB1M*+UUFfQ}jK(H+zC4h(<i(Bm4zy J<VRsV`WIc+X-fbA literal 8031 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 GB==uyBEA;@ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/compat.cpython-38.pyc index 41bcef20c0c3160564a0377740f2cff42efad242..39d4f87ebda369a05d986d81f7efe32ec083080e 100644 GIT binary patch delta 3418 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 Q`Bzv{(i&0~WlUB654Q3Gr~m)} delta 3529 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-38.pyc index 20c0b1402e5f26406f810ff59677f30ea5af4308..a5c9fdfde16e460aeec3e597081112247b329c53 100644 GIT binary patch delta 138 zcmZn{TO-CB%FD~e00f%<cEx|&$or7dIaNO+KQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+H_-G7pmmqvU2&CRavA q#mUvo-x!TH7qLuaVN96J!g-I;Zt`Q!5XM`REx5KYvQK`?B?SP@R4$7E delta 123 zcmZ1@)-J{y%FD~e00hs=HpF#q<bB8}=b&GbTcBT%S)iMlS6q^qlcQ^tVNzOQoSz61 zoNUOX!6>>pipiCcQFihI=5LI8o2Ro(WMPb%tjT$g(P}aWR|sR&<XEmP(#$+e9E==H YJWM={JWMQ%0?aJT0xT>nT!I`t0KE7f8vp<R diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-38.pyc index 3a54a36de67b0e8b7cbb10462acd2f0ea188d2bb..14aea42724aaa257b8d9b8947f29ecc4b698c8ba 100644 GIT binary patch delta 332 zcmYjLy-EW?7|eIKr^%VSgkXY*KcF@#%oakhuuw$s0b(64cT2M7vUlw6g+wBPudrYp z8^uCFyZ8pa!XnuF2o~zb$`9rnhJl%RFFd;bndiAVbM^1nHgcZ*7Wj^la~vCp7nQ;( zwA2iCDwk-2BIp;yNG@K(1Wohm1Gc@w)Q$4DkUq(!X;GD|8F=c=Iw<)^LJ%%#!cI6( zxI*^fm7`G<$UxhjWT5keg-JwNSEHCRq8B(3Su7uNeBD%kb#N~k5X{F}c22S2A&vq@ zNgO6z644lqFYu7CA&zMWr(@Ym*j{5F3o6NO8if6zO9W17irbV)!dVdGOx@U9%@q@# zbBf@?npJ~U!$qh-84#3z_@?pdRlQ(_kx=kuBelf|uc=S_zB+gR#{GL6>JBx30rw4G AnE(I) delta 235 zcmZ3>b%&ELl$V!_0SKO#ZHPO>vXL)@k&gw)Wd&kqATC}sxq#7w(Pi>ZMir(7?33R! zD)VwI;7s9I$XGD1glhr!WO=5Yj69QXGTBU4Wwv)>xy6!_Sdw^)IVnH)7DsAca(+r? zUivMToXot`l?+AFKqG(I>X+me=oe%b=w{{>mn7!o=o)31lvWt$CxQegUuHHk5&^1X zVC7-tVw7PLW0Yc)U=(0vVHEgZBnuSR6urd;G&eQ5xJVety~R|NS|mEznq|2tNEU1d L5+O7BJBt|r(ZW5; diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-38.pyc index be5631abc845aa362e26c5ecd1819ea6e51f5e5c..67c6f7876adaa8e2df68fbe1329de7ee4606288d 100644 GIT binary patch literal 5638 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 S6O~eMEVvL%20>5?D*ppv18oNY literal 623 zcmYjNy>8S%5T04vXLE9nQ-mlG4}gpKB%nlqghGRq6b=epk(1?JIOo<s*<FVO`5J<F zj=PeM=h=dW0`Uq|%sLUutmc1qzL|Nuvoi*w-{(J0etH1EoO7EPIWLLzBN7}qN|;}3 z95j=x^5z}__qhKR=03*^lHd<j!$E>J{wU0%&CPPrmApU~z9B+`i1-z;{zk%pL5^2U zPdLj6V~suZxboB&gQslc^{_=%8{GI?LR&F)@;Np^4_CNm$57w*!Hia8b%fyFd*FTs z@1SR{HlyB~uqSyMZOJ>^9c;F_<GM1!T2svZNP+_!($IqDJyLGq*U8w1%UtKiD9ajc zeYcMdrMM`y(aJ5N+?{NAnC&aoC_BoFLTIWyUL3x$Aum;(S0eG$$dyH{66a;pX|irE z^BvTLQh#5}Ox4cXvfV3dZE`919xtDE7f+hp1qWV~wGq@$&N@>{J^N5fp)a)&RoY(K zX|WW=>iXi%r&_3x+UkcSz#pT}e2g$=vBxmR3E2^wvU{kelurT`kg{Q;(_zC01eyMa lO9!~LXevq$`wqW`xo?TPu0`~$YIrBbb9X=OmUc+7_YW=Hmy!Sg diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-38.pyc index 9cf3b403156165ade0e082484e8e5859e58572c1..1210018663e567112b008c20af7b34879eb2ed96 100644 GIT binary patch delta 480 zcmW+yO>fgc5Zzg??X7DkG<*ouUZAMRMUAWGQmGs&B8n=ZfQUjNAQ?Bip>AS3+I0$! z=m~CciS`e)x1P9gf*WU~o>6Z604{JxteKJKX`VE1-pu*JxmW3Uo`ZDwf4_!5-DzbB zUQTb{Xc|M3m|YVPH^m)>7#UiL-L(_irGS{ptoNup$81J5I&6+P8t2(Ob2YjQw~_Bn z&;B&S;2=wQAd2z$Fb<^X1uRNqKI~;8=d%8$m;^^WJqm{LelRNXgDh>-Hv<{xd~Fo< z2GJ`n)fZ?$Rs90Lv!i|H=nxnTu&9(<CRcKNVld+rPRJ>GfsfHK?4fjtpxn%@-0m9# zM{ENs^BF29o}#y)-I2-mBM~Q&DAYHju0CLQ&3qlFjg8jqVzV9IZ*{^4yLX%6lY5Wb zyANAFof)!_GddbZc|Q}0`h=fXFKa)tQhv{NfWYTV#xg)nZIX>^S2a0X7>TUMr3}+3 z;Zh&O#iDvgZo(~fMpo5t>jx~W@AlUEUMWQX3t2#cV6mbb-<vsM*dOO(!NX8sO^Iq* gJher4U`2hT*B6N<WK9<rQ=r(z1TGlVqBXky5Bwl`L;wH) delta 990 zcmZ8f(M}UV6rGu!-EK=;iUh>O=ms!x!J?ujiin97l&IB+h!%BIIxAh<-L11zAY=&- z_yLmrf%XqfeDMqPjStvp^vw_O%@@71C2E|_+&gpb%$;-3-Gki0Kz=!w%ODuvH{QMY zRM^iS$6Nc8qpPGzE0iIoG*wrtXc*ZVzX^NVOu2eRchi+LMoeYe8&t`#6w|@?u{6to z&$2$21)pO%mIt3_{j31KpOGbG4(z}Eabo7Ia9d|vPOIp6fv7f{#p(LR_SOZzD#7R@ zzJPPlPi)Rz25Q^G0(CIMUECpE^o;DF9lV0P;}i)+P@%q58W}!~k^G(_`N$I#Vt7i4 zd{R0(SX#1fm6xr%i#JNv<N1e6i}%ZAQ;WWm)xJSUA0+js-Y+U+823jmoyJ2^haSZv z(FZz?$D%KEVpowG9S#a!&JxVvHkcm05Ov9p5-P#CARUE~5Dg<iy99JnmXJ_GrK2(0 z#d|o!4dO2xB5Hz=h6;qW^7i=Y>knq#>MNhmt)44hc|K`An>u}c7cj^Bi)~+<-)h-4 zVKZaB>8#a^4Vwp!?-`qps2kHp&39YAXL}+rl3Y{C?K8%@FJ_EW!9uJiFgTgjOvQxT z5)-w0tZ!Di=XmQuOyw%hKWuxu!g1}D9v&->Ct`J-`|XxV`AHBU&U5>9+u=5|dU<n@ z*KymfmE@1H%XK)`GiiBYuvWKg4J#pU9g<J<9EK>;vzTHHlV1cTB^2)-!G&M^41{V# z9ylDbD}Oq10yYBep&b$uh8j9Q!r&(mID}4wcn^ADlJbH{xa@b5%T%~2*AvpnI{s%l zRIhH>7KmxIs=`@o+C9RL;AkKVLPWzlQ02u)Q9t9U=$m@=lKUr`N}`0H2gEGI8OwUv z7Hw`@7ME4<tTdz2j7N90g?q9-UX(`O_=ij)UZR^m>-wzSwC6CK2u8qUi4Giek_DLx OimvGe-Ova0W4{5jZRxiF diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-38.pyc index 512c48f08b843dbb7a2021de665477e1e8936b0d..1f6e43ebef7e4f73710add93db043ace209c37a6 100644 GIT binary patch delta 1789 zcmZux&2QX96rb_edYxUTgf!_#T0*Hx7lmC)dni>DwWS|Pflw0KL)2nid$PNU*WMj_ z(<Jq3K?!PlL7+K+#3eaYkV6kuPattY{1yHeDj{*C2g-Z1DG8{y=I42D-h1;t{b=;z zar;KGXc2fyfB)iK8F*|zqhs?xGBQVfGN<@-PW6X<)z{YPoaXDku}<c6X81YZTqkQ( zoKa2}_xnS@wS8rllny)zltD_j#h2>Q$-`jj+2@s7)L<39(rz!*D>3&fz8ltA;6*%P zad~-VwX(#*rAko0Q)#XwwJ1DYK3j?F346QgdW&wA#o{;hBrS=j>PS~XXLlYAzPMCa z@g0DKq%@&xN^B?KOG@LR4LVCUXnZt<Z=H0ML`~^}wni_J+hezs2c)BJ!1;o<nB(VL zWB18@Iu9}X%DS1Vmmt1W*&ySjHI~3`4QzBv>a<7UsuvIXqr-X?R(uqoN>Xxrs6$f< zcF6`gNEQvQrSw~+rOgtKDdEEaB_&hJ?__joTgg;6sPcn&B9BL4ms#UMJx;u+(VVyl zbZh_^1md^J>aj^Tu0ie`#|?eQDUSz{=LYcvY+mS;^vtTq^)OD{&|`cEP1@5@GSz4X ztii&B`5g1c4*--jd3&ZuNsaML4cXnySaO3li+di8q9nR?Hp}f?dJ3o*m5E|eP1C4+ zRgDf%iz@UGUA6amDKza~iDQDYoL`5UCOf8gBhHUkS;&@~d}31ksEwD=IDZpho9;=@ zu6&_q$MK?em|PZv`d2fklBrdel+<2C`5I)(3Ec+EtQuQ(dMdr3b}jYSV@C?QK@i<# z{xvWY%TCLQr~12tKLIVf2Wq=OW%o>oQ^xDBT%!cv#PI26E>*XvaE<*}P3#ruFuS9t z`er`WwkRd7&ssBywR19hOX;W`BQ-YrwxrEem3^{I2~JUKIVGC~@vHIh$i2>VsmQU* zWu>wl`U#`LPXJ4Fb0cPE%tyT8CgO+O$u2fgW_Y!BxEN<zHG(W-p)y^vG7YsMK~eJm z6byPb<}EsI)y1B1dKP9uRW>y-HEKgu2jEqx`MjW+v_NfTAJ8UUJv`a#M^8+c7f+Qy ztE6yjSn2b&(ktIMGGx;K%{)H`yoPveK00<DPxAnvDx=Wm>jB#<FTThR)0X%?-#zy} z%I%a`Yr08|<BaST1~MD?Z%in+Dn79`PRPzGzeJ<Yal$BEWju16u6S-;eoF>J`4kGj zOv7}XJ5dxk&bkQuUZefu>%MaL2uhzs7tAJ)nv5qayn?*b2<H(naE@W{s|eCQw%wi> zcC&=jdmNUWHxs7KGR;ASTAG<R51EL%smmGnK#Dv$Q%LC4A=piqv`mlN-~qo5BuB@x z;*|?GKc1QT^s+N~VRlkRwN10U<9LA^$Bxr;0jFKce<S`Z-l)hts62<<8HD!`E+D+5 zq~D3Q{l?7?@bp83j}WF2WNI+@thjTb#{x*-9xK>&@@FG`egKsG`9a)9A;+(aKkQ-s w3~=X!)&Db{5x@73?w8T+I?_v>_^bcOuwI}AMWZ8X0sc_7QqVQsQuncc0FQo)KmY&$ delta 1282 zcmZ`(-EJF26rR~XuO0u8;-pEN(2%w?8_~E;BcLKc(>9fJlOmc{!73eXy%XES^{!{v zPFk&r)CSaCaDnCp(n=sjY9&x5u6PC>U|#?sAwjQ@dc`^8iiAjbwcpO1Ip25wcK!XS z=M(vxxm<?8@3-!ccP<rv%D<xT-hnMA73z_S=Fy7o4SBj}Y}1OtP0#eKZSsg#EHCBR z+eFT37fkI2afV++T9Hym?&xowJO&D{J}gD|f>O{3&Nf<M<TjgUXX|sF%?rMZM){{c zMbF3)V@&>GZcZiI%(*1xHEKMJLV^4~9EVksp0Dv1-wedZv+`SO{`^riT3xr<;o%+? zBma6Uo}y&?QmpECT2V><ZGD|nEWO4fM;9Y<Cv|-KP?$m^WOX;JGsxB7;NBeQh8h5| z<gcmO;t#NDke(Kin0!ee(W~T(d0DjI-YQdqS7doK)`y`x59#NmonM7JMz67+5v5{H zG4ee#Hh1mVctR;@-)?^zrC*;++}3(}&x)<x%o7zM)<?;@CAyS&(BXDBCc6W%hCJLm z`h$m8>b$x>A%C{NyLdWWcCx~N6oo1@g_SfLcN4wEH<HXPY}TR>zDUw5_k;dY*x)W7 zr>8i!FtMujPHR0(jG7NKID;lrnGyrV5*_S^M^mg~3e2s!IAqpWm<MWz%_X)$^Hifp z;3{fzG_!hs9ITEeEO@9y_q6`}X3_B9frxWpTaiyQ&nMr*(=-53Rj$Tbqsb5Y%l5!g zx+-@Dwk9v4AIumYi4nL_U3`G_1LENPrimx6yqtaf4mM1jI^=`w0mfQ>>j4)&V{7uS z?BcXapNdcZk6|-**Y}%@txJ|WLGyAeH?uZ|T6Q4(fQ#t9IE`cnL6wD73d~u2grKA^ z;c7o&wZivW3<FHU9pb{KhLN!~nlWtK9(i#r{|#Ll1^cpNBxcxwXyO`dg^HiMws7nE zXG<%Kth{ietjgV^Nt&^0(+xw$`r%X%^xu%b7jBkRxw=T9N*SSq@IJzRc8Y^ld?oL_ zadK+`PcI`}LAZ*5ifWum?sdQ_Z$g(2s4St2lERz=xI=tNphhd3Qgt}vNe1T7i8_J< w6~9a|4UiPz|73=BdCT*~j4TX3qh<Na;KYzBem~EC7v;;rajMJ0ks-SL5B{1TCjbBd diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/logging.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/logging.cpython-38.pyc index 5e1caa1be3ec0edcbe1d6350adb614646fe0ec05..42a47066645d500e41a51941cfc6b065114b53e6 100644 GIT binary patch delta 1046 zcmYLHO>7%g5Z-xSukH1E?KqBqLSlREB&|tnM}(g$<$$1yK_HNzX<@6%a{XSDHEXZC zyD3RZ1;V*hNEOiti36xoIl-kuMo6?&Dj;#{feWHoT#z_{xPquc#n?r3pLX=keDl81 zo0*U5|J3!hSWK1ZtK7TZm|x!0XW*;7#pi0Bh#3KiOI)_qPSlK!anRN}F*7#Cimi9z zW_*l8_TI<dTOz{MKA5w0iATA%D{)O^`vEgAV()=l6j8Ei9^?A1WEQ$%9{&$z$IKE> z{Lf6>M}oDBe4bD8)Gm;&!KZkd?v_YD!?UEH6>_^w73O%3Pw$?T%z2_7;xk0e5Vb(m z0gBA>JVo*pIoPgH>|u%(c#&d75hj0;e1n(BFOB^}yv*mQ&|%JAktz%L8%!tJP+7HX zU%11_y6|6c*4Hu0YRfQGMc3POMT1*z1%~04V>@oM(<CgfI<DAB^sHXh+dR{AotE%C z$HgwY^Gvh0;dDgJ-QL`6TQ$#Z)p)aO3A^REzVNDB+dH-MqI<q(TW4y$ZGXe*E?1A# zJj)k{d(GDC&2`}+56r;|UJCpO&tg;l5MIQ4@;Nw;z2IN)8g3|+M<1uL`chx=p}~BR zr8aw0dO~7SgYBpsPDmh~lpZ7YK67Nu;7#S7WMCMlS2nCJ7hS*UTTU0B3LTx|r00#7 zB@_l77^uuGVKJA&tD#va;;m2$3TTuwNjE=A9sP`q1a6+vW(Nnt-vVq8evd2wgfJPc zLm$oP2Wp$0mHbd&x(v7<{UMjT;9op+!4=dEUhR0I<*h6&SC`IS#Gf=9uHtIUjwrU% zYT6zNUyr>6h^pR)H}JB48$QKT@iq8l@LBvIfP%wB9d2N0;!DCmPaK1921fEIz->G| zc^7`cS5y1&2d+(h4%bjke*t0qI&Hx|E@n={UA&aJ#sYvV*|+KTjqC{qFqq6`01~)3 z-2ip)?)0%Bl=1t5F*%%gFy@9$8zNl%v+y0H@n&%VSMZ#1JnPET4KqI4i3SarJ8spp zw%j1zF^W{-Z)2YNQYhu|>C%=`pj`KTyj998r4h{IucaqR$S519MmpZhWHc6r2PeTa zrU4zs$m*a6n3@Raphh$%2PiL)h$ylGs-gzT2E$PqG(9XQ9|<eT=To6XB%%Easzek( delta 1017 zcmYLGTZkJ~7(V~WWM+0UnOwWcZa4Q$+jMu6vaM9;`sCUmeGprBg;+Ploas7YGFi{e zmRh!I-F*@f*B|kM6^e>bkP4B41z+{0FFuG86@1eNp9C#P75_x3bKv8<ob#QT`TuHO zYg%j3sKMy@`QoP==a%=aIk>&Q@Mr^=U_x=H`bNu`@UR={n=Ny~RX5tVTGoVXZmb_~ z?SJ6ED40Fh&NZ1ZL}ZVNh@IUHweq(4I>@|j5T=DGqI;}W@N{AQ$Fh^8E@JnS_`l5N zy`q>GNs-!vU1*g=S{$IWW$K?68S2m2O0PmU%!{m;p=7N}(X2Q~(Lst1QFNG`IgukL zN6wL6jl84e<wb$Kf~}KYAYBwC(xr)B6lGDNx+THSv04>>g;@<o>S@OfFv}Y!_{gw5 ze_PsZ;mA?K-+pFG4!XAQx81?!rY&nQ(z^q9AUpjIapm+t+IX3NmtScF{jJ89v$f=S ze$a8<rR8T&Y+pJ)=!{K#Gc*q;@pkB2cm&^2-h(sP2tNmp<Mr@eSjTtN+G3ri6flML zV27P#oVDSyAz+;Wdy+kHKY4JH;2-MC!0{FBRH{SAe0@A()dCI%mnBTZv-q1fGhHB8 z0zr+Bv`stc1c8)!yjscTVkFy+Cv1;gXW)6X%jX0PWQ7XS!wvloKrmb|4gsimHqwL_ z@ZHGU#*VTBJ?#RYX1HR0qw7_Fv3l&dz@t$YuHjozR}c4nyX#YpX*~w7;dyHpB>rUG zfsgQ$*cyB|48@NCgmE#^gj*OSJ||vJuEG~XKY0q^E4-Qd6Mn!O>3i@Ceth6FxPj-V zZ-IuXj01P^O6F<!9ly`q<bN}KHTx0(MrYRfJvOvwG5`_0GTVmm@W<KJ@ZmCjkZcf) z)b7B$;B1Zz;dFzCCtMyIr{jNz>%}i2fw|HU-p8*?PozdM8d|-5(e}hZ)_v!aRPdp4 zkzRD8T&<|%!t7*+;{~?#I&OVCa9qFMcl@r@#*Np@&#U=ye*ue?yjmL53a(aG=!UD6 z(o^HH_-6@BuEYP!<g~zqIOl{GSRro2LlziQCRai_sG<0js;FS7Mwl?HM-(tkT}dwM NYVu54i%-SPe*lBC17-jK diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/marker_files.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/marker_files.cpython-38.pyc deleted file mode 100644 index 1da829eaa8b041f0602524a9cbe3f71774ff363f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 763 zcmY*WO^?$s5Ve!^E20Y*B!ocnksjJg3)~P;K|m|EWoZ{J>VYU5yCl1A9NErxTXj!x z=P&FYxpC#M_{stC7dSCa1C)_woOqt!%)EKqZu<!A$Jy8S69=L1_GjDR4m|}|cOXzi zF-KEOovB0JsY^Xt`-G+*#S_%2{{#dYt-c*5sUowKGXiJMqnJ^WFv-aAlH_Slv><6l z(>T(M=!6j^3K=u9hyYz^e+%04{nr_!v}Mer_%!-ZlByz(nNqWY^CfU89dQmtN?64f z3ksAe=j53AlyRm3aIeTXydz6d5Xt7^tfIEfc6$EmF0|L(fV-BgOH;{WE#$JN&vlIL zfR(v$w!oi(t6c~ho#0DnjkJ5^Twv|3F~uL9&o?fdwR2h1^(&0g5qgN;pfP%fr~`_* zt0z7IJCbQ7g_UPhpUfk9%4DTu2AY-A{cEUvY4BpyX&6T+<K>Y~jCUf^%-lZMI|!c# z`@vxl4hQ2`!8m-ew;zlK!@zhVXPK!jY)y0Xf6y?POa?E5j%!+f3z?=>rzCG}dJ1Rx z7bM#-^RGc)&-1=jt=d9&H+fK;-xra+EImv!&14qwexXyY`hPfpRQ2+uxm9)&Zl(^m zvbKP#LqN41d=1O%@YSiAhJa@<s<a!Bb_LRc%5>S(R@i}rX+D|@T5$H*uCF9)I$pzb Fe*-;c+sgm| diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/misc.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/misc.cpython-38.pyc index 077cfb94ce31ac8c36449f6ae745c89bc1f638e1..272e1d8689497bcfed87b6ee6dd79f6dbd238170 100644 GIT binary patch literal 25054 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 E0gFoO@c;k- literal 29848 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 J_nA!U{{eMckH-K2 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/models.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/models.cpython-38.pyc index fab3506bdb078a406776c1a3fffd4c94191417a1..9a02208958b9715937d4445fcc34936e83a4f63c 100644 GIT binary patch delta 361 zcmW-cKTE?v7>9dzNlc4rhGIn!L~Ef%+N*SN)jBAM2-XfFv}tlQv1w9rX=&a3gQE~% zKZCfsx;r@v3IP{CfS*9bYi{`Qdw6-d=e^Wlb?rpcGAZ%Oe=qIlNV`UzD9Yg;jvjaC zt%aM^sb=MmQ{~0zrwJpp0z0Ul35Zw-BoXj{ij5An{Q;xFbTm45C=X0(8J@#j(+@(% ztCQ&k9W!rCU8hTj)6n+4dUcC(CuEhOVfKw4<M4?}NWaI;tUPnUv1A+E4hVE{0p;Kp zw~!29xPkJpN}8gNNewNDz7B7q$?z+3S#SZ4q)owBQccLt_#<IeuA#Mr&*a(sPH-{d zZ+W|%d@98mhdUk*4bNoBb#eC45BCQ{mkpQ~GE4XzC>y8*6NREIJSmlQoNl+d>xUfP Wl|4Nz<au6%iX@_9D9yEqtdf7+<6-~+ delta 301 zcmX@g-^kA!%FD~e00hs=HpB@|<ZWh*m^e|GsfA(UG8eXB22IghB9jYPL?-hv+D*=6 zG@k6mC_i}_qpF;>eo1bDenDn|Zf0I_Nn%cpu2F_bX@zlqB1mvDACm?n_hfUX5I$z0 z*_uqZSTYieGm2Oy&ty_&<e$8kDU6YMvIw&?qtN66R^`dn%!WYzT4n=AQ81s81;jUI zF<_Jc^V`Avoj|@cn9s`!lDB6yV3Y&$LxAj~K(-=SPLj=06KpBVEw0RBu<P=YQ;S%E z?zqM0mtW$UTac5Qo0?aWngVoBGn+P}%H;KI`i#7j@3ZMn7H4<kWd|xP76B3*j4aHP LbJ)X}nK_sN6%0%@ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/outdated.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/outdated.cpython-38.pyc deleted file mode 100644 index 232b67fd1e38322199e7df7c7bae60b30885f6e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4208 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-38.pyc index acd46708bf421eb481f58ef3bb5d1d50dc997c1e..bc7e039754c80aeb10a0dadc1df1d306bc63773b 100644 GIT binary patch delta 94 zcmZ20a!G_Il$V!_0SGkz?TX*XBgo>Mte=seo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5)wn&lHK0Jdu&#{d8T delta 57 zcmca4vQ~sAl$V!_0SKO#ZHU{*Bgi6Wr(cp=pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JoWSyl6#(TR5>o&G diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-38.pyc index 097b560af925bd7d705aa090c601461980c14b98..2fa6bce8f2a9038838b9c588b4926ba5054b785d 100644 GIT binary patch literal 2955 zcmZ`*%Z}W}6(!khHm6@BjqSwmP<HGY8pCcQHjqG*G2#f4EJPX^p3%Y+2Lzi{-A##2 zGF9YA-KI8%7g^YUkVUf84`h+0f&2uwUilXUInKF7_RL6Dim3Oks(VkJdy97lgRX|; z{`cShcQ0t#_tZI`TIl=%Sx!+fjp?y=Otlf~3**?(HExJq^jmRjVIG@{_Hlb*9b3A_ z%;OH*VixOstsmRWW*c8?#~ZB6dZ@ds&jzS_Y{)iI_t^z@5%qxShnoAs4>(IZaP?~I z*5{vo?qB)j>XkqFpWQh)xN&gZZB^#YNamG&JIkXq3F68=<bN%A67to5qD7X9+>uMU z>qwp#S)Qgb+If19C((-U(bOmqvy(r+{}*T9`SSfs;^Cg-`_m}qzQ14hr~5OW2YD`b z*6Vhi?KI=b_O3&fyR%;4?u9Ai`_qx&0o!p=WpNPlo$W8g7bLxn(%qYm!Z?+D$KB%( zc(@a$iwwu1W_<VbYzWirw(DLCO#+}vZPb*nAj@kga_z1@(;u2;OZ=iV8QQ<q&@-8l z8~<pP+CTM~p+<D^VQH52tRemgiPl;cD4Rj5Yg*Sqy3PUFDOwKnTLcMn08_ExNiLoH zQ9gI%JX$#SMUZ8j)#47J=0wR!8U}P1qpsTSau$eSQH%K5($9i?e%U#ibB9{Ei+XC5 zEvY@>>rF@JSI^>f62yM0E?Hi7K4vVc@7t-Ta1+#*PpwK)zmQz`VVX>%*=6U()HxCb zP-c+~CNY;z#)Tx-I3x#CNv;r$`UFO!eUVIx>68o3{ItlkB0slTz?gJ$*mEZ2NMIBy z<1nENImOS3!Pi>NmEjf0;cDP{N$QafUO1h(X4L{Qt1dC1$Vt=cf`54R=+37{w{PD( z^bbF|ajUYXsaOQL+pY%cw$|8I!>7TjhEKy#T|CpXF{Uzcx$==FHbJPzcgOQ|!N+1* z6nCSs6ycZ!NyOt2zQpC|!E!Y|;mOH3jwa)5na|VYgVFECGRnD^1>wD5#^pGRvauf} zITrwTT;x$K$7h`KCq)!9+<5iMBDlx>b2CIMpS1ZU5qt}UcEQ$7y{m7btXtwDM*qK8 z>|i$6O0CqH&Wvwc${Sh?9x`jyzERd5VS@MVgQG`==wXQ%ps0Eia3lBc&pD5AHSCeD zPIKFWBBK(l21@-k8LLgkWgaDpG(L-j7?LDGSr->*U*}mv&z+;}{SBlfiE2GVSKp6T zdkBjKArTrh(<F+*r!nA7be^)-C=CW{mDi(P+b9UhsvX8WNLFpn3*uP3h#|LiX4iA| ze)U<s)fP(Q>sT+zR;_)eabFj&U?l9&c#~|@r~1;%QCgy3nxda;U+K9{H&wQnj+^R~ z9R}@{?r5uf>Ok@%j3cHs<87wh+Yp~&tX;O7F-uI)$NREg3%l(Dx4GIr4y`(jpYS-% zRvXIO7|-Nm+w(HPr_qDQmgf=esU|;s454~v|B+D*Kb9Dy0CQD{RMeEP&!DR|qeSKa zbxjJPPPFPBDwB4u2H3ZbN8~HdMf>$<(QZ^$c;A5$lCE3p_Kj1-t-fI!rrrlr`cxa@ z9Y}=4k#(Z?gR*)v-a|w2#Q@^Q!xoS?)H~2Bb@48Gs1=5op?3ifZ*7dtXEV6;G+lK) z4{dJ}024(bQz23H*AmJL2!ZDs`Np$Go-QN5Kf$uv4=mWI89!NOx3-J?IwVhBCpy7G zR(5@dMrngr?V49;zYONQe2!xqDjt{*du5M2q=^UAYbykLcoT_PM;Nghw)M)IZF7uu z8n*SoG?FVZW|uYNdN}VJ^zl!l(Cd|5@ptrl_0CBb?S6BLCH{rpptKsvp5i(50N%rc zBlx6>M+!g{lsXN&R-mikh{J64w&%$xnZ?{Y!4n2zdi+5hZR4ef_Zm@{t-xiGrnz_x z*ofDuc!LV!5II5f=dtQ5e^~b}dR}v!H^*-bb{D_G0=IugcX0^=)n=`V`dLZ>5ZqLU zy+w1~dZ{A9+ZYhPrb0QzMz(B@dM-PD<^pTaB69o<yGV+Z+OQ9*H%_1%Pb_PwcMZ4z zxq-^$3Y2T|*oGKkmD@VFcFi3MVomib9;wmkBQ;Ww)F@wOfK^bqt*oX)z9h(j1Vu4H z;Y>vU6`57IQ$8n%pz4@&!CyTC>IJZWzergT^N;YKrAfLC+aMKR+%SGJdYX>!N%uAT LC3|RJvbX*RI@9}P delta 404 zcmYjNJ5K^Z5Wd-6j)MS3V>CfKZ7v2$)L0Q4f<ja<8VV@59PaWk2W;;43>fU}tjJYb zL22jTu(37SKVY=6v#`+xEu3V&nfd0Kxn2GYC(7}7R8#VL`B-})qr@ugjy96Hb*fS9 z;0~!0&?u>fs6llazJaPv;Y>3lZ_}ot33B1Ma#FFf`CRtUIxQEAh2nu?$x+)Aqvxj* zn%4aZR#sP<RqAaj5ZVPa;TjFWT^gb>qA&r_l!qx2WE>i56KJAePA$b(9|54dAc<>h zrY^BJ@MM(r*|{(5y2GSybI!U{>Z~u64es$u3Cp<0gwHKLu(&N+a^COO{YHbij9NWk za9>DbyG`#wbK~lyuUuMmc$&9)s@?U3?Kr8e){fub?%7i^D3E+|_OOTn1fsAA?wo2f tVc!h9BzTW*WegS1$l1VukWdL}WI8?SJ8TbB<i!*iD252cBIp}MegKo!Wa<C_ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-38.pyc index b8e5a2776a62f2c4a40fde523a908fe1814d3c51..0430fb710d5d9333bd749329c1435cd9068b733d 100644 GIT binary patch literal 7123 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 aWh{#R{hTj2HWp}Td{RG0$DO=A9{v|2@%|+M literal 4872 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 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/typing.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/typing.cpython-38.pyc index e1e6102043ebd84e2e8e57f508b66c512d2f1415..7d49d6410c3eba8d64ed5937df38820e3f00c48d 100644 GIT binary patch delta 337 zcmZqT+Rq&p%FD~e00f%<cEwk+GB7*_agYHMkmCTv#cDtzg&~R|g)xdTm9a=Fg(-zO zhbfmiikXoik0XU8g|&qtiaCWXm_d_$qm2hk{Y#(*22I9WEXj$*CCMOjU;xBs1Y&0( zE@lA|HH<)AjD9N_G?{L(mQ)s`#@}KsOUx-vEn)`Bf{9-V`WgATsrp5grKMS!`o%@b z`YDNdnW;I+`9&qE#d;N$Rr+PAd1d-JnMwKul_eR%`FX~A7W&1RC8@dviOJcC>8Zt& z&$Gx$6oIT)1z8Pt6C;@Kr^zz8okiB>78}s|%)E54Ai{PCiw&sh7Kcr4eoARhsvXD& Q#T-C_MTUi$g^`a101IJ9fdBvi delta 171 zcmdnb-Na=R%FD~e00hs=HpHc}Ffcp@agYHckmCTv#XLYFg&~R|g)xdTg(;XplX+v9 z2aC6#CetnU`1q9k<oNhoLcWm!k@3zRuFl@^L7{$ro__8t8H$*JI>E#*YyFbk0{w!_ v0^Q8K;*!Li99^RflhO*~{6vu8WCK<?(OVogx%nxjIjMFan~Rx%1d9v+@pvb~ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/ui.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/ui.cpython-38.pyc deleted file mode 100644 index 100fce0b5ce53c0c4b575582f124e83e8c22f83a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11807 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 bj?)>&e?M}k3j1Ih9VpF}3Z=`XlaBenO<+{f diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-38.pyc index be71e695225701449366bca11ae6515b6b495fed..3d329564b9cc7fd30874a5659eef251c9a5c7556 100644 GIT binary patch literal 3358 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 W^~thZCpM(RT38Q*a5;Q8T>L*LR<79q literal 875 zcmZuv!EO^V5M6sWyW4~Ygi3|P#V1fulSsg+LKK0N8$Hl)$$^zqJBibccV&Ciw6v%2 zA>_!7@9~ub;uknEcB&*u%xcCvZ)QBRZ}!vvemwyBHUIJXOBe({owF+#oVTF*2n-7t z%7X#&CmvvbhJ%n{7Jdx|5sO$2&Kg5!K`Z_Z6~XDbv%69Q=RK%?4#orqF|@?0$?zGx zPq7IB0iEJycoC|n4rdYESG)dDCm<iWsgxvrRdFIl<dQ#AoTy4lA;&~WEf^=1%!M)) z&AFT(ksi%8Cxw}CbtyFO)crlSp*YR6Qt^>k^lf8EHNW$Et;i-5s;M!`hWbj|c%5dG zF*gqV9;g(?_vX(@*UZXpDatmqH#E=NFD9?5#mj;^&}$~7;Y!lHTN#n-?smLRd1W8p zjh|JLag}X@vE#`vD6ZoO9pDHn=l(;gThWHpci@;{ioRiQLlaGFE3`tlYc#%r6|V3t zGRZPf$37>$fw(&MM28!)PyR=?kd9g)l~BouEC_I8_>5>_I4SA*1s!wU@s-z4WYHey z#gOK07jAFDW?}lh)7GBFg|<;i&BP{5068;m6FSr$iCm3Mvuq@Co@F+g7DD=Ox3SO; zY+-xPC1taMWl(RMvdGpAebIJ7Y7a=U2U}XRP39p))&wVqsEHmTAovkrt=J}o?zmA@ l1AKMg8OO4p!RPEW@c)AElD>v<s+_+;kgFY@B6z~|!CxER<qH4+ diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/appdirs.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/appdirs.py index fb26111..3989ed3 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/appdirs.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/appdirs.py @@ -1,15 +1,17 @@ """ -This code was taken from https://github.com/ActiveState/appdirs and modified -to suit our purposes. +This code wraps the vendored appdirs module to so the return values are +compatible for the current pip code base. + +The intention is to rewrite current usages gradually, keeping the tests pass, +and eventually drop this after all usages are changed. """ + from __future__ import absolute_import import os -import sys -from pip._vendor.six import PY2, text_type +from pip._vendor import appdirs as _appdirs -from pip._internal.utils.compat import WINDOWS, expanduser from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: @@ -18,251 +20,25 @@ if MYPY_CHECK_RUNNING: def user_cache_dir(appname): # type: (str) -> str - r""" - Return full path to the user-specific cache dir for this application. - - "appname" is the name of application. - - Typical user cache directories are: - macOS: ~/Library/Caches/<AppName> - Unix: ~/.cache/<AppName> (XDG default) - Windows: C:\Users\<username>\AppData\Local\<AppName>\Cache - - On Windows the only suggestion in the MSDN docs is that local settings go - in the `CSIDL_LOCAL_APPDATA` directory. This is identical to the - non-roaming app data dir (the default returned by `user_data_dir`). Apps - typically put cache data somewhere *under* the given dir here. Some - examples: - ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache - ...\Acme\SuperApp\Cache\1.0 - - OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. - """ - if WINDOWS: - # Get the base path - path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) - - # When using Python 2, return paths as bytes on Windows like we do on - # other operating systems. See helper function docs for more details. - if PY2 and isinstance(path, text_type): - path = _win_path_to_bytes(path) - - # Add our app name and Cache directory to it - path = os.path.join(path, appname, "Cache") - elif sys.platform == "darwin": - # Get the base path - path = expanduser("~/Library/Caches") - - # Add our app name to it - path = os.path.join(path, appname) - else: - # Get the base path - path = os.getenv("XDG_CACHE_HOME", expanduser("~/.cache")) - - # Add our app name to it - path = os.path.join(path, appname) - - return path - - -def user_data_dir(appname, roaming=False): - # type: (str, bool) -> str - r""" - Return full path to the user-specific data dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "roaming" (boolean, default False) can be set True to use the Windows - roaming appdata directory. That means that for users on a Windows - network setup for roaming profiles, this user data will be - sync'd on login. See - <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> - for a discussion of issues. - - Typical user data directories are: - macOS: ~/Library/Application Support/<AppName> - if it exists, else ~/.config/<AppName> - Unix: ~/.local/share/<AppName> # or in - $XDG_DATA_HOME, if defined - Win XP (not roaming): C:\Documents and Settings\<username>\ ... - ...Application Data\<AppName> - Win XP (roaming): C:\Documents and Settings\<username>\Local ... - ...Settings\Application Data\<AppName> - Win 7 (not roaming): C:\\Users\<username>\AppData\Local\<AppName> - Win 7 (roaming): C:\\Users\<username>\AppData\Roaming\<AppName> - - For Unix, we follow the XDG spec and support $XDG_DATA_HOME. - That means, by default "~/.local/share/<AppName>". - """ - if WINDOWS: - const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" - path = os.path.join(os.path.normpath(_get_win_folder(const)), appname) - elif sys.platform == "darwin": - path = os.path.join( - expanduser('~/Library/Application Support/'), - appname, - ) if os.path.isdir(os.path.join( - expanduser('~/Library/Application Support/'), - appname, - ) - ) else os.path.join( - expanduser('~/.config/'), - appname, - ) - else: - path = os.path.join( - os.getenv('XDG_DATA_HOME', expanduser("~/.local/share")), - appname, - ) - - return path + return _appdirs.user_cache_dir(appname, appauthor=False) def user_config_dir(appname, roaming=True): # type: (str, bool) -> str - """Return full path to the user-specific config dir for this application. - - "appname" is the name of application. - If None, just the system directory is returned. - "roaming" (boolean, default True) can be set False to not use the - Windows roaming appdata directory. That means that for users on a - Windows network setup for roaming profiles, this user data will be - sync'd on login. See - <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> - for a discussion of issues. - - Typical user data directories are: - macOS: same as user_data_dir - Unix: ~/.config/<AppName> - Win *: same as user_data_dir - - For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. - That means, by default "~/.config/<AppName>". - """ - if WINDOWS: - path = user_data_dir(appname, roaming=roaming) - elif sys.platform == "darwin": - path = user_data_dir(appname) - else: - path = os.getenv('XDG_CONFIG_HOME', expanduser("~/.config")) - path = os.path.join(path, appname) - + path = _appdirs.user_config_dir(appname, appauthor=False, roaming=roaming) + if _appdirs.system == "darwin" and not os.path.isdir(path): + path = os.path.expanduser('~/.config/') + if appname: + path = os.path.join(path, appname) return path -# for the discussion regarding site_config_dirs locations +# for the discussion regarding site_config_dir locations # see <https://github.com/pypa/pip/issues/1733> def site_config_dirs(appname): # type: (str) -> List[str] - r"""Return a list of potential user-shared config dirs for this application. - - "appname" is the name of application. - - Typical user config directories are: - macOS: /Library/Application Support/<AppName>/ - Unix: /etc or $XDG_CONFIG_DIRS[i]/<AppName>/ for each value in - $XDG_CONFIG_DIRS - Win XP: C:\Documents and Settings\All Users\Application ... - ...Data\<AppName>\ - Vista: (Fail! "C:\ProgramData" is a hidden *system* directory - on Vista.) - Win 7: Hidden, but writeable on Win 7: - C:\ProgramData\<AppName>\ - """ - if WINDOWS: - path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) - pathlist = [os.path.join(path, appname)] - elif sys.platform == 'darwin': - pathlist = [os.path.join('/Library/Application Support', appname)] - else: - # try looking in $XDG_CONFIG_DIRS - xdg_config_dirs = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') - if xdg_config_dirs: - pathlist = [ - os.path.join(expanduser(x), appname) - for x in xdg_config_dirs.split(os.pathsep) - ] - else: - pathlist = [] - + dirval = _appdirs.site_config_dir(appname, appauthor=False, multipath=True) + if _appdirs.system not in ["win32", "darwin"]: # always look in /etc directly as well - pathlist.append('/etc') - - return pathlist - - -# -- Windows support functions -- - -def _get_win_folder_from_registry(csidl_name): - # type: (str) -> str - """ - This is a fallback technique at best. I'm not sure if using the - registry for this guarantees us the correct answer for all CSIDL_* - names. - """ - import _winreg - - shell_folder_name = { - "CSIDL_APPDATA": "AppData", - "CSIDL_COMMON_APPDATA": "Common AppData", - "CSIDL_LOCAL_APPDATA": "Local AppData", - }[csidl_name] - - key = _winreg.OpenKey( - _winreg.HKEY_CURRENT_USER, - r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" - ) - directory, _type = _winreg.QueryValueEx(key, shell_folder_name) - return directory - - -def _get_win_folder_with_ctypes(csidl_name): - # type: (str) -> str - csidl_const = { - "CSIDL_APPDATA": 26, - "CSIDL_COMMON_APPDATA": 35, - "CSIDL_LOCAL_APPDATA": 28, - }[csidl_name] - - buf = ctypes.create_unicode_buffer(1024) - ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) - - # Downgrade to short path name if have highbit chars. See - # <http://bugs.activestate.com/show_bug.cgi?id=85099>. - has_high_char = False - for c in buf: - if ord(c) > 255: - has_high_char = True - break - if has_high_char: - buf2 = ctypes.create_unicode_buffer(1024) - if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): - buf = buf2 - - return buf.value - - -if WINDOWS: - try: - import ctypes - _get_win_folder = _get_win_folder_with_ctypes - except ImportError: - _get_win_folder = _get_win_folder_from_registry - - -def _win_path_to_bytes(path): - """Encode Windows paths to bytes. Only used on Python 2. - - Motivation is to be consistent with other operating systems where paths - are also returned as bytes. This avoids problems mixing bytes and Unicode - elsewhere in the codebase. For more details and discussion see - <https://github.com/pypa/pip/issues/3463>. - - If encoding using ASCII and MBCS fails, return the original Unicode path. - """ - for encoding in ('ASCII', 'MBCS'): - try: - return path.encode(encoding) - except (UnicodeEncodeError, LookupError): - pass - return path + return dirval.split(os.pathsep) + ['/etc'] + return [dirval] diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/compat.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/compat.py index ec3995c..9a2bb78 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/compat.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/compat.py @@ -1,29 +1,33 @@ """Stuff that differs in different Python versions and platform distributions.""" + +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + from __future__ import absolute_import, division import codecs +import functools import locale import logging import os import shutil import sys -from pip._vendor.six import text_type -from pip._vendor.urllib3.util import IS_PYOPENSSL +from pip._vendor.six import PY2, text_type from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: - from typing import Optional, Text, Tuple, Union + from typing import Callable, Optional, Protocol, Text, Tuple, TypeVar, Union -try: - import _ssl # noqa -except ImportError: - ssl = None -else: - # This additional assignment was needed to prevent a mypy error. - ssl = _ssl + # Used in the @lru_cache polyfill. + F = TypeVar('F') + + class LruCache(Protocol): + def __call__(self, maxsize=None): + # type: (Optional[int]) -> Callable[[F], F] + raise NotImplementedError try: import ipaddress @@ -37,20 +41,14 @@ except ImportError: __all__ = [ - "ipaddress", "uses_pycache", "console_to_str", "native_str", + "ipaddress", "uses_pycache", "console_to_str", "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "get_terminal_size", - "get_extension_suffixes", ] logger = logging.getLogger(__name__) -HAS_TLS = (ssl is not None) or IS_PYOPENSSL - -if sys.version_info >= (3, 4): - uses_pycache = True - from importlib.util import cache_from_source -else: +if PY2: import imp try: @@ -60,27 +58,41 @@ else: cache_from_source = None uses_pycache = cache_from_source is not None - - -if sys.version_info >= (3, 5): - backslashreplace_decode = "backslashreplace" else: - # In version 3.4 and older, backslashreplace exists + uses_pycache = True + from importlib.util import cache_from_source + + +if PY2: + # In Python 2.7, backslashreplace exists # but does not support use for decoding. # We implement our own replace handler for this # situation, so that we can consistently use # backslash replacement for all versions. def backslashreplace_decode_fn(err): raw_bytes = (err.object[i] for i in range(err.start, err.end)) - if sys.version_info[0] == 2: - # Python 2 gave us characters - convert to numeric bytes - raw_bytes = (ord(b) for b in raw_bytes) - return u"".join(u"\\x%x" % c for c in raw_bytes), err.end + # Python 2 gave us characters - convert to numeric bytes + raw_bytes = (ord(b) for b in raw_bytes) + return u"".join(map(u"\\x{:x}".format, raw_bytes)), err.end codecs.register_error( "backslashreplace_decode", backslashreplace_decode_fn, ) backslashreplace_decode = "backslashreplace_decode" +else: + backslashreplace_decode = "backslashreplace" + + +def has_tls(): + # type: () -> bool + try: + import _ssl # noqa: F401 # ignore unused + return True + except ImportError: + pass + + from pip._vendor.urllib3.util import IS_PYOPENSSL + return IS_PYOPENSSL def str_to_display(data, desc=None): @@ -118,10 +130,11 @@ def str_to_display(data, desc=None): try: decoded_data = data.decode(encoding) except UnicodeDecodeError: - if desc is None: - desc = 'Bytes object' - msg_format = '{} does not appear to be encoded as %s'.format(desc) - logger.warning(msg_format, encoding) + logger.warning( + '%s does not appear to be encoded as %s', + desc or 'Bytes object', + encoding, + ) decoded_data = data.decode(encoding, errors=backslashreplace_decode) # Make sure we can print the output, by encoding it to the output @@ -156,22 +169,6 @@ def console_to_str(data): return str_to_display(data, desc='Subprocess output') -if sys.version_info >= (3,): - def native_str(s, replace=False): - # type: (str, bool) -> str - if isinstance(s, bytes): - return s.decode('utf-8', 'replace' if replace else 'strict') - return s - -else: - def native_str(s, replace=False): - # type: (str, bool) -> str - # Replace is ignored -- unicode to UTF-8 can't fail - if isinstance(s, text_type): - return s.encode('utf-8') - return s - - def get_path_uid(path): # type: (str) -> int """ @@ -197,23 +194,12 @@ def get_path_uid(path): else: # raise OSError for parity with os.O_NOFOLLOW above raise OSError( - "%s is a symlink; Will not return uid for symlinks" % path + "{} is a symlink; Will not return uid for symlinks".format( + path) ) return file_uid -if sys.version_info >= (3, 4): - from importlib.machinery import EXTENSION_SUFFIXES - - def get_extension_suffixes(): - return EXTENSION_SUFFIXES -else: - from imp import get_suffixes - - def get_extension_suffixes(): - return [suffix[0] for suffix in get_suffixes()] - - def expanduser(path): # type: (str) -> str """ @@ -282,12 +268,26 @@ else: return cr cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) if not cr: - try: - fd = os.open(os.ctermid(), os.O_RDONLY) - cr = ioctl_GWINSZ(fd) - os.close(fd) - except Exception: - pass + if sys.platform != "win32": + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + cr = ioctl_GWINSZ(fd) + os.close(fd) + except Exception: + pass if not cr: cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) return int(cr[1]), int(cr[0]) + + +# Fallback to noop_lru_cache in Python 2 +# TODO: this can be removed when python 2 support is dropped! +def noop_lru_cache(maxsize=None): + # type: (Optional[int]) -> Callable[[F], F] + def _wrapper(f): + # type: (F) -> F + return f + return _wrapper + + +lru_cache = getattr(functools, "lru_cache", noop_lru_cache) # type: LruCache diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/deprecation.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/deprecation.py index b9359bd..2f20cfd 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/deprecation.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/deprecation.py @@ -1,6 +1,10 @@ """ A module that implements tooling to enable easy warnings about deprecations. """ + +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + from __future__ import absolute_import import logging diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/encoding.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/encoding.py index 30139f2..5b83d61 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/encoding.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/encoding.py @@ -32,7 +32,9 @@ def auto_decode(data): # Lets check the first two lines as in PEP263 for line in data.split(b'\n')[:2]: if line[0:1] == b'#' and ENCODING_RE.search(line): - encoding = ENCODING_RE.search(line).groups()[0].decode('ascii') + result = ENCODING_RE.search(line) + assert result is not None + encoding = result.groups()[0].decode('ascii') return data.decode(encoding) return data.decode( locale.getpreferredencoding(False) or sys.getdefaultencoding(), diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/filesystem.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/filesystem.py index 1e6b033..303243f 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/filesystem.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/filesystem.py @@ -1,16 +1,42 @@ +import errno +import fnmatch import os import os.path +import random +import shutil +import stat +import sys +from contextlib import contextmanager +from tempfile import NamedTemporaryFile + +# NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import. +from pip._vendor.retrying import retry # type: ignore +from pip._vendor.six import PY2 from pip._internal.utils.compat import get_path_uid +from pip._internal.utils.misc import format_size +from pip._internal.utils.typing import MYPY_CHECK_RUNNING, cast + +if MYPY_CHECK_RUNNING: + from typing import Any, BinaryIO, Iterator, List, Union + + class NamedTemporaryFileResult(BinaryIO): + @property + def file(self): + # type: () -> BinaryIO + pass def check_path_owner(path): # type: (str) -> bool # If we don't have a way to check the effective uid of this process, then # we'll just assume that we own the directory. - if not hasattr(os, "geteuid"): + if sys.platform == "win32" or not hasattr(os, "geteuid"): return True + assert os.path.isabs(path) + previous = None while path != previous: if os.path.lexists(path): @@ -28,3 +54,171 @@ def check_path_owner(path): else: previous, path = path, os.path.dirname(path) return False # assume we don't own the path + + +def copy2_fixed(src, dest): + # type: (str, str) -> None + """Wrap shutil.copy2() but map errors copying socket files to + SpecialFileError as expected. + + See also https://bugs.python.org/issue37700. + """ + try: + shutil.copy2(src, dest) + except (OSError, IOError): + for f in [src, dest]: + try: + is_socket_file = is_socket(f) + except OSError: + # An error has already occurred. Another error here is not + # a problem and we can ignore it. + pass + else: + if is_socket_file: + raise shutil.SpecialFileError( + "`{f}` is a socket".format(**locals())) + + raise + + +def is_socket(path): + # type: (str) -> bool + return stat.S_ISSOCK(os.lstat(path).st_mode) + + +@contextmanager +def adjacent_tmp_file(path, **kwargs): + # type: (str, **Any) -> Iterator[NamedTemporaryFileResult] + """Return a file-like object pointing to a tmp file next to path. + + The file is created securely and is ensured to be written to disk + after the context reaches its end. + + kwargs will be passed to tempfile.NamedTemporaryFile to control + the way the temporary file will be opened. + """ + with NamedTemporaryFile( + delete=False, + dir=os.path.dirname(path), + prefix=os.path.basename(path), + suffix='.tmp', + **kwargs + ) as f: + result = cast('NamedTemporaryFileResult', f) + try: + yield result + finally: + result.file.flush() + os.fsync(result.file.fileno()) + + +_replace_retry = retry(stop_max_delay=1000, wait_fixed=250) + +if PY2: + @_replace_retry + def replace(src, dest): + # type: (str, str) -> None + try: + os.rename(src, dest) + except OSError: + os.remove(dest) + os.rename(src, dest) + +else: + replace = _replace_retry(os.replace) + + +# test_writable_dir and _test_writable_dir_win are copied from Flit, +# with the author's agreement to also place them under pip's license. +def test_writable_dir(path): + # type: (str) -> bool + """Check if a directory is writable. + + Uses os.access() on POSIX, tries creating files on Windows. + """ + # If the directory doesn't exist, find the closest parent that does. + while not os.path.isdir(path): + parent = os.path.dirname(path) + if parent == path: + break # Should never get here, but infinite loops are bad + path = parent + + if os.name == 'posix': + return os.access(path, os.W_OK) + + return _test_writable_dir_win(path) + + +def _test_writable_dir_win(path): + # type: (str) -> bool + # os.access doesn't work on Windows: http://bugs.python.org/issue2528 + # and we can't use tempfile: http://bugs.python.org/issue22107 + basename = 'accesstest_deleteme_fishfingers_custard_' + alphabet = 'abcdefghijklmnopqrstuvwxyz0123456789' + for _ in range(10): + name = basename + ''.join(random.choice(alphabet) for _ in range(6)) + file = os.path.join(path, name) + try: + fd = os.open(file, os.O_RDWR | os.O_CREAT | os.O_EXCL) + # Python 2 doesn't support FileExistsError and PermissionError. + except OSError as e: + # exception FileExistsError + if e.errno == errno.EEXIST: + continue + # exception PermissionError + if e.errno == errno.EPERM or e.errno == errno.EACCES: + # This could be because there's a directory with the same name. + # But it's highly unlikely there's a directory called that, + # so we'll assume it's because the parent dir is not writable. + # This could as well be because the parent dir is not readable, + # due to non-privileged user access. + return False + raise + else: + os.close(fd) + os.unlink(file) + return True + + # This should never be reached + raise EnvironmentError( + 'Unexpected condition testing for writable directory' + ) + + +def find_files(path, pattern): + # type: (str, str) -> List[str] + """Returns a list of absolute paths of files beneath path, recursively, + with filenames which match the UNIX-style shell glob pattern.""" + result = [] # type: List[str] + for root, _, files in os.walk(path): + matches = fnmatch.filter(files, pattern) + result.extend(os.path.join(root, f) for f in matches) + return result + + +def file_size(path): + # type: (str) -> Union[int, float] + # If it's a symlink, return 0. + if os.path.islink(path): + return 0 + return os.path.getsize(path) + + +def format_file_size(path): + # type: (str) -> str + return format_size(file_size(path)) + + +def directory_size(path): + # type: (str) -> Union[int, float] + size = 0.0 + for root, _dirs, files in os.walk(path): + for filename in files: + file_path = os.path.join(root, filename) + size += file_size(file_path) + return size + + +def format_directory_size(path): + # type: (str) -> str + return format_size(directory_size(path)) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/glibc.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/glibc.py index aa77d9b..3610424 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/glibc.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/glibc.py @@ -1,8 +1,10 @@ +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False + from __future__ import absolute_import import os -import re -import warnings +import sys from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -23,6 +25,8 @@ def glibc_version_string_confstr(): # 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 + if sys.platform == "win32": + return None try: # os.confstr("CS_GNU_LIBC_VERSION") returns a string like "glibc 2.17": _, version = os.confstr("CS_GNU_LIBC_VERSION").split() @@ -63,32 +67,6 @@ def glibc_version_string_ctypes(): return version_str -# Separated out from have_compatible_glibc for easier unit testing -def check_glibc_version(version_str, required_major, minimum_minor): - # type: (str, int, int) -> bool - # Parse string and check against requested 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<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str) - if not m: - warnings.warn("Expected glibc version with 2 components major.minor," - " got: %s" % version_str, RuntimeWarning) - return False - return (int(m.group("major")) == required_major and - int(m.group("minor")) >= minimum_minor) - - -def have_compatible_glibc(required_major, minimum_minor): - # type: (int, int) -> bool - version_str = glibc_version_string() - if version_str is None: - return False - return check_glibc_version(version_str, required_major, minimum_minor) - - # platform.libc_ver regularly returns completely nonsensical glibc # versions. E.g. on my computer, platform says: # diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/hashes.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/hashes.py index e8aabe1..d9f74a6 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/hashes.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/hashes.py @@ -5,7 +5,9 @@ import hashlib from pip._vendor.six import iteritems, iterkeys, itervalues from pip._internal.exceptions import ( - HashMismatch, HashMissing, InstallationError, + HashMismatch, + HashMissing, + InstallationError, ) from pip._internal.utils.misc import read_chunks from pip._internal.utils.typing import MYPY_CHECK_RUNNING @@ -44,6 +46,26 @@ class Hashes(object): """ self._allowed = {} if hashes is None else hashes + def __and__(self, other): + # type: (Hashes) -> Hashes + if not isinstance(other, Hashes): + return NotImplemented + + # If either of the Hashes object is entirely empty (i.e. no hash + # specified at all), all hashes from the other object are allowed. + if not other: + return self + if not self: + return other + + # Otherwise only hashes that present in both objects are allowed. + new = {} + for alg, values in iteritems(other._allowed): + if alg not in self._allowed: + continue + new[alg] = [v for v in values if v in self._allowed[alg]] + return Hashes(new) + @property def digest_count(self): # type: () -> int @@ -54,6 +76,7 @@ class Hashes(object): hash_name, # type: str hex_digest, # type: str ): + # type: (...) -> bool """Return whether the given hex digest is allowed.""" return hex_digest in self._allowed.get(hash_name, []) @@ -70,7 +93,9 @@ class Hashes(object): try: gots[hash_name] = hashlib.new(hash_name) except (ValueError, TypeError): - raise InstallationError('Unknown hash name: %s' % hash_name) + raise InstallationError( + 'Unknown hash name: {}'.format(hash_name) + ) for chunk in chunks: for hash in itervalues(gots): diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/logging.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/logging.py index 3fbec71..9a017cf 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/logging.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/logging.py @@ -1,3 +1,6 @@ +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + from __future__ import absolute_import import contextlib @@ -6,13 +9,13 @@ import logging import logging.handlers import os import sys -from logging import Filter +from logging import Filter, getLogger from pip._vendor.six import PY2 from pip._internal.utils.compat import WINDOWS from pip._internal.utils.deprecation import DEPRECATION_MSG_PREFIX -from pip._internal.utils.misc import ensure_dir, subprocess_logger +from pip._internal.utils.misc import ensure_dir try: import threading @@ -49,7 +52,7 @@ else: _log_state = threading.local() -_log_state.indentation = 0 +subprocess_logger = getLogger('pip.subprocessor') class BrokenStdoutLoggingError(Exception): @@ -100,6 +103,8 @@ def indent_log(num=2): A context manager which will cause the log output to be indented for any log messages emitted inside it. """ + # For thread-safety + _log_state.indentation = get_indentation() _log_state.indentation += num try: yield @@ -152,7 +157,7 @@ class IndentingFormatter(logging.Formatter): if self.add_timestamp: # TODO: Use Formatter.default_time_format after dropping PY2. t = self.formatTime(record, "%Y-%m-%dT%H:%M:%S") - prefix = '%s,%03d ' % (t, record.msecs) + prefix = '{t},{record.msecs:03.0f} '.format(**locals()) prefix += " " * get_indentation() formatted = "".join([ prefix + line diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/marker_files.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/marker_files.py deleted file mode 100644 index cb0c8eb..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/marker_files.py +++ /dev/null @@ -1,20 +0,0 @@ -import os.path - -DELETE_MARKER_MESSAGE = '''\ -This file is placed here by pip to indicate the source was put -here by pip. - -Once this package is successfully installed this source code will be -deleted (unless you remove this file). -''' -PIP_DELETE_MARKER_FILENAME = 'pip-delete-this-directory.txt' - - -def write_delete_marker_file(directory): - # type: (str) -> None - """ - Write the pip delete marker file into this directory. - """ - filepath = os.path.join(directory, PIP_DELETE_MARKER_FILENAME) - with open(filepath, 'w') as marker_fp: - marker_fp.write(DELETE_MARKER_MESSAGE) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/misc.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/misc.py index 61f74dc..5629c60 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/misc.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/misc.py @@ -1,43 +1,50 @@ +# The following comment should be removed at some point in the future. +# mypy: strict-optional=False +# mypy: disallow-untyped-defs=False + from __future__ import absolute_import import contextlib import errno import getpass +import hashlib import io -# we have a submodule named 'logging' which would shadow this if we used the -# regular name: -import logging as std_logging +import logging import os import posixpath -import re import shutil import stat -import subprocess import sys -import tarfile -import zipfile from collections import deque +from itertools import tee from pip._vendor import pkg_resources +from pip._vendor.packaging.utils import canonicalize_name # NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is # why we ignore the type on this import. from pip._vendor.retrying import retry # type: ignore from pip._vendor.six import PY2, text_type -from pip._vendor.six.moves import input, shlex_quote +from pip._vendor.six.moves import filter, filterfalse, input, map, zip_longest from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._vendor.six.moves.urllib import request as urllib_request from pip._vendor.six.moves.urllib.parse import unquote as urllib_unquote from pip import __version__ -from pip._internal.exceptions import CommandError, InstallationError -from pip._internal.locations import site_packages, user_site -from pip._internal.utils.compat import ( - WINDOWS, console_to_str, expanduser, stdlib_pkgs, str_to_display, +from pip._internal.exceptions import CommandError +from pip._internal.locations import ( + get_major_minor_version, + site_packages, + user_site, ) -from pip._internal.utils.marker_files import write_delete_marker_file -from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.compat import ( + WINDOWS, + expanduser, + stdlib_pkgs, + str_to_display, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING, cast from pip._internal.utils.virtualenv import ( - running_under_virtualenv, virtualenv_no_global, + running_under_virtualenv, + virtualenv_no_global, ) if PY2: @@ -47,60 +54,25 @@ else: if MYPY_CHECK_RUNNING: from typing import ( - Any, AnyStr, Container, Iterable, List, Mapping, Match, Optional, Text, - Tuple, Union, cast, + Any, AnyStr, Callable, Container, Iterable, Iterator, List, Optional, + Text, Tuple, TypeVar, Union, ) from pip._vendor.pkg_resources import Distribution - from pip._internal.models.link import Link - from pip._internal.utils.ui import SpinnerInterface VersionInfo = Tuple[int, int, int] -else: - # typing's cast() is needed at runtime, but we don't want to import typing. - # Thus, we use a dummy no-op version, which we tell mypy to ignore. - def cast(type_, value): # type: ignore - return value + T = TypeVar("T") __all__ = ['rmtree', 'display_path', 'backup_dir', 'ask', 'splitext', 'format_size', 'is_installable_dir', - 'is_svn_page', 'file_contents', - 'split_leading_dir', 'has_leading_dir', 'normalize_path', 'renames', 'get_prog', - 'unzip_file', 'untar_file', 'unpack_file', 'call_subprocess', 'captured_stdout', 'ensure_dir', - 'ARCHIVE_EXTENSIONS', 'SUPPORTED_EXTENSIONS', 'WHEEL_EXTENSION', 'get_installed_version', 'remove_auth_from_url'] -logger = std_logging.getLogger(__name__) -subprocess_logger = std_logging.getLogger('pip.subprocessor') - -LOG_DIVIDER = '----------------------------------------' - -WHEEL_EXTENSION = '.whl' -BZ2_EXTENSIONS = ('.tar.bz2', '.tbz') -XZ_EXTENSIONS = ('.tar.xz', '.txz', '.tlz', '.tar.lz', '.tar.lzma') -ZIP_EXTENSIONS = ('.zip', WHEEL_EXTENSION) -TAR_EXTENSIONS = ('.tar.gz', '.tgz', '.tar') -ARCHIVE_EXTENSIONS = ( - ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS) -SUPPORTED_EXTENSIONS = ZIP_EXTENSIONS + TAR_EXTENSIONS - -try: - import bz2 # noqa - SUPPORTED_EXTENSIONS += BZ2_EXTENSIONS -except ImportError: - logger.debug('bz2 module is not available') - -try: - # Only for Python 3.3+ - import lzma # noqa - SUPPORTED_EXTENSIONS += XZ_EXTENSIONS -except ImportError: - logger.debug('lzma module is not available') +logger = logging.getLogger(__name__) def get_pip_version(): @@ -110,7 +82,7 @@ def get_pip_version(): return ( 'pip {} from {} (python {})'.format( - __version__, pip_pkg_dir, sys.version[:3], + __version__, pip_pkg_dir, get_major_minor_version(), ) ) @@ -141,7 +113,8 @@ def ensure_dir(path): try: os.makedirs(path) except OSError as e: - if e.errno != errno.EEXIST: + # Windows can raise spurious ENOTEMPTY errors. See #6426. + if e.errno != errno.EEXIST and e.errno != errno.ENOTEMPTY: raise @@ -150,7 +123,7 @@ def get_prog(): try: prog = os.path.basename(sys.argv[0]) if prog in ('__main__.py', '-c'): - return "%s -m pip" % sys.executable + return "{} -m pip".format(sys.executable) else: return prog except (AttributeError, TypeError, IndexError): @@ -161,7 +134,7 @@ def get_prog(): # Retry every half second for up to 3 seconds @retry(stop_max_delay=3000, wait_fixed=500) def rmtree(dir, ignore_errors=False): - # type: (str, bool) -> None + # type: (Text, bool) -> None shutil.rmtree(dir, ignore_errors=ignore_errors, onerror=rmtree_errorhandler) @@ -170,8 +143,13 @@ def rmtree_errorhandler(func, path, exc_info): """On Windows, the files in .svn are read-only, so when rmtree() tries to remove them, an exception is thrown. We catch that here, remove the read-only attribute, and hopefully continue without problems.""" - # if file type currently read only - if os.stat(path).st_mode & stat.S_IREAD: + try: + has_attr_readonly = not (os.stat(path).st_mode & stat.S_IWRITE) + except (IOError, OSError): + # it's equivalent to os.path.exists + return + + if has_attr_readonly: # convert to read/write os.chmod(path, stat.S_IWRITE) # use the original function to repeat the operation @@ -253,8 +231,8 @@ def _check_no_input(message): """Raise an error if no input is allowed.""" if os.environ.get('PIP_NO_INPUT'): raise Exception( - 'No input was expected ($PIP_NO_INPUT set); question: %s' % - message + 'No input was expected ($PIP_NO_INPUT set); question: {}'.format( + message) ) @@ -267,8 +245,8 @@ def ask(message, options): response = response.strip().lower() if response not in options: print( - 'Your response (%r) was not one of the expected responses: ' - '%s' % (response, ', '.join(options)) + 'Your response ({!r}) was not one of the expected responses: ' + '{}'.format(response, ', '.join(options)) ) else: return response @@ -291,13 +269,28 @@ def ask_password(message): def format_size(bytes): # type: (float) -> str if bytes > 1000 * 1000: - return '%.1fMB' % (bytes / 1000.0 / 1000) + return '{:.1f} MB'.format(bytes / 1000.0 / 1000) elif bytes > 10 * 1000: - return '%ikB' % (bytes / 1000) + return '{} kB'.format(int(bytes / 1000)) elif bytes > 1000: - return '%.1fkB' % (bytes / 1000.0) + return '{:.1f} kB'.format(bytes / 1000.0) else: - return '%ibytes' % bytes + return '{} bytes'.format(int(bytes)) + + +def tabulate(rows): + # type: (Iterable[Iterable[Any]]) -> Tuple[List[str], List[int]] + """Return a list of formatted rows and a list of column sizes. + + For example:: + + >>> tabulate([['foobar', 2000], [0xdeadbeef]]) + (['foobar 2000', '3735928559'], [10, 4]) + """ + rows = [tuple(map(str, row)) for row in rows] + sizes = [max(map(len, col)) for col in zip_longest(*rows, fillvalue='')] + table = [" ".join(map(str.ljust, row, sizes)).rstrip() for row in rows] + return table, sizes def is_installable_dir(path): @@ -315,21 +308,6 @@ def is_installable_dir(path): return False -def is_svn_page(html): - # type: (Union[str, Text]) -> Optional[Match[Union[str, Text]]] - """ - Returns true if the page appears to be the index page of an svn repository - """ - return (re.search(r'<title>[^<]*Revision \d+:', html) and - re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I)) - - -def file_contents(filename): - # type: (str) -> Text - with open(filename, 'rb') as fp: - return fp.read().decode('utf-8') - - def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): """Yield pieces of data from a file-like object until EOF.""" while True: @@ -339,34 +317,6 @@ def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): yield chunk -def split_leading_dir(path): - # type: (Union[str, Text]) -> List[Union[str, Text]] - path = path.lstrip('/').lstrip('\\') - if '/' in path and (('\\' in path and path.find('/') < path.find('\\')) or - '\\' not in path): - return path.split('/', 1) - elif '\\' in path: - return path.split('\\', 1) - else: - return [path, ''] - - -def has_leading_dir(paths): - # type: (Iterable[Union[str, Text]]) -> bool - """Returns true if all the paths have the same leading path name - (i.e., everything is in one subdirectory in an archive)""" - common_prefix = None - for path in paths: - prefix, rest = split_leading_dir(path) - if not prefix: - return False - elif common_prefix is None: - common_prefix = prefix - elif prefix != common_prefix: - return False - return True - - def normalize_path(path, resolve_symlinks=True): # type: (str, bool) -> str """ @@ -416,10 +366,12 @@ def is_local(path): If we're not in a virtualenv, all paths are considered "local." + Caution: this function assumes the head of path has been normalized + with normalize_path. """ if not running_under_virtualenv(): return True - return normalize_path(path).startswith(normalize_path(sys.prefix)) + return path.startswith(normalize_path(sys.prefix)) def dist_is_local(dist): @@ -439,8 +391,7 @@ def dist_in_usersite(dist): """ Return True if given Distribution is installed in user site. """ - norm_path = normalize_path(dist_location(dist)) - return norm_path.startswith(normalize_path(user_site)) + return dist_location(dist).startswith(normalize_path(user_site)) def dist_in_site_packages(dist): @@ -449,9 +400,7 @@ def dist_in_site_packages(dist): Return True if given Distribution is installed in sysconfig.get_python_lib(). """ - return normalize_path( - dist_location(dist) - ).startswith(normalize_path(site_packages)) + return dist_location(dist).startswith(normalize_path(site_packages)) def dist_is_editable(dist): @@ -525,8 +474,7 @@ def get_installed_distributions( def user_test(d): return True - # because of pkg_resources vendoring, mypy cannot find stub in typeshed - return [d for d in working_set # type: ignore + return [d for d in working_set if local_test(d) and d.key not in skip and editable_test(d) and @@ -535,6 +483,57 @@ def get_installed_distributions( ] +def _search_distribution(req_name): + # type: (str) -> Optional[Distribution] + """Find a distribution matching the ``req_name`` in the environment. + + This searches from *all* distributions available in the environment, to + match the behavior of ``pkg_resources.get_distribution()``. + """ + # Canonicalize the name before searching in the list of + # installed distributions and also while creating the package + # dictionary to get the Distribution object + req_name = canonicalize_name(req_name) + packages = get_installed_distributions( + local_only=False, + skip=(), + include_editables=True, + editables_only=False, + user_only=False, + paths=None, + ) + pkg_dict = {canonicalize_name(p.key): p for p in packages} + return pkg_dict.get(req_name) + + +def get_distribution(req_name): + # type: (str) -> Optional[Distribution] + """Given a requirement name, return the installed Distribution object. + + This searches from *all* distributions available in the environment, to + match the behavior of ``pkg_resources.get_distribution()``. + """ + + # Search the distribution by looking through the working set + dist = _search_distribution(req_name) + + # If distribution could not be found, call working_set.require + # to update the working set, and try to find the distribution + # again. + # This might happen for e.g. when you install a package + # twice, once using setup.py develop and again using setup.py install. + # Now when run pip uninstall twice, the package gets removed + # from the working set in the first uninstall, so we have to populate + # the working set again so that pip knows about it and the packages + # gets picked up and is successfully uninstalled the second time too. + if not dist: + try: + pkg_resources.working_set.require(req_name) + except pkg_resources.DistributionNotFound: + return None + return _search_distribution(req_name) + + def egg_link_path(dist): # type: (Distribution) -> Optional[str] """ @@ -556,12 +555,9 @@ def egg_link_path(dist): """ sites = [] if running_under_virtualenv(): - if virtualenv_no_global(): - sites.append(site_packages) - else: - sites.append(site_packages) - if user_site: - sites.append(user_site) + sites.append(site_packages) + if not virtualenv_no_global() and user_site: + sites.append(user_site) else: if user_site: sites.append(user_site) @@ -582,383 +578,28 @@ def dist_location(dist): packages, where dist.location is the source code location, and we want to know where the egg-link file is. + The returned location is normalized (in particular, with symlinks removed). """ egg_link = egg_link_path(dist) if egg_link: - return egg_link - return dist.location + return normalize_path(egg_link) + return normalize_path(dist.location) -def current_umask(): - """Get the current umask which involves having to set it temporarily.""" - mask = os.umask(0) - os.umask(mask) - return mask - - -def unzip_file(filename, location, flatten=True): - # type: (str, str, bool) -> None - """ - Unzip the file (with path `filename`) to the destination `location`. All - files are written based on system defaults and umask (i.e. permissions are - not preserved), except that regular file members with any execute - permissions (user, group, or world) have "chmod +x" applied after being - written. Note that for windows, any execute changes using os.chmod are - no-ops per the python docs. - """ - ensure_dir(location) - zipfp = open(filename, 'rb') - try: - zip = zipfile.ZipFile(zipfp, allowZip64=True) - leading = has_leading_dir(zip.namelist()) and flatten - for info in zip.infolist(): - name = info.filename - fn = name - if leading: - fn = split_leading_dir(name)[1] - fn = os.path.join(location, fn) - dir = os.path.dirname(fn) - if fn.endswith('/') or fn.endswith('\\'): - # A directory - ensure_dir(fn) - else: - ensure_dir(dir) - # Don't use read() to avoid allocating an arbitrarily large - # chunk of memory for the file's content - fp = zip.open(name) - try: - with open(fn, 'wb') as destfp: - shutil.copyfileobj(fp, destfp) - finally: - fp.close() - mode = info.external_attr >> 16 - # if mode and regular file and any execute permissions for - # user/group/world? - if mode and stat.S_ISREG(mode) and mode & 0o111: - # make dest file have execute for user/group/world - # (chmod +x) no-op on windows per python docs - os.chmod(fn, (0o777 - current_umask() | 0o111)) - finally: - zipfp.close() - - -def untar_file(filename, location): - # type: (str, str) -> None - """ - Untar the file (with path `filename`) to the destination `location`. - All files are written based on system defaults and umask (i.e. permissions - are not preserved), except that regular file members with any execute - permissions (user, group, or world) have "chmod +x" applied after being - written. Note that for windows, any execute changes using os.chmod are - no-ops per the python docs. - """ - ensure_dir(location) - if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'): - mode = 'r:gz' - elif filename.lower().endswith(BZ2_EXTENSIONS): - mode = 'r:bz2' - elif filename.lower().endswith(XZ_EXTENSIONS): - mode = 'r:xz' - elif filename.lower().endswith('.tar'): - mode = 'r' - else: - logger.warning( - 'Cannot determine compression type for file %s', filename, - ) - mode = 'r:*' - tar = tarfile.open(filename, mode) - try: - leading = has_leading_dir([ - member.name for member in tar.getmembers() - ]) - for member in tar.getmembers(): - fn = member.name - if leading: - # https://github.com/python/mypy/issues/1174 - fn = split_leading_dir(fn)[1] # type: ignore - path = os.path.join(location, fn) - if member.isdir(): - ensure_dir(path) - elif member.issym(): - try: - # https://github.com/python/typeshed/issues/2673 - tar._extract_member(member, path) # type: ignore - except Exception as exc: - # Some corrupt tar files seem to produce this - # (specifically bad symlinks) - logger.warning( - 'In the tar file %s the member %s is invalid: %s', - filename, member.name, exc, - ) - continue - else: - try: - fp = tar.extractfile(member) - except (KeyError, AttributeError) as exc: - # Some corrupt tar files seem to produce this - # (specifically bad symlinks) - logger.warning( - 'In the tar file %s the member %s is invalid: %s', - filename, member.name, exc, - ) - continue - ensure_dir(os.path.dirname(path)) - with open(path, 'wb') as destfp: - shutil.copyfileobj(fp, destfp) - fp.close() - # Update the timestamp (useful for cython compiled files) - # https://github.com/python/typeshed/issues/2673 - tar.utime(member, path) # type: ignore - # member have any execute permissions for user/group/world? - if member.mode & 0o111: - # make dest file have execute for user/group/world - # no-op on windows per python docs - os.chmod(path, (0o777 - current_umask() | 0o111)) - finally: - tar.close() - - -def unpack_file( - filename, # type: str - location, # type: str - content_type, # type: Optional[str] - link # type: Optional[Link] -): - # type: (...) -> None - filename = os.path.realpath(filename) - if (content_type == 'application/zip' or - filename.lower().endswith(ZIP_EXTENSIONS) or - zipfile.is_zipfile(filename)): - unzip_file( - filename, - location, - flatten=not filename.endswith('.whl') - ) - elif (content_type == 'application/x-gzip' or - tarfile.is_tarfile(filename) or - filename.lower().endswith( - TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS)): - untar_file(filename, location) - elif (content_type and content_type.startswith('text/html') and - is_svn_page(file_contents(filename))): - # We don't really care about this - from pip._internal.vcs.subversion import Subversion - url = 'svn+' + link.url - Subversion().unpack(location, url=url) - else: - # FIXME: handle? - # FIXME: magic signatures? - logger.critical( - 'Cannot unpack file %s (downloaded from %s, content-type: %s); ' - 'cannot detect archive format', - filename, location, content_type, - ) - raise InstallationError( - 'Cannot determine archive format of %s' % location - ) - - -def format_command_args(args): - # type: (List[str]) -> str - """ - Format command arguments for display. - """ - return ' '.join(shlex_quote(arg) for arg in args) - - -def make_subprocess_output_error( - cmd_args, # type: List[str] - cwd, # type: Optional[str] - lines, # type: List[Text] - exit_status, # type: int -): - # type: (...) -> Text - """ - Create and return the error message to use to log a subprocess error - with command output. - - :param lines: A list of lines, each ending with a newline. - """ - command = format_command_args(cmd_args) - # Convert `command` and `cwd` to text (unicode in Python 2) so we can use - # them as arguments in the unicode format string below. This avoids - # "UnicodeDecodeError: 'ascii' codec can't decode byte ..." in Python 2 - # if either contains a non-ascii character. - command_display = str_to_display(command, desc='command bytes') - cwd_display = path_to_display(cwd) - - # We know the joined output value ends in a newline. - output = ''.join(lines) - msg = ( - # Use a unicode string to avoid "UnicodeEncodeError: 'ascii' - # codec can't encode character ..." in Python 2 when a format - # argument (e.g. `output`) has a non-ascii character. - u'Command errored out with exit status {exit_status}:\n' - ' command: {command_display}\n' - ' cwd: {cwd_display}\n' - 'Complete output ({line_count} lines):\n{output}{divider}' - ).format( - exit_status=exit_status, - command_display=command_display, - cwd_display=cwd_display, - line_count=len(lines), - output=output, - divider=LOG_DIVIDER, - ) - return msg - - -def call_subprocess( - cmd, # type: List[str] - show_stdout=False, # type: bool - cwd=None, # type: Optional[str] - on_returncode='raise', # type: str - extra_ok_returncodes=None, # type: Optional[Iterable[int]] - command_desc=None, # type: Optional[str] - extra_environ=None, # type: Optional[Mapping[str, Any]] - unset_environ=None, # type: Optional[Iterable[str]] - spinner=None # type: Optional[SpinnerInterface] -): - # type: (...) -> Text - """ - Args: - show_stdout: if true, use INFO to log the subprocess's stderr and - stdout streams. Otherwise, use DEBUG. Defaults to False. - extra_ok_returncodes: an iterable of integer return codes that are - acceptable, in addition to 0. Defaults to None, which means []. - unset_environ: an iterable of environment variable names to unset - prior to calling subprocess.Popen(). - """ - if extra_ok_returncodes is None: - extra_ok_returncodes = [] - if unset_environ is None: - unset_environ = [] - # Most places in pip use show_stdout=False. What this means is-- - # - # - We connect the child's output (combined stderr and stdout) to a - # single pipe, which we read. - # - We log this output to stderr at DEBUG level as it is received. - # - If DEBUG logging isn't enabled (e.g. if --verbose logging wasn't - # requested), then we show a spinner so the user can still see the - # subprocess is in progress. - # - If the subprocess exits with an error, we log the output to stderr - # at ERROR level if it hasn't already been displayed to the console - # (e.g. if --verbose logging wasn't enabled). This way we don't log - # the output to the console twice. - # - # If show_stdout=True, then the above is still done, but with DEBUG - # replaced by INFO. - if show_stdout: - # Then log the subprocess output at INFO level. - log_subprocess = subprocess_logger.info - used_level = std_logging.INFO - else: - # Then log the subprocess output using DEBUG. This also ensures - # it will be logged to the log file (aka user_log), if enabled. - log_subprocess = subprocess_logger.debug - used_level = std_logging.DEBUG - - # Whether the subprocess will be visible in the console. - showing_subprocess = subprocess_logger.getEffectiveLevel() <= used_level - - # Only use the spinner if we're not showing the subprocess output - # and we have a spinner. - use_spinner = not showing_subprocess and spinner is not None - - if command_desc is None: - command_desc = format_command_args(cmd) - - log_subprocess("Running command %s", command_desc) - env = os.environ.copy() - if extra_environ: - env.update(extra_environ) - for name in unset_environ: - env.pop(name, None) - try: - proc = subprocess.Popen( - cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, cwd=cwd, env=env, - ) - proc.stdin.close() - except Exception as exc: - subprocess_logger.critical( - "Error %s while executing command %s", exc, command_desc, - ) - raise - all_output = [] - while True: - # The "line" value is a unicode string in Python 2. - line = console_to_str(proc.stdout.readline()) - if not line: - break - line = line.rstrip() - all_output.append(line + '\n') - - # Show the line immediately. - log_subprocess(line) - # Update the spinner. - if use_spinner: - spinner.spin() - try: - proc.wait() - finally: - if proc.stdout: - proc.stdout.close() - proc_had_error = ( - proc.returncode and proc.returncode not in extra_ok_returncodes - ) - if use_spinner: - if proc_had_error: - spinner.finish("error") - else: - spinner.finish("done") - if proc_had_error: - if on_returncode == 'raise': - if not showing_subprocess: - # Then the subprocess streams haven't been logged to the - # console yet. - msg = make_subprocess_output_error( - cmd_args=cmd, - cwd=cwd, - lines=all_output, - exit_status=proc.returncode, - ) - subprocess_logger.error(msg) - exc_msg = ( - 'Command errored out with exit status {}: {} ' - 'Check the logs for full command output.' - ).format(proc.returncode, command_desc) - raise InstallationError(exc_msg) - elif on_returncode == 'warn': - subprocess_logger.warning( - 'Command "%s" had error code %s in %s', - command_desc, proc.returncode, cwd, - ) - elif on_returncode == 'ignore': - pass - else: - raise ValueError('Invalid value: on_returncode=%s' % - repr(on_returncode)) - return ''.join(all_output) - - -def _make_build_dir(build_dir): - os.makedirs(build_dir) - write_delete_marker_file(build_dir) +def write_output(msg, *args): + # type: (Any, Any) -> None + logger.info(msg, *args) class FakeFile(object): """Wrap a list of lines in an object with readline() to make ConfigParser happy.""" def __init__(self, lines): - self._gen = (l for l in lines) + self._gen = iter(lines) def readline(self): try: - try: - return next(self._gen) - except NameError: - return self._gen.next() + return next(self._gen) except StopIteration: return '' @@ -1013,26 +654,6 @@ def captured_stderr(): return captured_output('stderr') -class cached_property(object): - """A property that is only computed once per instance and then replaces - itself with an ordinary attribute. Deleting the attribute resets the - property. - - Source: https://github.com/bottlepy/bottle/blob/0.11.5/bottle.py#L175 - """ - - def __init__(self, func): - self.__doc__ = getattr(func, '__doc__') - self.func = func - - def __get__(self, obj, cls): - if obj is None: - # We're being accessed from the class itself, not from an object - return self - value = obj.__dict__[self.func.__name__] = self.func(obj) - return value - - def get_installed_version(dist_name, working_set=None): """Get the installed version of dist_name avoiding pkg_resources cache""" # Create a requirement that we'll look for inside of setuptools. @@ -1064,15 +685,38 @@ def enum(*sequential, **named): return type('Enum', (), enums) -def path_to_url(path): - # type: (Union[str, Text]) -> str +def build_netloc(host, port): + # type: (str, Optional[int]) -> str """ - Convert a path to a file: URL. The path will be made absolute and have - quoted path parts. + Build a netloc from a host-port pair """ - path = os.path.normpath(os.path.abspath(path)) - url = urllib_parse.urljoin('file:', urllib_request.pathname2url(path)) - return url + if port is None: + return host + if ':' in host: + # Only wrap host with square brackets when it is IPv6 + host = '[{}]'.format(host) + return '{}:{}'.format(host, port) + + +def build_url_from_netloc(netloc, scheme='https'): + # type: (str, str) -> str + """ + Build a full URL from a netloc. + """ + if netloc.count(':') >= 2 and '@' not in netloc and '[' not in netloc: + # It must be a bare IPv6 address, so wrap it with brackets. + netloc = '[{}]'.format(netloc) + return '{}://{}'.format(scheme, netloc) + + +def parse_netloc(netloc): + # type: (str) -> Tuple[str, Optional[int]] + """ + Return the host-port pair from a netloc. + """ + url = build_url_from_netloc(netloc) + parsed = urllib_parse.urlparse(url) + return parsed.hostname, parsed.port def split_auth_from_netloc(netloc): @@ -1106,15 +750,22 @@ def split_auth_from_netloc(netloc): def redact_netloc(netloc): # type: (str) -> str """ - Replace the password in a netloc with "****", if it exists. + Replace the sensitive data in a netloc with "****", if it exists. - For example, "user:pass@example.com" returns "user:****@example.com". + For example: + - "user:pass@example.com" returns "user:****@example.com" + - "accesstoken@example.com" returns "****@example.com" """ netloc, (user, password) = split_auth_from_netloc(netloc) if user is None: return netloc - password = '' if password is None else ':****' - return '{user}{password}@{netloc}'.format(user=urllib_parse.quote(user), + if password is None: + user = '****' + password = '' + else: + user = urllib_parse.quote(user) + password = ':****' + return '{user}{password}@{netloc}'.format(user=user, password=password, netloc=netloc) @@ -1166,13 +817,60 @@ def remove_auth_from_url(url): return _transform_url(url, _get_netloc)[0] -def redact_password_from_url(url): +def redact_auth_from_url(url): # type: (str) -> str """Replace the password in a given url with ****.""" return _transform_url(url, _redact_netloc)[0] +class HiddenText(object): + def __init__( + self, + secret, # type: str + redacted, # type: str + ): + # type: (...) -> None + self.secret = secret + self.redacted = redacted + + def __repr__(self): + # type: (...) -> str + return '<HiddenText {!r}>'.format(str(self)) + + def __str__(self): + # type: (...) -> str + return self.redacted + + # This is useful for testing. + def __eq__(self, other): + # type: (Any) -> bool + if type(self) != type(other): + return False + + # The string being used for redaction doesn't also have to match, + # just the raw, original string. + return (self.secret == other.secret) + + # We need to provide an explicit __ne__ implementation for Python 2. + # TODO: remove this when we drop PY2 support. + def __ne__(self, other): + # type: (Any) -> bool + return not self == other + + +def hide_value(value): + # type: (str) -> HiddenText + return HiddenText(value, redacted='****') + + +def hide_url(url): + # type: (str) -> HiddenText + redacted = redact_auth_from_url(url) + return HiddenText(url, redacted=redacted) + + def protect_pip_from_modification_on_windows(modifying_pip): + # type: (bool) -> None """Protection of pip.exe from modification on Windows On Windows, any operation modifying pip should be run as: @@ -1199,3 +897,63 @@ def protect_pip_from_modification_on_windows(modifying_pip): 'To modify pip, please run the following command:\n{}' .format(" ".join(new_command)) ) + + +def is_console_interactive(): + # type: () -> bool + """Is this console interactive? + """ + return sys.stdin is not None and sys.stdin.isatty() + + +def hash_file(path, blocksize=1 << 20): + # type: (Text, int) -> Tuple[Any, int] + """Return (hash, length) for path using hashlib.sha256() + """ + + h = hashlib.sha256() + length = 0 + with open(path, 'rb') as f: + for block in read_chunks(f, size=blocksize): + length += len(block) + h.update(block) + return h, length + + +def is_wheel_installed(): + """ + Return whether the wheel package is installed. + """ + try: + import wheel # noqa: F401 + except ImportError: + return False + + return True + + +def pairwise(iterable): + # type: (Iterable[Any]) -> Iterator[Tuple[Any, Any]] + """ + Return paired elements. + + For example: + s -> (s0, s1), (s2, s3), (s4, s5), ... + """ + iterable = iter(iterable) + return zip_longest(iterable, iterable) + + +def partition( + pred, # type: Callable[[T], bool] + iterable, # type: Iterable[T] +): + # type: (...) -> Tuple[Iterable[T], Iterable[T]] + """ + Use a predicate to partition entries into false entries and true entries, + like + + partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 + """ + t1, t2 = tee(iterable) + return filterfalse(pred, t1), filter(pred, t2) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/models.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/models.py index fccaf5d..d1c2f22 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/models.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/models.py @@ -1,5 +1,7 @@ """Utilities for defining models """ +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False import operator @@ -8,6 +10,8 @@ class KeyBasedCompareMixin(object): """Provides comparison capabilities that is based on a key """ + __slots__ = ['_compare_key', '_defining_class'] + def __init__(self, key, defining_class): self._compare_key = key self._defining_class = defining_class diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/outdated.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/outdated.py deleted file mode 100644 index 2b10aef..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/outdated.py +++ /dev/null @@ -1,178 +0,0 @@ -from __future__ import absolute_import - -import datetime -import json -import logging -import os.path -import sys - -from pip._vendor import lockfile, pkg_resources -from pip._vendor.packaging import version as packaging_version - -from pip._internal.cli.cmdoptions import make_search_scope -from pip._internal.index import PackageFinder -from pip._internal.models.selection_prefs import SelectionPreferences -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.filesystem import check_path_owner -from pip._internal.utils.misc import ensure_dir, get_installed_version -from pip._internal.utils.packaging import get_installer -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - import optparse - from typing import Any, Dict - from pip._internal.download import PipSession - - -SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ" - - -logger = logging.getLogger(__name__) - - -class SelfCheckState(object): - def __init__(self, cache_dir): - # type: (str) -> None - self.state = {} # type: Dict[str, Any] - self.statefile_path = None - - # Try to load the existing state - if cache_dir: - self.statefile_path = os.path.join(cache_dir, "selfcheck.json") - try: - with open(self.statefile_path) as statefile: - self.state = json.load(statefile)[sys.prefix] - except (IOError, ValueError, KeyError): - # Explicitly suppressing exceptions, since we don't want to - # error out if the cache file is invalid. - pass - - def save(self, pypi_version, current_time): - # type: (str, datetime.datetime) -> None - # If we do not have a path to cache in, don't bother saving. - if not self.statefile_path: - return - - # Check to make sure that we own the directory - if not check_path_owner(os.path.dirname(self.statefile_path)): - return - - # Now that we've ensured the directory is owned by this user, we'll go - # ahead and make sure that all our directories are created. - ensure_dir(os.path.dirname(self.statefile_path)) - - # Attempt to write out our version check file - with lockfile.LockFile(self.statefile_path): - if os.path.exists(self.statefile_path): - with open(self.statefile_path) as statefile: - state = json.load(statefile) - else: - state = {} - - state[sys.prefix] = { - "last_check": current_time.strftime(SELFCHECK_DATE_FMT), - "pypi_version": pypi_version, - } - - with open(self.statefile_path, "w") as statefile: - json.dump(state, statefile, sort_keys=True, - separators=(",", ":")) - - -def was_installed_by_pip(pkg): - # type: (str) -> bool - """Checks whether pkg was installed by pip - - This is used not to display the upgrade message when pip is in fact - installed by system package manager, such as dnf on Fedora. - """ - try: - dist = pkg_resources.get_distribution(pkg) - return "pip" == get_installer(dist) - except pkg_resources.DistributionNotFound: - return False - - -def pip_version_check(session, options): - # type: (PipSession, optparse.Values) -> None - """Check for an update for pip. - - Limit the frequency of checks to once per week. State is stored either in - the active virtualenv or in the user's USER_CACHE_DIR keyed off the prefix - of the pip script path. - """ - installed_version = get_installed_version("pip") - if not installed_version: - return - - pip_version = packaging_version.parse(installed_version) - pypi_version = None - - try: - state = SelfCheckState(cache_dir=options.cache_dir) - - current_time = datetime.datetime.utcnow() - # Determine if we need to refresh the state - if "last_check" in state.state and "pypi_version" in state.state: - last_check = datetime.datetime.strptime( - state.state["last_check"], - SELFCHECK_DATE_FMT - ) - if (current_time - last_check).total_seconds() < 7 * 24 * 60 * 60: - pypi_version = state.state["pypi_version"] - - # Refresh the version if we need to or just see if we need to warn - if pypi_version is None: - # Lets use PackageFinder to see what the latest pip version is - search_scope = make_search_scope(options, suppress_no_index=True) - - # Pass allow_yanked=False so we don't suggest upgrading to a - # yanked version. - selection_prefs = SelectionPreferences( - allow_yanked=False, - allow_all_prereleases=False, # Explicitly set to False - ) - - finder = PackageFinder.create( - search_scope=search_scope, - selection_prefs=selection_prefs, - trusted_hosts=options.trusted_hosts, - session=session, - ) - candidate = finder.find_candidates("pip").get_best() - if candidate is None: - return - pypi_version = str(candidate.version) - - # save that we've performed a check - state.save(pypi_version, current_time) - - remote_version = packaging_version.parse(pypi_version) - - local_version_is_older = ( - pip_version < remote_version and - pip_version.base_version != remote_version.base_version and - was_installed_by_pip('pip') - ) - - # Determine if our pypi_version is older - if not local_version_is_older: - return - - # Advise "python -m pip" on Windows to avoid issues - # with overwriting pip.exe. - if WINDOWS: - pip_cmd = "python -m pip" - else: - pip_cmd = "pip" - logger.warning( - "You are using pip version %s, however version %s is " - "available.\nYou should consider upgrading via the " - "'%s install --upgrade pip' command.", - pip_version, pypi_version, pip_cmd - ) - except Exception: - logger.debug( - "There was an error checking the latest version of pip", - exc_info=True, - ) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/setuptools_build.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/setuptools_build.py index 5895607..2a664b0 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/setuptools_build.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/setuptools_build.py @@ -3,7 +3,7 @@ import sys from pip._internal.utils.typing import MYPY_CHECK_RUNNING if MYPY_CHECK_RUNNING: - from typing import List + from typing import List, Optional, Sequence # Shim to wrap setup.py invocation with setuptools # @@ -20,17 +20,162 @@ _SETUPTOOLS_SHIM = ( ) -def make_setuptools_shim_args(setup_py_path, unbuffered_output=False): - # type: (str, bool) -> List[str] +def make_setuptools_shim_args( + setup_py_path, # type: str + global_options=None, # type: Sequence[str] + no_user_config=False, # type: bool + unbuffered_output=False # type: bool +): + # type: (...) -> List[str] """ Get setuptools command arguments with shim wrapped setup file invocation. :param setup_py_path: The path to setup.py to be wrapped. + :param global_options: Additional global options. + :param no_user_config: If True, disables personal user configuration. :param unbuffered_output: If True, adds the unbuffered switch to the argument list. """ args = [sys.executable] if unbuffered_output: - args.append('-u') - args.extend(['-c', _SETUPTOOLS_SHIM.format(setup_py_path)]) + args += ["-u"] + args += ["-c", _SETUPTOOLS_SHIM.format(setup_py_path)] + if global_options: + args += global_options + if no_user_config: + args += ["--no-user-cfg"] + return args + + +def make_setuptools_bdist_wheel_args( + setup_py_path, # type: str + global_options, # type: Sequence[str] + build_options, # type: Sequence[str] + destination_dir, # type: str +): + # type: (...) -> List[str] + # NOTE: Eventually, we'd want to also -S to the flags here, when we're + # isolating. Currently, it breaks Python in virtualenvs, because it + # relies on site.py to find parts of the standard library outside the + # virtualenv. + args = make_setuptools_shim_args( + setup_py_path, + global_options=global_options, + unbuffered_output=True + ) + args += ["bdist_wheel", "-d", destination_dir] + args += build_options + return args + + +def make_setuptools_clean_args( + setup_py_path, # type: str + global_options, # type: Sequence[str] +): + # type: (...) -> List[str] + args = make_setuptools_shim_args( + setup_py_path, + global_options=global_options, + unbuffered_output=True + ) + args += ["clean", "--all"] + return args + + +def make_setuptools_develop_args( + setup_py_path, # type: str + global_options, # type: Sequence[str] + install_options, # type: Sequence[str] + no_user_config, # type: bool + prefix, # type: Optional[str] + home, # type: Optional[str] + use_user_site, # type: bool +): + # type: (...) -> List[str] + assert not (use_user_site and prefix) + + args = make_setuptools_shim_args( + setup_py_path, + global_options=global_options, + no_user_config=no_user_config, + ) + + args += ["develop", "--no-deps"] + + args += install_options + + if prefix: + args += ["--prefix", prefix] + if home is not None: + args += ["--home", home] + + if use_user_site: + args += ["--user", "--prefix="] + + return args + + +def make_setuptools_egg_info_args( + setup_py_path, # type: str + egg_info_dir, # type: Optional[str] + no_user_config, # type: bool +): + # type: (...) -> List[str] + args = make_setuptools_shim_args( + setup_py_path, no_user_config=no_user_config + ) + + args += ["egg_info"] + + if egg_info_dir: + args += ["--egg-base", egg_info_dir] + + return args + + +def make_setuptools_install_args( + setup_py_path, # type: str + global_options, # type: Sequence[str] + install_options, # type: Sequence[str] + record_filename, # type: str + root, # type: Optional[str] + prefix, # type: Optional[str] + header_dir, # type: Optional[str] + home, # type: Optional[str] + use_user_site, # type: bool + no_user_config, # type: bool + pycompile # type: bool +): + # type: (...) -> List[str] + assert not (use_user_site and prefix) + assert not (use_user_site and root) + + args = make_setuptools_shim_args( + setup_py_path, + global_options=global_options, + no_user_config=no_user_config, + unbuffered_output=True + ) + args += ["install", "--record", record_filename] + args += ["--single-version-externally-managed"] + + if root is not None: + args += ["--root", root] + if prefix is not None: + args += ["--prefix", prefix] + if home is not None: + args += ["--home", home] + if use_user_site: + args += ["--user", "--prefix="] + + if pycompile: + args += ["--compile"] + else: + args += ["--no-compile"] + + if header_dir: + args += ["--install-headers", header_dir] + + args += install_options + return args diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/temp_dir.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/temp_dir.py index 2c81ad5..03aa828 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/temp_dir.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/temp_dir.py @@ -5,12 +5,95 @@ import itertools import logging import os.path import tempfile +from contextlib import contextmanager + +from pip._vendor.contextlib2 import ExitStack +from pip._vendor.six import ensure_text + +from pip._internal.utils.misc import enum, rmtree +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Dict, Iterator, Optional, TypeVar, Union + + _T = TypeVar('_T', bound='TempDirectory') -from pip._internal.utils.misc import rmtree logger = logging.getLogger(__name__) +# Kinds of temporary directories. Only needed for ones that are +# globally-managed. +tempdir_kinds = enum( + BUILD_ENV="build-env", + EPHEM_WHEEL_CACHE="ephem-wheel-cache", + REQ_BUILD="req-build", +) + + +_tempdir_manager = None # type: Optional[ExitStack] + + +@contextmanager +def global_tempdir_manager(): + # type: () -> Iterator[None] + global _tempdir_manager + with ExitStack() as stack: + old_tempdir_manager, _tempdir_manager = _tempdir_manager, stack + try: + yield + finally: + _tempdir_manager = old_tempdir_manager + + +class TempDirectoryTypeRegistry(object): + """Manages temp directory behavior + """ + + def __init__(self): + # type: () -> None + self._should_delete = {} # type: Dict[str, bool] + + def set_delete(self, kind, value): + # type: (str, bool) -> None + """Indicate whether a TempDirectory of the given kind should be + auto-deleted. + """ + self._should_delete[kind] = value + + def get_delete(self, kind): + # type: (str) -> bool + """Get configured auto-delete flag for a given TempDirectory type, + default True. + """ + return self._should_delete.get(kind, True) + + +_tempdir_registry = None # type: Optional[TempDirectoryTypeRegistry] + + +@contextmanager +def tempdir_registry(): + # type: () -> Iterator[TempDirectoryTypeRegistry] + """Provides a scoped global tempdir registry that can be used to dictate + whether directories should be deleted. + """ + global _tempdir_registry + old_tempdir_registry = _tempdir_registry + _tempdir_registry = TempDirectoryTypeRegistry() + try: + yield _tempdir_registry + finally: + _tempdir_registry = old_tempdir_registry + + +class _Default(object): + pass + + +_default = _Default() + + class TempDirectory(object): """Helper class that owns and cleans up a temporary directory. @@ -19,69 +102,101 @@ class TempDirectory(object): Attributes: path - Location to the created temporary directory or None + Location to the created temporary directory delete Whether the directory should be deleted when exiting (when used as a contextmanager) Methods: - create() - Creates a temporary directory and stores its path in the path - attribute. cleanup() - Deletes the temporary directory and sets path attribute to None + Deletes the temporary directory - When used as a context manager, a temporary directory is created on - entering the context and, if the delete attribute is True, on exiting the - context the created directory is deleted. + When used as a context manager, if the delete attribute is True, on + exiting the context the temporary directory is deleted. """ - def __init__(self, path=None, delete=None, kind="temp"): + def __init__( + self, + path=None, # type: Optional[str] + delete=_default, # type: Union[bool, None, _Default] + kind="temp", # type: str + globally_managed=False, # type: bool + ): super(TempDirectory, self).__init__() - if path is None and delete is None: - # If we were not given an explicit directory, and we were not given - # an explicit delete option, then we'll default to deleting. - delete = True + if delete is _default: + if path is not None: + # If we were given an explicit directory, resolve delete option + # now. + delete = False + else: + # Otherwise, we wait until cleanup and see what + # tempdir_registry says. + delete = None - self.path = path + if path is None: + path = self._create(kind) + + self._path = path + self._deleted = False self.delete = delete self.kind = kind + if globally_managed: + assert _tempdir_manager is not None + _tempdir_manager.enter_context(self) + + @property + def path(self): + # type: () -> str + assert not self._deleted, ( + "Attempted to access deleted path: {}".format(self._path) + ) + return self._path + def __repr__(self): + # type: () -> str return "<{} {!r}>".format(self.__class__.__name__, self.path) def __enter__(self): - self.create() + # type: (_T) -> _T return self def __exit__(self, exc, value, tb): - if self.delete: + # type: (Any, Any, Any) -> None + if self.delete is not None: + delete = self.delete + elif _tempdir_registry: + delete = _tempdir_registry.get_delete(self.kind) + else: + delete = True + + if delete: self.cleanup() - def create(self): + def _create(self, kind): + # type: (str) -> str """Create a temporary directory and store its path in self.path """ - if self.path is not None: - logger.debug( - "Skipped creation of temporary directory: {}".format(self.path) - ) - return # We realpath here because some systems have their default tmpdir # symlinked to another directory. This tends to confuse build # scripts, so we canonicalize the path by traversing potential # symlinks here. - self.path = os.path.realpath( - tempfile.mkdtemp(prefix="pip-{}-".format(self.kind)) + path = os.path.realpath( + tempfile.mkdtemp(prefix="pip-{}-".format(kind)) ) - logger.debug("Created temporary directory: {}".format(self.path)) + logger.debug("Created temporary directory: %s", path) + return path def cleanup(self): + # type: () -> None """Remove the temporary directory created and reset state """ - if self.path is not None and os.path.exists(self.path): - rmtree(self.path) - self.path = None + self._deleted = True + if os.path.exists(self._path): + # Make sure to pass unicode on Python 2 to make the contents also + # use unicode, ensuring non-ASCII names and can be represented. + rmtree(ensure_text(self._path)) class AdjacentTempDirectory(TempDirectory): @@ -106,11 +221,13 @@ class AdjacentTempDirectory(TempDirectory): LEADING_CHARS = "-~.=%0123456789" def __init__(self, original, delete=None): - super(AdjacentTempDirectory, self).__init__(delete=delete) + # type: (str, Optional[bool]) -> None self.original = original.rstrip('/\\') + super(AdjacentTempDirectory, self).__init__(delete=delete) @classmethod def _generate_names(cls, name): + # type: (str) -> Iterator[str] """Generates a series of temporary names. The algorithm replaces the leading characters in the name @@ -133,7 +250,8 @@ class AdjacentTempDirectory(TempDirectory): if new_name != name: yield new_name - def create(self): + def _create(self, kind): + # type: (str) -> str root, name = os.path.split(self.original) for candidate in self._generate_names(name): path = os.path.join(root, candidate) @@ -144,12 +262,13 @@ class AdjacentTempDirectory(TempDirectory): if ex.errno != errno.EEXIST: raise else: - self.path = os.path.realpath(path) + path = os.path.realpath(path) break - - if not self.path: + else: # Final fallback on the default behavior. - self.path = os.path.realpath( - tempfile.mkdtemp(prefix="pip-{}-".format(self.kind)) + path = os.path.realpath( + tempfile.mkdtemp(prefix="pip-{}-".format(kind)) ) - logger.debug("Created temporary directory: {}".format(self.path)) + + logger.debug("Created temporary directory: %s", path) + return path diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/typing.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/typing.py index 10170ce..8505a29 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/typing.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/typing.py @@ -27,3 +27,12 @@ Ref: https://github.com/python/mypy/issues/3216 """ MYPY_CHECK_RUNNING = False + + +if MYPY_CHECK_RUNNING: + from typing import cast +else: + # typing's cast() is needed at runtime, but we don't want to import typing. + # Thus, we use a dummy no-op version, which we tell mypy to ignore. + def cast(type_, value): # type: ignore + return value diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/ui.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/ui.py deleted file mode 100644 index 46390f4..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/ui.py +++ /dev/null @@ -1,424 +0,0 @@ -from __future__ import absolute_import, division - -import contextlib -import itertools -import logging -import sys -import time -from signal import SIGINT, default_int_handler, signal - -from pip._vendor import six -from pip._vendor.progress import HIDE_CURSOR, SHOW_CURSOR -from pip._vendor.progress.bar import Bar, FillingCirclesBar, IncrementalBar -from pip._vendor.progress.spinner import Spinner - -from pip._internal.utils.compat import WINDOWS -from pip._internal.utils.logging import get_indentation -from pip._internal.utils.misc import format_size -from pip._internal.utils.typing import MYPY_CHECK_RUNNING - -if MYPY_CHECK_RUNNING: - from typing import Any, Iterator, IO - -try: - from pip._vendor import colorama -# Lots of different errors can come from this, including SystemError and -# ImportError. -except Exception: - colorama = None - -logger = logging.getLogger(__name__) - - -def _select_progress_class(preferred, fallback): - encoding = getattr(preferred.file, "encoding", None) - - # If we don't know what encoding this file is in, then we'll just assume - # that it doesn't support unicode and use the ASCII bar. - if not encoding: - return fallback - - # Collect all of the possible characters we want to use with the preferred - # bar. - characters = [ - getattr(preferred, "empty_fill", six.text_type()), - getattr(preferred, "fill", six.text_type()), - ] - characters += list(getattr(preferred, "phases", [])) - - # Try to decode the characters we're using for the bar using the encoding - # of the given file, if this works then we'll assume that we can use the - # fancier bar and if not we'll fall back to the plaintext bar. - try: - six.text_type().join(characters).encode(encoding) - except UnicodeEncodeError: - return fallback - else: - return preferred - - -_BaseBar = _select_progress_class(IncrementalBar, Bar) # type: Any - - -class InterruptibleMixin(object): - """ - Helper to ensure that self.finish() gets called on keyboard interrupt. - - This allows downloads to be interrupted without leaving temporary state - (like hidden cursors) behind. - - This class is similar to the progress library's existing SigIntMixin - helper, but as of version 1.2, that helper has the following problems: - - 1. It calls sys.exit(). - 2. It discards the existing SIGINT handler completely. - 3. It leaves its own handler in place even after an uninterrupted finish, - which will have unexpected delayed effects if the user triggers an - unrelated keyboard interrupt some time after a progress-displaying - download has already completed, for example. - """ - - def __init__(self, *args, **kwargs): - """ - Save the original SIGINT handler for later. - """ - super(InterruptibleMixin, self).__init__(*args, **kwargs) - - self.original_handler = signal(SIGINT, self.handle_sigint) - - # If signal() returns None, the previous handler was not installed from - # Python, and we cannot restore it. This probably should not happen, - # but if it does, we must restore something sensible instead, at least. - # The least bad option should be Python's default SIGINT handler, which - # just raises KeyboardInterrupt. - if self.original_handler is None: - self.original_handler = default_int_handler - - def finish(self): - """ - Restore the original SIGINT handler after finishing. - - This should happen regardless of whether the progress display finishes - normally, or gets interrupted. - """ - super(InterruptibleMixin, self).finish() - signal(SIGINT, self.original_handler) - - def handle_sigint(self, signum, frame): - """ - Call self.finish() before delegating to the original SIGINT handler. - - This handler should only be in place while the progress display is - active. - """ - self.finish() - self.original_handler(signum, frame) - - -class SilentBar(Bar): - - def update(self): - pass - - -class BlueEmojiBar(IncrementalBar): - - suffix = "%(percent)d%%" - bar_prefix = " " - bar_suffix = " " - phases = (u"\U0001F539", u"\U0001F537", u"\U0001F535") # type: Any - - -class DownloadProgressMixin(object): - - def __init__(self, *args, **kwargs): - super(DownloadProgressMixin, self).__init__(*args, **kwargs) - self.message = (" " * (get_indentation() + 2)) + self.message - - @property - def downloaded(self): - return format_size(self.index) - - @property - def download_speed(self): - # Avoid zero division errors... - if self.avg == 0.0: - return "..." - return format_size(1 / self.avg) + "/s" - - @property - def pretty_eta(self): - if self.eta: - return "eta %s" % self.eta_td - return "" - - def iter(self, it, n=1): - for x in it: - yield x - self.next(n) - self.finish() - - -class WindowsMixin(object): - - def __init__(self, *args, **kwargs): - # The Windows terminal does not support the hide/show cursor ANSI codes - # even with colorama. So we'll ensure that hide_cursor is False on - # Windows. - # This call needs to go before the super() call, so that hide_cursor - # is set in time. The base progress bar class writes the "hide cursor" - # code to the terminal in its init, so if we don't set this soon - # enough, we get a "hide" with no corresponding "show"... - if WINDOWS and self.hide_cursor: - self.hide_cursor = False - - super(WindowsMixin, self).__init__(*args, **kwargs) - - # Check if we are running on Windows and we have the colorama module, - # if we do then wrap our file with it. - if WINDOWS and colorama: - self.file = colorama.AnsiToWin32(self.file) - # The progress code expects to be able to call self.file.isatty() - # but the colorama.AnsiToWin32() object doesn't have that, so we'll - # add it. - self.file.isatty = lambda: self.file.wrapped.isatty() - # The progress code expects to be able to call self.file.flush() - # but the colorama.AnsiToWin32() object doesn't have that, so we'll - # add it. - self.file.flush = lambda: self.file.wrapped.flush() - - -class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, - DownloadProgressMixin): - - file = sys.stdout - message = "%(percent)d%%" - suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s" - -# NOTE: The "type: ignore" comments on the following classes are there to -# work around https://github.com/python/typing/issues/241 - - -class DefaultDownloadProgressBar(BaseDownloadProgressBar, - _BaseBar): - pass - - -class DownloadSilentBar(BaseDownloadProgressBar, SilentBar): # type: ignore - pass - - -class DownloadBar(BaseDownloadProgressBar, # type: ignore - Bar): - pass - - -class DownloadFillingCirclesBar(BaseDownloadProgressBar, # type: ignore - FillingCirclesBar): - pass - - -class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, # type: ignore - BlueEmojiBar): - pass - - -class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin, - DownloadProgressMixin, Spinner): - - file = sys.stdout - suffix = "%(downloaded)s %(download_speed)s" - - def next_phase(self): - if not hasattr(self, "_phaser"): - self._phaser = itertools.cycle(self.phases) - return next(self._phaser) - - def update(self): - message = self.message % self - phase = self.next_phase() - suffix = self.suffix % self - line = ''.join([ - message, - " " if message else "", - phase, - " " if suffix else "", - suffix, - ]) - - self.writeln(line) - - -BAR_TYPES = { - "off": (DownloadSilentBar, DownloadSilentBar), - "on": (DefaultDownloadProgressBar, DownloadProgressSpinner), - "ascii": (DownloadBar, DownloadProgressSpinner), - "pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner), - "emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner) -} - - -def DownloadProgressProvider(progress_bar, max=None): - if max is None or max == 0: - return BAR_TYPES[progress_bar][1]().iter - else: - return BAR_TYPES[progress_bar][0](max=max).iter - - -################################################################ -# Generic "something is happening" spinners -# -# We don't even try using progress.spinner.Spinner here because it's actually -# simpler to reimplement from scratch than to coerce their code into doing -# what we need. -################################################################ - -@contextlib.contextmanager -def hidden_cursor(file): - # type: (IO) -> Iterator[None] - # The Windows terminal does not support the hide/show cursor ANSI codes, - # even via colorama. So don't even try. - if WINDOWS: - yield - # We don't want to clutter the output with control characters if we're - # writing to a file, or if the user is running with --quiet. - # See https://github.com/pypa/pip/issues/3418 - elif not file.isatty() or logger.getEffectiveLevel() > logging.INFO: - yield - else: - file.write(HIDE_CURSOR) - try: - yield - finally: - file.write(SHOW_CURSOR) - - -class RateLimiter(object): - def __init__(self, min_update_interval_seconds): - # type: (float) -> None - self._min_update_interval_seconds = min_update_interval_seconds - self._last_update = 0 # type: float - - def ready(self): - # type: () -> bool - now = time.time() - delta = now - self._last_update - return delta >= self._min_update_interval_seconds - - def reset(self): - # type: () -> None - self._last_update = time.time() - - -class SpinnerInterface(object): - def spin(self): - # type: () -> None - raise NotImplementedError() - - def finish(self, final_status): - # type: (str) -> None - raise NotImplementedError() - - -class InteractiveSpinner(SpinnerInterface): - def __init__(self, message, file=None, spin_chars="-\\|/", - # Empirically, 8 updates/second looks nice - min_update_interval_seconds=0.125): - self._message = message - if file is None: - file = sys.stdout - self._file = file - self._rate_limiter = RateLimiter(min_update_interval_seconds) - self._finished = False - - self._spin_cycle = itertools.cycle(spin_chars) - - self._file.write(" " * get_indentation() + self._message + " ... ") - self._width = 0 - - def _write(self, status): - assert not self._finished - # Erase what we wrote before by backspacing to the beginning, writing - # spaces to overwrite the old text, and then backspacing again - backup = "\b" * self._width - self._file.write(backup + " " * self._width + backup) - # Now we have a blank slate to add our status - self._file.write(status) - self._width = len(status) - self._file.flush() - self._rate_limiter.reset() - - def spin(self): - # type: () -> None - if self._finished: - return - if not self._rate_limiter.ready(): - return - self._write(next(self._spin_cycle)) - - def finish(self, final_status): - # type: (str) -> None - if self._finished: - return - self._write(final_status) - self._file.write("\n") - self._file.flush() - self._finished = True - - -# Used for dumb terminals, non-interactive installs (no tty), etc. -# We still print updates occasionally (once every 60 seconds by default) to -# act as a keep-alive for systems like Travis-CI that take lack-of-output as -# an indication that a task has frozen. -class NonInteractiveSpinner(SpinnerInterface): - def __init__(self, message, min_update_interval_seconds=60): - # type: (str, float) -> None - self._message = message - self._finished = False - self._rate_limiter = RateLimiter(min_update_interval_seconds) - self._update("started") - - def _update(self, status): - assert not self._finished - self._rate_limiter.reset() - logger.info("%s: %s", self._message, status) - - def spin(self): - # type: () -> None - if self._finished: - return - if not self._rate_limiter.ready(): - return - self._update("still running...") - - def finish(self, final_status): - # type: (str) -> None - if self._finished: - return - self._update("finished with status '%s'" % (final_status,)) - self._finished = True - - -@contextlib.contextmanager -def open_spinner(message): - # type: (str) -> Iterator[SpinnerInterface] - # Interactive spinner goes directly to sys.stdout rather than being routed - # through the logging system, but it acts like it has level INFO, - # i.e. it's only displayed if we're at level INFO or better. - # Non-interactive spinner goes through the logging system, so it is always - # in sync with logging configuration. - if sys.stdout.isatty() and logger.getEffectiveLevel() <= logging.INFO: - spinner = InteractiveSpinner(message) # type: SpinnerInterface - else: - spinner = NonInteractiveSpinner(message) - try: - with hidden_cursor(sys.stdout): - yield spinner - except KeyboardInterrupt: - spinner.finish("canceled") - raise - except Exception: - spinner.finish("error") - raise - else: - spinner.finish("done") diff --git a/venv/lib/python3.8/site-packages/pip/_internal/utils/virtualenv.py b/venv/lib/python3.8/site-packages/pip/_internal/utils/virtualenv.py index 380db1c..4a78128 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/utils/virtualenv.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/utils/virtualenv.py @@ -1,34 +1,119 @@ -import os.path +from __future__ import absolute_import + +import io +import logging +import os +import re import site import sys +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Optional + +logger = logging.getLogger(__name__) +_INCLUDE_SYSTEM_SITE_PACKAGES_REGEX = re.compile( + r"include-system-site-packages\s*=\s*(?P<value>true|false)" +) + + +def _running_under_venv(): + # type: () -> bool + """Checks if sys.base_prefix and sys.prefix match. + + This handles PEP 405 compliant virtual environments. + """ + return sys.prefix != getattr(sys, "base_prefix", sys.prefix) + + +def _running_under_regular_virtualenv(): + # type: () -> bool + """Checks if sys.real_prefix is set. + + This handles virtual environments created with pypa's virtualenv. + """ + # pypa/virtualenv case + return hasattr(sys, 'real_prefix') + def running_under_virtualenv(): # type: () -> bool + """Return True if we're running inside a virtualenv, False otherwise. """ - Return True if we're running inside a virtualenv, False otherwise. + return _running_under_venv() or _running_under_regular_virtualenv() + +def _get_pyvenv_cfg_lines(): + # type: () -> Optional[List[str]] + """Reads {sys.prefix}/pyvenv.cfg and returns its contents as list of lines + + Returns None, if it could not read/access the file. """ - if hasattr(sys, 'real_prefix'): - # pypa/virtualenv case - return True - elif sys.prefix != getattr(sys, "base_prefix", sys.prefix): - # PEP 405 venv + pyvenv_cfg_file = os.path.join(sys.prefix, 'pyvenv.cfg') + try: + # Although PEP 405 does not specify, the built-in venv module always + # writes with UTF-8. (pypa/pip#8717) + with io.open(pyvenv_cfg_file, encoding='utf-8') as f: + return f.read().splitlines() # avoids trailing newlines + except IOError: + return None + + +def _no_global_under_venv(): + # type: () -> bool + """Check `{sys.prefix}/pyvenv.cfg` for system site-packages inclusion + + PEP 405 specifies that when system site-packages are not supposed to be + visible from a virtual environment, `pyvenv.cfg` must contain the following + line: + + include-system-site-packages = false + + Additionally, log a warning if accessing the file fails. + """ + cfg_lines = _get_pyvenv_cfg_lines() + if cfg_lines is None: + # We're not in a "sane" venv, so assume there is no system + # site-packages access (since that's PEP 405's default state). + logger.warning( + "Could not access 'pyvenv.cfg' despite a virtual environment " + "being active. Assuming global site-packages is not accessible " + "in this environment." + ) return True + for line in cfg_lines: + match = _INCLUDE_SYSTEM_SITE_PACKAGES_REGEX.match(line) + if match is not None and match.group('value') == 'false': + return True return False +def _no_global_under_regular_virtualenv(): + # type: () -> bool + """Check if "no-global-site-packages.txt" exists beside site.py + + This mirrors logic in pypa/virtualenv for determining whether system + site-packages are visible in the virtual environment. + """ + site_mod_dir = os.path.dirname(os.path.abspath(site.__file__)) + no_global_site_packages_file = os.path.join( + site_mod_dir, 'no-global-site-packages.txt', + ) + return os.path.exists(no_global_site_packages_file) + + def virtualenv_no_global(): # type: () -> bool + """Returns a boolean, whether running in venv with no system site-packages. """ - Return True if in a venv and no system site packages. - """ - # this mirrors the logic in virtualenv.py for locating the - # no-global-site-packages.txt file - site_mod_dir = os.path.dirname(os.path.abspath(site.__file__)) - no_global_file = os.path.join(site_mod_dir, 'no-global-site-packages.txt') - if running_under_virtualenv() and os.path.isfile(no_global_file): - return True - else: - return False + # PEP 405 compliance needs to be checked first since virtualenv >=20 would + # return True for both checks, but is only able to use the PEP 405 config. + if _running_under_venv(): + return _no_global_under_venv() + + if _running_under_regular_virtualenv(): + return _no_global_under_regular_virtualenv() + + return False diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/__init__.py b/venv/lib/python3.8/site-packages/pip/_internal/vcs/__init__.py index cb573ab..2a4eb13 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/vcs/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/vcs/__init__.py @@ -2,11 +2,14 @@ # the vcs package don't need to import deeper than `pip._internal.vcs`. # (The test directory and imports protected by MYPY_CHECK_RUNNING may # still need to import from a vcs sub-package.) -from pip._internal.vcs.versioncontrol import ( # noqa: F401 - RemoteNotFoundError, make_vcs_requirement_url, vcs, -) # Import all vcs modules to register each VCS in the VcsSupport object. import pip._internal.vcs.bazaar import pip._internal.vcs.git import pip._internal.vcs.mercurial import pip._internal.vcs.subversion # noqa: F401 +from pip._internal.vcs.versioncontrol import ( # noqa: F401 + RemoteNotFoundError, + is_url, + make_vcs_requirement_url, + vcs, +) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-38.pyc index bee208cfe3793aff2c78244d577585e069c3df05..ec5c7e0f9d7643302eac2cc02fa38b86eed09b12 100644 GIT binary patch delta 254 zcmZ3({D_%1l$V!_0SGkz?TXKw$Sdn*1LUMIq%h_%L@|PCCMeAerCGo<Qx0n`TNGO^ zdlY*vM-)dcXA~zRP**U6Ci6>>d48HK6Z6G1*fNXbON(-DN#rJGr^c5h7snT+7M5lf zrRJvQm4IcKfr6S`6R#IeTxJ+r#0u29lA(wPNP&r83HllNxvBa^m8GRwnfk>=$@(dY zd6}s>$@xVksl|E~l~wv>sd;7kIhjfN1(hWk`FX~A7W&1RC8@dviOJcC>8Zt&iy1Wp P*?=Y%a{vhrMhFA|RcS^) delta 192 zcmaFFyoQ-Kl$V!_0SKO#ZHNn<$SWIV0pz4Gq%h_%<T6Gv<}yVw<uXSxGlImJa#*5R z!899`W{1)oK$<C-L6i9<$Sh6fTf#x9x%nlje)%PC`K5U&u0=)pMH45=Gy7?BPF7|# zoVck_dnH2=H&8K{_+_nMl3So(kXfLcnO9trn3JPxlwnd@VVs``5}dq}QA3awsJNH| LNQkg-FoGZeSrab7 diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-38.pyc index 3d993d5f1839cbc8aeb201ae0999e7176baa092f..56630abecf54c040264d1924bb7cfca86f4dd87f 100644 GIT binary patch delta 2029 zcmZuy-ESL35Wn5~@Yy~)wwp8`B&|y*jZ<P%^+U9@r8J<lv^A(7NVRBBSKrpT_Ri<* z-la+9$`9eGQYEUDkPrwGi3h}=z%vg;z!Pux(q|sv4?u`Aa|xx1YU{>xJHMTso%zl9 zmx=YM;<Z8{r@*K7&kuHE=y7q9{P_6b@c~g>#nt^>kZ<Kv-SDlT&?=;Q#xDj#t)Wym z{ZdeFm4iyFLKIfuU%|etzbhDS4F@Bwkrb2jGr{iG?o`hMezY|jjJ3u9PuIuU#0F`- zvY@z@TliFQ3#`1Rw#t*NvOdKoHwbK^SCm@u@wd|hnpmzUdcL!2_nc@kF?bMh#%d(7 z0_QHX+hGtmT^HUfm#%+w-JU=9{`>{|^0j93d~*R-^SH~7LObSujV8s985dsIoe#Sa z5B)@4ZVOm8KkP-Y>iCI%HSYQ7K6lP@T{hXh%2pyoyc<W0=exJVBzKuDZ^9)ZKa;Zj zm3&W1a)s_EyX4pO(EQEDVi>RnUyb8CUPJJ9!*#kI^V=bhn5eI;-ft|k?sCKTZZ&$V z(PG#=Tz{(}yok;9oc3L(!-V{UPU*X$MALFey;R?e#UhEy*)m6cQ&d4q${iNjw;aK2 zFxn39h*|kiJ(@GYI1i6FEq_uEOs?yZ;gUY-)4sZ%*-+NB=V?}DNwY_rH8Y{1NVLr? zvlUN7g6r~gZGVLucv1$Ei2iFDpO8<q>df{?_%wj(c%lVDF)U)zBGE|cnXKqFa$26$ z_l`xHOI;O0&^Htag{<ih^uDrg$b0&MTm`oMMdy}k8Tp-F9pIt7hGGUp&EOO8lV~mz z5kH8_Z{T|#uf4^P#B2v{8sp9^WpA^ny=ZsYy_2v>41-Xp3DME?Yy7QcD$l5TzjW5Q z?>M{;aCye44vhh>uiQ~00?DImGBB!VXc|wN6HEml_#qU}W7=^zKMK|l;1LvrLgf>q zI?zE&%kwHIk>U~;3qznV>H`f<q<yVVT=fyf27+GDnoyb8_xT*)`7sbRH4Wi~4CyZo z<}hy9UaG_>$354HSQBhQ0|8NqOl*uGwj}?|%pFc|vk%^rY%Cau<`aTXp*{6gMePKL zEAR*;o1)34d8)!e!;HD419WrgBPzc!M{DYP%8j#dGj(0<1NHa}Xc}s+Hm;-`(EB>9 z-;__ysq)OySbA%{$=?Kj{Fofc9$7#dBsrJ`UgUdSCK4T(;Pv?1xUQ$`$*}DS+Yj50 z5B<;!p{YW?$}v755Z0d0%FnXnvpW(}#4h422qT7r;u8RFk)$Ml%N`$Kj?!{Xg0lU3 z4``oa;aqimt57;nvKyvF`u!PvYFmtX2lhhMHlqMNF#+h|G}>7oYcrfp;~hoGD<U1( zR3n=FGPigF!~f3}k}uJ^PQZ4$sX#7pK6;Vuxi(vh9e+ul%3mZG<-`2G0nV4i5|I;m z?SR1?ayhawZDf7~HDoS7j<9^&2Lf!Nu<m>T#RU|X5Kyq~6w+qCZ`&_Kl5(bsxDp6# z7x6j>lgL@Ce4=P-rcO!Gq$F2>$Dky|)%GMg+rAw~F=yZoJ15EbVW;DDJNz|xYsuJ} zCS&po>%bt{)AM?D+v`S*!wj#-k>`uLh;Q|H*k-`nbbd{|3>2;Q&|?PukG%{4Y!E4b zlInId{BhKm(?1jW)XEOB;DKY25@X9}9#?P{@&bw?iXjk57OHy@uEIFS2ILJCm>eWT v2j(sq{^w_^Ra5K9AarA&okli_Js>QYVJ5X`i40o=za?Nu34hg`TDtKs2E*@W delta 1639 zcmZux&2QX96!(lj*50+Zn`A|ruQqK+A}38kND56_swzbZppqgXpo&BtcRlR7@~$^C z-ZVuHIlvX6XbzkZn<MlB2mS{R+>y)y2?<r)IiU)8&l{8`!qz-Lzj^cK_ddI0KMj}P zbDW|A&(q!S?zim2@+e6TXIE}Di(5sa1WKSsrKY`QH=QkqD2#T??A#IAs%$8M5fnaC zf&#NYRk!+>)9q({M+DB$cNNz>{Bz=ln%O}p+L8a*Yx_wfD<Sog*z52pGk7!MjJY%` zzt6Y`<JRrCmGC&q)ZLn>9rjh_kK_kZl%LRVi6vcilGyUDx_E14A!)W3+F^SxY>C8= zqPdqF%bmTY*hgW$ys(up-twabFtzZ&|Je8WeETs!2YwF9-_^J0&jaU@Oyz8sBi|!K zz-4`PmUs_*!93XXd|nq9<hFKIUMyH-O@6ISk3ZA{l9H6x)l}^oN6H}h9H^gD@LdDn zb@`j-O|OIbl4!(_Jdp%(C)soh8I47z<)JXxUMLd54S7$Wbg}{j1#faSJ|Mr)$7fDs z;-diUGAvOBqUbg;X_;uGLg?S}XWa!{#JD($DC!h2X^1JMDXG&zWnWK~t}d?`)5Q`T z{)^7-xP}ak@v#Z`<!IJ5_yBw|Enp(ylPI2&PmGb}(=amYBbL+}UW+|?33Nn15QUfk zgyygDOf$|C`OLWDyZ}3?@=$?5(Yk!KFn*o%ZUP5ki_aqIU4-1}d-wv#uEP=(h(hF- zh4BLoxZ5a0zyS$p?x}*F?rU%rNwt(5XF-81Xqyn~P89KJ(C3KPrToNW{eN-Hq3&rg znbBzneqytmuqO}&0NOA+B}@gkfMiv<XjSDeW_2m|Xc%QyM=%a$F9gR}oYWUzhTk<< z!UUqI^0M_>H36;{t~z*@`=QDmYtYqRS3X<=|J1IUYDa|6V0MuU^r7R-raH*C<@eUu z(9F(ofW8}>d<HD8e?$2geEFjM)mk3Hz-2|~$1sV)7898c$qw86s=QLX^o|a@PzSG| z{)?!oL6<_gqH0F=GL5r#d^R>^>=n+Mal){v--2_Z3Php(@~h&?0UFJdb^(~P4(`*G zcF7Sm%@BgtH!~eNt`)EIYoPtdKkz`x5H()~;;PSqGeI-Np>Y<G-9yydtlWch!Um#H zjc5v$+oi@T=J!8iScjR`@|*0eq5e>KwYb>~6E6%rw$t$=Pg461*^qbbO9wbgG8^Vk z64sh5X~Y2^0a4zmd>%P0V!niGrCJ1aaIA&t=a_%Kj^qtga6B(psj(>XyyuYQrGrx` zFEp$;F$KgVv)~TCx?P~8sG4Q7WU8h{Ng4kgSOz8eA$LFyJ0m(KAd{=k1nHCaooNb_ z=czLl6wo#nVrD_$?!@&v<NQq&x=8Z!hFI5OSi#0gXXIQyF3lUwIOs&|CV>N@0>q{! P%qN>xNre{G$_M`f3+HWi diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/git.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/git.cpython-38.pyc index a5c2a8509a744547187fa5139cfbc81d867b2d77..baa50fe03e8ce4fdc54e4c0a84f12b692b6a4342 100644 GIT binary patch delta 5263 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 JN9$<i{|Dit_RatR delta 4624 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 kG+(hB-^v z?PqcVPw?uz%yjU=)O3_WDdf`02DhfBO~UIiXiYuFHiJJ-P4aL!NKdCa(48TN+X+2L zGeOsMXRt6m&Z5EQ^uC6wBysGO2_kP2d5eyUqFQ`W^`P>5G^v~!q2utM9I}(9Qbbf3 z*wQHiOOQ`(7$?DwcSHMlr6$(P&NJ|EJJl1wbNund9^`id`A*+e36?S}X6Z5f*+y4G IYiOtb2Z~%a$N&HU diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-38.pyc index 1944fd83b8eeef5c06c1086402c0511bd507dc2a..bfae02d4220992034203441588c59b88f79638e4 100644 GIT binary patch literal 5026 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 HjX(YuUZfU< delta 1835 zcmb7E&5smC6tAlOoSqM6M_fJ}R#{}128KmG*2HX(brHV^2IR{PI5tzgGmSITV^z&A zkX||9QG%OFNVv^<a!>LX7%$#UJlS{S!M^}PHon(`3!)sHPQ7{cKI;AIy?XDv$v>;5 z^Tnb^;P=PkgU_7eN~ubdm3?Opc8c>wN<ua$g_~CCeEB`X9qxWjxEmI38}lP!aZm|I zRw*T%eM0=)%H#c43Otg%c5tKK3sfu3Bdx2r-WP43rp0q%r*|R}VME2@hR@Q{g;2;S z?#{(sCE|8!EH-2Vkv#h|U~?Rnysq<X$>v)i)>i#JtJ;=8*!ov?c~1ctf#lK5l<M@R zdQq<yb)^d0?b@N%k^c3=aezXd7>DS~`UhjSbR4V|;gqvG^zMGWZd9w>N{nla+jk5~ zE|R0<3^_|K!L1>ptB;t$_LFNY&C6E2RF{g!eU%!GC4SmBg{@c3H>N9aWa=uoWt~SN z!!sl$P>3>+ZLlQn2rJMsGpS9Owyp7!4I&5D94vWOPg}btIO7I46PD1Xm1WuDW|Jkx zz*;3+$g-7?Yi45UWot6XgV#;3R_n(79uHLbh}FJK?IFKL#VDwKJN2LvPwJD}?YP+t zMQTRfg;<ziAP`&XfK4Ep(znHS+?za<N>sFK@0d;9Mu%tG=dPCK7DCl%)w|)+I5^48 zKnQiINm=&Uk4<|sEmQruJw+erZ|$*LGl?~@6BF+RoP&2w*ec{*xrxcm+w5+6*#=E6 zvC-yfH7=6wv`Lhw%xn1t_Jt?Dp=8;i<Yq+`21TeKOB_50JveB-axRfiN%u9Vqs^Tx zf2CF8LIPb#;3oa1b9r<O;EEkcUIpTpQx;3HRj)Zm^zY8Z-kl&!ouxo@qi$2|LOaZr zpUYAtUPl3zUhLLyxqA<aN#r+Pq`-2gwp@xJMF)VF7>>{iB#2Rumh^phnwt6-cdW!s z&N7G;OROKeW9K$t33T&W7CHmrTmOm=7XKAJb3F!1iO-BsEpwBz7I4{XI|K}*B5Q>v z)`4>KjxhiT%Pb)S26drguY&sArXXRcfsU~BZ@H>>Qed&61Gee)+|GCLP~U*IXiM=5 z@WZ@3my1#}RCN({Vin?K$UtCo5bOuah`#C_-nRj-3W^uP!@*<eA3b$-2xRR^e%=Nr z-w?C#m*GgujlK|J7vnBQICGvaP+<sas5}LJ5>XRt2#KwGhF;10wf_O@W=sF%ZPpL- z=jojOxG;Kj2vMAXV_%4^-U?*vS#0`#VaLdY4LtUf6#ZOS97lkEAB2xEHM>D4{D<?E z;uad{esPa++OO#K@^1SBFceeTADOtd30X|M*n?yS2|ltk-)IL?c0$#Pxp)V~Cy~65 z<U=G+3z~7+c*}tTPm~A+dq4XaJaNO#xdpfETEM%oa<Du`Ck49rFQs0+zR*{F5!UO1 zfhcuwIAO2VU^lNvEBi+JDr(CEok%u@!^+b4D&y4F4=WQ3I5&lhjyWjescf)`k5Gu6 tn?*@o5jG>K!e^)Q2KLmQ>BPL>4v$fAkl4!w=2DjxSefFS_KfnSzW_bugv9^= diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-38.pyc index 43308a1be8191af2d16324bb6fb42a4b8048e6f4..67dd21227ccf99e513b38dff4c3a28befe497421 100644 GIT binary patch delta 3276 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 YsYx@?HszygGy`McsBtyZC0#Q2U&RjpkpKVy delta 3114 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 Qnoct`%EDT*Lpmh?KVj|6e*gdg diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-38.pyc index cb4eb56f676d141c0ba881a066c4f0d1880253b3..518ff68abf312803661e4fa620df920b610641cb 100644 GIT binary patch literal 21033 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 delta 5938 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 HlbZ6s0GwYd diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/bazaar.py b/venv/lib/python3.8/site-packages/pip/_internal/vcs/bazaar.py index 4f1e114..94408c5 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/vcs/bazaar.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/vcs/bazaar.py @@ -1,3 +1,6 @@ +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + from __future__ import absolute_import import logging @@ -5,9 +8,18 @@ import os from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._internal.utils.misc import display_path, path_to_url, rmtree +from pip._internal.utils.misc import display_path, rmtree +from pip._internal.utils.subprocess import make_command +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import path_to_url from pip._internal.vcs.versioncontrol import VersionControl, vcs +if MYPY_CHECK_RUNNING: + from typing import Optional, Tuple + from pip._internal.utils.misc import HiddenText + from pip._internal.vcs.versioncontrol import AuthInfo, RevOptions + + logger = logging.getLogger(__name__) @@ -32,6 +44,7 @@ class Bazaar(VersionControl): return ['-r', rev] def export(self, location, url): + # type: (str, HiddenText) -> None """ Export the Bazaar repository at the url to the destination location """ @@ -41,11 +54,11 @@ class Bazaar(VersionControl): url, rev_options = self.get_url_rev_options(url) self.run_command( - ['export', location, url] + rev_options.to_args(), - show_stdout=False, + make_command('export', location, url, rev_options.to_args()) ) def fetch_new(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None rev_display = rev_options.to_display() logger.info( 'Checking out %s%s to %s', @@ -53,18 +66,23 @@ class Bazaar(VersionControl): rev_display, display_path(dest), ) - cmd_args = ['branch', '-q'] + rev_options.to_args() + [url, dest] + cmd_args = ( + make_command('branch', '-q', rev_options.to_args(), url, dest) + ) self.run_command(cmd_args) def switch(self, dest, url, rev_options): - self.run_command(['switch', url], cwd=dest) + # type: (str, HiddenText, RevOptions) -> None + self.run_command(make_command('switch', url), cwd=dest) def update(self, dest, url, rev_options): - cmd_args = ['pull', '-q'] + rev_options.to_args() + # type: (str, HiddenText, RevOptions) -> None + cmd_args = make_command('pull', '-q', rev_options.to_args()) self.run_command(cmd_args, cwd=dest) @classmethod def get_url_rev_and_auth(cls, url): + # type: (str) -> Tuple[str, Optional[str], AuthInfo] # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it url, rev, user_pass = super(Bazaar, cls).get_url_rev_and_auth(url) if url.startswith('ssh://'): @@ -73,7 +91,7 @@ class Bazaar(VersionControl): @classmethod def get_remote_url(cls, location): - urls = cls.run_command(['info'], show_stdout=False, cwd=location) + urls = cls.run_command(['info'], cwd=location) for line in urls.splitlines(): line = line.strip() for x in ('checkout of branch: ', @@ -88,7 +106,7 @@ class Bazaar(VersionControl): @classmethod def get_revision(cls, location): revision = cls.run_command( - ['revno'], show_stdout=False, cwd=location, + ['revno'], cwd=location, ) return revision.splitlines()[-1] diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/git.py b/venv/lib/python3.8/site-packages/pip/_internal/vcs/git.py index 3445c1b..a9c7fb6 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/vcs/git.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/vcs/git.py @@ -1,3 +1,6 @@ +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + from __future__ import absolute_import import logging @@ -8,14 +11,24 @@ from pip._vendor.packaging.version import parse as parse_version from pip._vendor.six.moves.urllib import parse as urllib_parse from pip._vendor.six.moves.urllib import request as urllib_request -from pip._internal.exceptions import BadCommand -from pip._internal.utils.compat import samefile -from pip._internal.utils.misc import display_path, redact_password_from_url +from pip._internal.exceptions import BadCommand, SubProcessError +from pip._internal.utils.misc import display_path, hide_url +from pip._internal.utils.subprocess import make_command from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING from pip._internal.vcs.versioncontrol import ( - RemoteNotFoundError, VersionControl, vcs, + RemoteNotFoundError, + VersionControl, + find_path_to_setup_from_repo_root, + vcs, ) +if MYPY_CHECK_RUNNING: + from typing import Optional, Tuple + from pip._internal.utils.misc import HiddenText + from pip._internal.vcs.versioncontrol import AuthInfo, RevOptions + + urlsplit = urllib_parse.urlsplit urlunsplit = urllib_parse.urlunsplit @@ -46,9 +59,26 @@ class Git(VersionControl): def get_base_rev_args(rev): return [rev] + def is_immutable_rev_checkout(self, url, dest): + # type: (str, str) -> bool + _, rev_options = self.get_url_rev_options(hide_url(url)) + if not rev_options.rev: + return False + if not self.is_commit_id_equal(dest, rev_options.rev): + # the current commit is different from rev, + # which means rev was something else than a commit hash + return False + # return False in the rare case rev is both a commit hash + # and a tag or a branch; we don't want to cache in that case + # because that branch/tag could point to something else in the future + is_tag_or_branch = bool( + self.get_revision_sha(dest, rev_options.rev)[0] + ) + return not is_tag_or_branch + def get_git_version(self): VERSION_PFX = 'git version ' - version = self.run_command(['version'], show_stdout=False) + version = self.run_command(['version']) if version.startswith(VERSION_PFX): version = version[len(VERSION_PFX):].split()[0] else: @@ -71,7 +101,7 @@ class Git(VersionControl): # and to suppress the message to stderr. args = ['symbolic-ref', '-q', 'HEAD'] output = cls.run_command( - args, extra_ok_returncodes=(1, ), show_stdout=False, cwd=location, + args, extra_ok_returncodes=(1, ), cwd=location, ) ref = output.strip() @@ -81,6 +111,7 @@ class Git(VersionControl): return None def export(self, location, url): + # type: (str, HiddenText) -> None """Export the Git repository at the url to the destination location""" if not location.endswith('/'): location = location + '/' @@ -89,7 +120,7 @@ class Git(VersionControl): self.unpack(temp_dir.path, url=url) self.run_command( ['checkout-index', '-a', '-f', '--prefix', location], - show_stdout=False, cwd=temp_dir.path + cwd=temp_dir.path ) @classmethod @@ -103,8 +134,13 @@ class Git(VersionControl): rev: the revision name. """ # Pass rev to pre-filter the list. - output = cls.run_command(['show-ref', rev], cwd=dest, - show_stdout=False, on_returncode='ignore') + + output = '' + try: + output = cls.run_command(['show-ref', rev], cwd=dest) + except SubProcessError: + pass + refs = {} for line in output.strip().splitlines(): try: @@ -129,6 +165,7 @@ class Git(VersionControl): @classmethod def resolve_revision(cls, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> RevOptions """ Resolve a revision to a new RevOptions object with the SHA1 of the branch, tag, or ref if found. @@ -137,6 +174,10 @@ class Git(VersionControl): rev_options: a RevOptions object. """ rev = rev_options.arg_rev + # The arg_rev property's implementation for Git ensures that the + # rev return value is always non-None. + assert rev is not None + sha, is_branch = cls.get_revision_sha(dest, rev) if sha is not None: @@ -158,7 +199,7 @@ class Git(VersionControl): # If it looks like a ref, we have to fetch it explicitly. cls.run_command( - ['fetch', '-q', url] + rev_options.to_args(), + make_command('fetch', '-q', url, rev_options.to_args()), cwd=dest, ) # Change the revision to the SHA of the ref we fetched @@ -183,12 +224,10 @@ class Git(VersionControl): return cls.get_revision(dest) == name def fetch_new(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None rev_display = rev_options.to_display() - logger.info( - 'Cloning %s%s to %s', redact_password_from_url(url), - rev_display, display_path(dest), - ) - self.run_command(['clone', '-q', url, dest]) + logger.info('Cloning %s%s to %s', url, rev_display, display_path(dest)) + self.run_command(make_command('clone', '-q', url, dest)) if rev_options.rev: # Then a specific revision was requested. @@ -198,7 +237,9 @@ class Git(VersionControl): # Only do a checkout if the current commit id doesn't match # the requested revision. if not self.is_commit_id_equal(dest, rev_options.rev): - cmd_args = ['checkout', '-q'] + rev_options.to_args() + cmd_args = make_command( + 'checkout', '-q', rev_options.to_args(), + ) self.run_command(cmd_args, cwd=dest) elif self.get_current_branch(dest) != branch_name: # Then a specific branch was requested, and that branch @@ -213,13 +254,18 @@ class Git(VersionControl): self.update_submodules(dest) def switch(self, dest, url, rev_options): - self.run_command(['config', 'remote.origin.url', url], cwd=dest) - cmd_args = ['checkout', '-q'] + rev_options.to_args() + # type: (str, HiddenText, RevOptions) -> None + self.run_command( + make_command('config', 'remote.origin.url', url), + cwd=dest, + ) + cmd_args = make_command('checkout', '-q', rev_options.to_args()) self.run_command(cmd_args, cwd=dest) self.update_submodules(dest) def update(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None # First fetch changes from the default remote if self.get_git_version() >= parse_version('1.9.0'): # fetch tags in addition to everything else @@ -228,7 +274,7 @@ class Git(VersionControl): self.run_command(['fetch', '-q'], cwd=dest) # Then reset to wanted revision (maybe even origin/master) rev_options = self.resolve_revision(dest, url, rev_options) - cmd_args = ['reset', '--hard', '-q'] + rev_options.to_args() + cmd_args = make_command('reset', '--hard', '-q', rev_options.to_args()) self.run_command(cmd_args, cwd=dest) #: update submodules self.update_submodules(dest) @@ -245,7 +291,7 @@ class Git(VersionControl): # exits with return code 1 if there are no matching lines. stdout = cls.run_command( ['config', '--get-regexp', r'remote\..*\.url'], - extra_ok_returncodes=(1, ), show_stdout=False, cwd=location, + extra_ok_returncodes=(1, ), cwd=location, ) remotes = stdout.splitlines() try: @@ -265,39 +311,28 @@ class Git(VersionControl): if rev is None: rev = 'HEAD' current_rev = cls.run_command( - ['rev-parse', rev], show_stdout=False, cwd=location, + ['rev-parse', rev], cwd=location, ) return current_rev.strip() @classmethod def get_subdirectory(cls, location): + """ + Return the path to setup.py, relative to the repo root. + Return None if setup.py is in the repo root. + """ # find the repo root - git_dir = cls.run_command(['rev-parse', '--git-dir'], - show_stdout=False, cwd=location).strip() + git_dir = cls.run_command( + ['rev-parse', '--git-dir'], + cwd=location).strip() if not os.path.isabs(git_dir): git_dir = os.path.join(location, git_dir) - root_dir = os.path.join(git_dir, '..') - # find setup.py - orig_location = location - while not os.path.exists(os.path.join(location, 'setup.py')): - last_location = location - location = os.path.dirname(location) - if location == last_location: - # We've traversed up to the root of the filesystem without - # finding setup.py - logger.warning( - "Could not find setup.py for directory %s (tried all " - "parent directories)", - orig_location, - ) - return None - # relative path of setup.py to repo root - if samefile(root_dir, location): - return None - return os.path.relpath(location, root_dir) + repo_root = os.path.abspath(os.path.join(git_dir, '..')) + return find_path_to_setup_from_repo_root(location, repo_root) @classmethod def get_url_rev_and_auth(cls, url): + # type: (str) -> Tuple[str, Optional[str], AuthInfo] """ Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. That's required because although they use SSH they sometimes don't @@ -340,19 +375,23 @@ class Git(VersionControl): ) @classmethod - def controls_location(cls, location): - if super(Git, cls).controls_location(location): - return True + def get_repository_root(cls, location): + loc = super(Git, cls).get_repository_root(location) + if loc: + return loc try: - r = cls.run_command(['rev-parse'], - cwd=location, - show_stdout=False, - on_returncode='ignore') - return not r + r = cls.run_command( + ['rev-parse', '--show-toplevel'], + cwd=location, + log_failed_cmd=False, + ) except BadCommand: logger.debug("could not determine if %s is under git control " "because git is not available", location) - return False + return None + except SubProcessError: + return None + return os.path.normpath(r.rstrip('\r\n')) vcs.register(Git) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/mercurial.py b/venv/lib/python3.8/site-packages/pip/_internal/vcs/mercurial.py index db42783..69763fe 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/vcs/mercurial.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/vcs/mercurial.py @@ -1,3 +1,6 @@ +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + from __future__ import absolute_import import logging @@ -5,9 +8,22 @@ import os from pip._vendor.six.moves import configparser -from pip._internal.utils.misc import display_path, path_to_url +from pip._internal.exceptions import BadCommand, SubProcessError +from pip._internal.utils.misc import display_path +from pip._internal.utils.subprocess import make_command from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.vcs.versioncontrol import VersionControl, vcs +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import path_to_url +from pip._internal.vcs.versioncontrol import ( + VersionControl, + find_path_to_setup_from_repo_root, + vcs, +) + +if MYPY_CHECK_RUNNING: + from pip._internal.utils.misc import HiddenText + from pip._internal.vcs.versioncontrol import RevOptions + logger = logging.getLogger(__name__) @@ -16,22 +32,26 @@ class Mercurial(VersionControl): name = 'hg' dirname = '.hg' repo_name = 'clone' - schemes = ('hg', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http') + schemes = ( + 'hg', 'hg+file', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http', + ) @staticmethod def get_base_rev_args(rev): return [rev] def export(self, location, url): + # type: (str, HiddenText) -> None """Export the Hg repository at the url to the destination location""" with TempDirectory(kind="export") as temp_dir: self.unpack(temp_dir.path, url=url) self.run_command( - ['archive', location], show_stdout=False, cwd=temp_dir.path + ['archive', location], cwd=temp_dir.path ) def fetch_new(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None rev_display = rev_options.to_display() logger.info( 'Cloning hg %s%s to %s', @@ -39,16 +59,19 @@ class Mercurial(VersionControl): rev_display, display_path(dest), ) - self.run_command(['clone', '--noupdate', '-q', url, dest]) - cmd_args = ['update', '-q'] + rev_options.to_args() - self.run_command(cmd_args, cwd=dest) + self.run_command(make_command('clone', '--noupdate', '-q', url, dest)) + self.run_command( + make_command('update', '-q', rev_options.to_args()), + cwd=dest, + ) def switch(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None repo_config = os.path.join(dest, self.dirname, 'hgrc') config = configparser.RawConfigParser() try: config.read(repo_config) - config.set('paths', 'default', url) + config.set('paths', 'default', url.secret) with open(repo_config, 'w') as config_file: config.write(config_file) except (OSError, configparser.NoSectionError) as exc: @@ -56,19 +79,20 @@ class Mercurial(VersionControl): 'Could not switch Mercurial repository to %s: %s', url, exc, ) else: - cmd_args = ['update', '-q'] + rev_options.to_args() + cmd_args = make_command('update', '-q', rev_options.to_args()) self.run_command(cmd_args, cwd=dest) def update(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None self.run_command(['pull', '-q'], cwd=dest) - cmd_args = ['update', '-q'] + rev_options.to_args() + cmd_args = make_command('update', '-q', rev_options.to_args()) self.run_command(cmd_args, cwd=dest) @classmethod def get_remote_url(cls, location): url = cls.run_command( ['showconfig', 'paths.default'], - show_stdout=False, cwd=location).strip() + cwd=location).strip() if cls._is_local_repository(url): url = path_to_url(url) return url.strip() @@ -79,8 +103,7 @@ class Mercurial(VersionControl): Return the repository-local changeset revision number, as an integer. """ current_revision = cls.run_command( - ['parents', '--template={rev}'], - show_stdout=False, cwd=location).strip() + ['parents', '--template={rev}'], cwd=location).strip() return current_revision @classmethod @@ -91,7 +114,7 @@ class Mercurial(VersionControl): """ current_rev_hash = cls.run_command( ['parents', '--template={node}'], - show_stdout=False, cwd=location).strip() + cwd=location).strip() return current_rev_hash @classmethod @@ -99,5 +122,37 @@ class Mercurial(VersionControl): """Always assume the versions don't match""" return False + @classmethod + def get_subdirectory(cls, location): + """ + Return the path to setup.py, relative to the repo root. + Return None if setup.py is in the repo root. + """ + # find the repo root + repo_root = cls.run_command( + ['root'], cwd=location).strip() + if not os.path.isabs(repo_root): + repo_root = os.path.abspath(os.path.join(location, repo_root)) + return find_path_to_setup_from_repo_root(location, repo_root) + + @classmethod + def get_repository_root(cls, location): + loc = super(Mercurial, cls).get_repository_root(location) + if loc: + return loc + try: + r = cls.run_command( + ['root'], + cwd=location, + log_failed_cmd=False, + ) + except BadCommand: + logger.debug("could not determine if %s is under hg control " + "because hg is not available", location) + return None + except SubProcessError: + return None + return os.path.normpath(r.rstrip('\r\n')) + vcs.register(Mercurial) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/subversion.py b/venv/lib/python3.8/site-packages/pip/_internal/vcs/subversion.py index 6bb4c8c..ab13497 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/vcs/subversion.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/vcs/subversion.py @@ -1,14 +1,20 @@ +# The following comment should be removed at some point in the future. +# mypy: disallow-untyped-defs=False + from __future__ import absolute_import import logging import os import re -import sys from pip._internal.utils.logging import indent_log from pip._internal.utils.misc import ( - display_path, rmtree, split_auth_from_netloc, + display_path, + is_console_interactive, + rmtree, + split_auth_from_netloc, ) +from pip._internal.utils.subprocess import make_command from pip._internal.utils.typing import MYPY_CHECK_RUNNING from pip._internal.vcs.versioncontrol import VersionControl, vcs @@ -19,8 +25,11 @@ _svn_info_xml_url_re = re.compile(r'<url>(.*)</url>') if MYPY_CHECK_RUNNING: - from typing import List, Optional, Tuple - from pip._internal.vcs.versioncontrol import RevOptions + from typing import Optional, Tuple + from pip._internal.utils.subprocess import CommandArgs + from pip._internal.utils.misc import HiddenText + from pip._internal.vcs.versioncontrol import AuthInfo, RevOptions + logger = logging.getLogger(__name__) @@ -47,7 +56,7 @@ class Subversion(VersionControl): # Note: taken from setuptools.command.egg_info revision = 0 - for base, dirs, files in os.walk(location): + for base, dirs, _ in os.walk(location): if cls.dirname not in dirs: dirs[:] = [] continue # no sense walking uncontrolled subdirs @@ -82,6 +91,7 @@ class Subversion(VersionControl): @classmethod def get_url_rev_and_auth(cls, url): + # type: (str) -> Tuple[str, Optional[str], AuthInfo] # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it url, rev, user_pass = super(Subversion, cls).get_url_rev_and_auth(url) if url.startswith('ssh://'): @@ -90,7 +100,8 @@ class Subversion(VersionControl): @staticmethod def make_rev_args(username, password): - extra_args = [] + # type: (Optional[str], Optional[HiddenText]) -> CommandArgs + extra_args = [] # type: CommandArgs if username: extra_args += ['--username', username] if password: @@ -121,7 +132,7 @@ class Subversion(VersionControl): @classmethod def _get_svn_url_rev(cls, location): - from pip._internal.exceptions import InstallationError + from pip._internal.exceptions import SubProcessError entries_path = os.path.join(location, cls.dirname, 'entries') if os.path.exists(entries_path): @@ -140,7 +151,8 @@ class Subversion(VersionControl): elif data.startswith('<?xml'): match = _svn_xml_url_re.search(data) if not match: - raise ValueError('Badly formatted data: %r' % data) + raise ValueError( + 'Badly formatted data: {data!r}'.format(**locals())) url = match.group(1) # get repository URL revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)] + [0] else: @@ -153,13 +165,12 @@ class Subversion(VersionControl): # are only potentially needed for remote server requests. xml = cls.run_command( ['info', '--xml', location], - show_stdout=False, ) url = _svn_info_xml_url_re.search(xml).group(1) revs = [ int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml) ] - except InstallationError: + except SubProcessError: url, revs = None, [] if revs: @@ -177,7 +188,7 @@ class Subversion(VersionControl): def __init__(self, use_interactive=None): # type: (bool) -> None if use_interactive is None: - use_interactive = sys.stdin.isatty() + use_interactive = is_console_interactive() self.use_interactive = use_interactive # This member is used to cache the fetched version of the current @@ -202,13 +213,16 @@ class Subversion(VersionControl): # compiled Feb 25 2019, 14:20:39 on x86_64-apple-darwin17.0.0 # svn, version 1.7.14 (r1542130) # compiled Mar 28 2018, 08:49:13 on x86_64-pc-linux-gnu + # svn, version 1.12.0-SlikSvn (SlikSvn/1.12.0) + # compiled May 28 2019, 13:44:56 on x86_64-microsoft-windows6.2 version_prefix = 'svn, version ' - version = self.run_command(['--version'], show_stdout=False) + version = self.run_command(['--version']) + if not version.startswith(version_prefix): return () version = version[len(version_prefix):].split()[0] - version_list = version.split('.') + version_list = version.partition('-')[0].split('.') try: parsed_version = tuple(map(int, version_list)) except ValueError: @@ -238,7 +252,7 @@ class Subversion(VersionControl): return vcs_version def get_remote_call_options(self): - # type: () -> List[str] + # type: () -> CommandArgs """Return options to be used on calls to Subversion that contact the server. These options are applicable for the following ``svn`` subcommands used @@ -271,6 +285,7 @@ class Subversion(VersionControl): return [] def export(self, location, url): + # type: (str, HiddenText) -> None """Export the svn repository at the url to the destination location""" url, rev_options = self.get_url_rev_options(url) @@ -280,12 +295,14 @@ class Subversion(VersionControl): # Subversion doesn't like to check out over an existing # directory --force fixes this, but was only added in svn 1.5 rmtree(location) - cmd_args = (['export'] + self.get_remote_call_options() + - rev_options.to_args() + [url, location]) - self.run_command(cmd_args, show_stdout=False) + cmd_args = make_command( + 'export', self.get_remote_call_options(), + rev_options.to_args(), url, location, + ) + self.run_command(cmd_args) def fetch_new(self, dest, url, rev_options): - # type: (str, str, RevOptions) -> None + # type: (str, HiddenText, RevOptions) -> None rev_display = rev_options.to_display() logger.info( 'Checking out %s%s to %s', @@ -293,21 +310,26 @@ class Subversion(VersionControl): rev_display, display_path(dest), ) - cmd_args = (['checkout', '-q'] + - self.get_remote_call_options() + - rev_options.to_args() + [url, dest]) + cmd_args = make_command( + 'checkout', '-q', self.get_remote_call_options(), + rev_options.to_args(), url, dest, + ) self.run_command(cmd_args) def switch(self, dest, url, rev_options): - # type: (str, str, RevOptions) -> None - cmd_args = (['switch'] + self.get_remote_call_options() + - rev_options.to_args() + [url, dest]) + # type: (str, HiddenText, RevOptions) -> None + cmd_args = make_command( + 'switch', self.get_remote_call_options(), rev_options.to_args(), + url, dest, + ) self.run_command(cmd_args) def update(self, dest, url, rev_options): - # type: (str, str, RevOptions) -> None - cmd_args = (['update'] + self.get_remote_call_options() + - rev_options.to_args() + [dest]) + # type: (str, HiddenText, RevOptions) -> None + cmd_args = make_command( + 'update', self.get_remote_call_options(), rev_options.to_args(), + dest, + ) self.run_command(cmd_args) diff --git a/venv/lib/python3.8/site-packages/pip/_internal/vcs/versioncontrol.py b/venv/lib/python3.8/site-packages/pip/_internal/vcs/versioncontrol.py index 2d05fc1..96f830f 100644 --- a/venv/lib/python3.8/site-packages/pip/_internal/vcs/versioncontrol.py +++ b/venv/lib/python3.8/site-packages/pip/_internal/vcs/versioncontrol.py @@ -1,36 +1,71 @@ """Handles all VCS (version control) support""" + from __future__ import absolute_import import errno import logging import os import shutil +import subprocess import sys from pip._vendor import pkg_resources from pip._vendor.six.moves.urllib import parse as urllib_parse -from pip._internal.exceptions import BadCommand +from pip._internal.exceptions import ( + BadCommand, + InstallationError, + SubProcessError, +) +from pip._internal.utils.compat import console_to_str, samefile +from pip._internal.utils.logging import subprocess_logger from pip._internal.utils.misc import ( - ask_path_exists, backup_dir, call_subprocess, display_path, rmtree, + ask_path_exists, + backup_dir, + display_path, + hide_url, + hide_value, + rmtree, +) +from pip._internal.utils.subprocess import ( + format_command_args, + make_command, + make_subprocess_output_error, + reveal_command_args, ) from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.urls import get_url_scheme if MYPY_CHECK_RUNNING: from typing import ( - Any, Dict, Iterable, List, Mapping, Optional, Text, Tuple, Type + Dict, Iterable, Iterator, List, Optional, Text, Tuple, + Type, Union, Mapping, Any ) - from pip._internal.utils.ui import SpinnerInterface + from pip._internal.utils.misc import HiddenText + from pip._internal.utils.subprocess import CommandArgs AuthInfo = Tuple[Optional[str], Optional[str]] + __all__ = ['vcs'] logger = logging.getLogger(__name__) +def is_url(name): + # type: (Union[str, Text]) -> bool + """ + Return true if the name looks like a URL. + """ + scheme = get_url_scheme(name) + if scheme is None: + return False + return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes + + def make_vcs_requirement_url(repo_url, rev, project_name, subdir=None): + # type: (str, str, str, Optional[str]) -> str """ Return the URL for a VCS requirement. @@ -46,6 +81,120 @@ def make_vcs_requirement_url(repo_url, rev, project_name, subdir=None): return req +def call_subprocess( + cmd, # type: Union[List[str], CommandArgs] + cwd=None, # type: Optional[str] + extra_environ=None, # type: Optional[Mapping[str, Any]] + extra_ok_returncodes=None, # type: Optional[Iterable[int]] + log_failed_cmd=True # type: Optional[bool] +): + # type: (...) -> Text + """ + Args: + extra_ok_returncodes: an iterable of integer return codes that are + acceptable, in addition to 0. Defaults to None, which means []. + log_failed_cmd: if false, failed commands are not logged, + only raised. + """ + if extra_ok_returncodes is None: + extra_ok_returncodes = [] + + # log the subprocess output at DEBUG level. + log_subprocess = subprocess_logger.debug + + env = os.environ.copy() + if extra_environ: + env.update(extra_environ) + + # Whether the subprocess will be visible in the console. + showing_subprocess = True + + command_desc = format_command_args(cmd) + try: + proc = subprocess.Popen( + # Convert HiddenText objects to the underlying str. + reveal_command_args(cmd), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=cwd + ) + if proc.stdin: + proc.stdin.close() + except Exception as exc: + if log_failed_cmd: + subprocess_logger.critical( + "Error %s while executing command %s", exc, command_desc, + ) + raise + all_output = [] + while True: + # The "line" value is a unicode string in Python 2. + line = None + if proc.stdout: + line = console_to_str(proc.stdout.readline()) + if not line: + break + line = line.rstrip() + all_output.append(line + '\n') + + # Show the line immediately. + log_subprocess(line) + try: + proc.wait() + finally: + if proc.stdout: + proc.stdout.close() + + proc_had_error = ( + proc.returncode and proc.returncode not in extra_ok_returncodes + ) + if proc_had_error: + if not showing_subprocess and log_failed_cmd: + # Then the subprocess streams haven't been logged to the + # console yet. + msg = make_subprocess_output_error( + cmd_args=cmd, + cwd=cwd, + lines=all_output, + exit_status=proc.returncode, + ) + subprocess_logger.error(msg) + exc_msg = ( + 'Command errored out with exit status {}: {} ' + 'Check the logs for full command output.' + ).format(proc.returncode, command_desc) + raise SubProcessError(exc_msg) + return ''.join(all_output) + + +def find_path_to_setup_from_repo_root(location, repo_root): + # type: (str, str) -> Optional[str] + """ + Find the path to `setup.py` by searching up the filesystem from `location`. + Return the path to `setup.py` relative to `repo_root`. + Return None if `setup.py` is in `repo_root` or cannot be found. + """ + # find setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without + # finding setup.py + logger.warning( + "Could not find setup.py for directory %s (tried all " + "parent directories)", + orig_location, + ) + return None + + if samefile(repo_root, location): + return None + + return os.path.relpath(location, repo_root) + + class RemoteNotFoundError(Exception): pass @@ -63,7 +212,7 @@ class RevOptions(object): self, vc_class, # type: Type[VersionControl] rev=None, # type: Optional[str] - extra_args=None, # type: Optional[List[str]] + extra_args=None, # type: Optional[CommandArgs] ): # type: (...) -> None """ @@ -78,8 +227,10 @@ class RevOptions(object): self.extra_args = extra_args self.rev = rev self.vc_class = vc_class + self.branch_name = None # type: Optional[str] def __repr__(self): + # type: () -> str return '<RevOptions {}: rev={!r}>'.format(self.vc_class.name, self.rev) @property @@ -91,11 +242,11 @@ class RevOptions(object): return self.rev def to_args(self): - # type: () -> List[str] + # type: () -> CommandArgs """ Return the VCS-specific command arguments. """ - args = [] # type: List[str] + args = [] # type: CommandArgs rev = self.arg_rev if rev is not None: args += self.vc_class.get_base_rev_args(rev) @@ -136,6 +287,7 @@ class VcsSupport(object): super(VcsSupport, self).__init__() def __iter__(self): + # type: () -> Iterator[str] return self._registry.__iter__() @property @@ -176,10 +328,32 @@ class VcsSupport(object): Return a VersionControl object if a repository of that type is found at the given directory. """ + vcs_backends = {} for vcs_backend in self._registry.values(): - if vcs_backend.controls_location(location): - logger.debug('Determine that %s uses VCS: %s', - location, vcs_backend.name) + repo_path = vcs_backend.get_repository_root(location) + if not repo_path: + continue + logger.debug('Determine that %s uses VCS: %s', + location, vcs_backend.name) + vcs_backends[repo_path] = vcs_backend + + if not vcs_backends: + return None + + # Choose the VCS in the inner-most directory. Since all repository + # roots found here would be either `location` or one of its + # parents, the longest path should have the most path components, + # i.e. the backend representing the inner-most repository. + inner_most_repo_path = max(vcs_backends, key=len) + return vcs_backends[inner_most_repo_path] + + def get_backend_for_scheme(self, scheme): + # type: (str) -> Optional[VersionControl] + """ + Return a VersionControl object or None. + """ + for vcs_backend in self._registry.values(): + if scheme in vcs_backend.schemes: return vcs_backend return None @@ -207,6 +381,7 @@ class VersionControl(object): @classmethod def should_add_vcs_url_prefix(cls, remote_url): + # type: (str) -> bool """ Return whether the vcs prefix (e.g. "git+") should be added to a repository's remote url when used in a requirement. @@ -214,14 +389,17 @@ class VersionControl(object): return not remote_url.lower().startswith('{}:'.format(cls.name)) @classmethod - def get_subdirectory(cls, repo_dir): + def get_subdirectory(cls, location): + # type: (str) -> Optional[str] """ Return the path to setup.py, relative to the repo root. + Return None if setup.py is in the repo root. """ return None @classmethod def get_requirement_revision(cls, repo_dir): + # type: (str) -> str """ Return the revision string that should be used in a requirement. """ @@ -229,6 +407,7 @@ class VersionControl(object): @classmethod def get_src_requirement(cls, repo_dir, project_name): + # type: (str, str) -> Optional[str] """ Return the requirement string to use to redownload the files currently at the given repository directory. @@ -256,6 +435,7 @@ class VersionControl(object): @staticmethod def get_base_rev_args(rev): + # type: (str) -> List[str] """ Return the base revision arguments for a vcs command. @@ -264,9 +444,23 @@ class VersionControl(object): """ raise NotImplementedError + def is_immutable_rev_checkout(self, url, dest): + # type: (str, str) -> bool + """ + Return true if the commit hash checked out at dest matches + the revision in url. + + Always return False, if the VCS does not support immutable commit + hashes. + + This method does not check if there are local uncommitted changes + in dest after checkout, as pip currently has no use case for that. + """ + return False + @classmethod def make_rev_options(cls, rev=None, extra_args=None): - # type: (Optional[str], Optional[List[str]]) -> RevOptions + # type: (Optional[str], Optional[CommandArgs]) -> RevOptions """ Return a RevOptions object. @@ -287,6 +481,7 @@ class VersionControl(object): return repo.startswith(os.path.sep) or bool(drive) def export(self, location, url): + # type: (str, HiddenText) -> None """ Export the repository at the url to the destination location i.e. only download the files, without vcs informations @@ -297,6 +492,7 @@ class VersionControl(object): @classmethod def get_netloc_and_auth(cls, netloc, scheme): + # type: (str, str) -> Tuple[str, Tuple[Optional[str], Optional[str]]] """ Parse the repository URL's netloc, and return the new netloc to use along with auth information. @@ -336,28 +532,38 @@ class VersionControl(object): rev = None if '@' in path: path, rev = path.rsplit('@', 1) + if not rev: + raise InstallationError( + "The URL {!r} has an empty revision (after @) " + "which is not supported. Include a revision after @ " + "or remove @ from the URL.".format(url) + ) url = urllib_parse.urlunsplit((scheme, netloc, path, query, '')) return url, rev, user_pass @staticmethod def make_rev_args(username, password): + # type: (Optional[str], Optional[HiddenText]) -> CommandArgs """ Return the RevOptions "extra arguments" to use in obtain(). """ return [] def get_url_rev_options(self, url): - # type: (str) -> Tuple[str, RevOptions] + # type: (HiddenText) -> Tuple[HiddenText, RevOptions] """ Return the URL and RevOptions object to use in obtain() and in some cases export(), as a tuple (url, rev_options). """ - url, rev, user_pass = self.get_url_rev_and_auth(url) - username, password = user_pass + secret_url, rev, user_pass = self.get_url_rev_and_auth(url.secret) + username, secret_password = user_pass + password = None # type: Optional[HiddenText] + if secret_password is not None: + password = hide_value(secret_password) extra_args = self.make_rev_args(username, password) rev_options = self.make_rev_options(rev, extra_args=extra_args) - return url, rev_options + return hide_url(secret_url), rev_options @staticmethod def normalize_url(url): @@ -377,6 +583,7 @@ class VersionControl(object): return (cls.normalize_url(url1) == cls.normalize_url(url2)) def fetch_new(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None """ Fetch a revision from a repository, in the case that this is the first fetch from the repository. @@ -388,6 +595,7 @@ class VersionControl(object): raise NotImplementedError def switch(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None """ Switch the repo at ``dest`` to point to ``URL``. @@ -397,6 +605,7 @@ class VersionControl(object): raise NotImplementedError def update(self, dest, url, rev_options): + # type: (str, HiddenText, RevOptions) -> None """ Update an already-existing repo to the given ``rev_options``. @@ -407,6 +616,7 @@ class VersionControl(object): @classmethod def is_commit_id_equal(cls, dest, name): + # type: (str, Optional[str]) -> bool """ Return whether the id of the current commit equals the given name. @@ -417,7 +627,7 @@ class VersionControl(object): raise NotImplementedError def obtain(self, dest, url): - # type: (str, str) -> None + # type: (str, HiddenText) -> None """ Install or update in editable mode the package represented by this VersionControl object. @@ -434,7 +644,7 @@ class VersionControl(object): rev_display = rev_options.to_display() if self.is_repository_directory(dest): existing_url = self.get_remote_url(dest) - if self.compare_urls(existing_url, url): + if self.compare_urls(existing_url, url.secret): logger.debug( '%s in %s exists, and has correct URL (%s)', self.repo_name.title(), @@ -478,7 +688,8 @@ class VersionControl(object): self.name, url, ) - response = ask_path_exists('What to do? %s' % prompt[0], prompt[1]) + response = ask_path_exists('What to do? {}'.format( + prompt[0]), prompt[1]) if response == 'a': sys.exit(-1) @@ -510,7 +721,7 @@ class VersionControl(object): self.switch(dest, url, rev_options) def unpack(self, location, url): - # type: (str, str) -> None + # type: (str, HiddenText) -> None """ Clean up current location and download the url repository (and vcs infos) into location @@ -523,6 +734,7 @@ class VersionControl(object): @classmethod def get_remote_url(cls, location): + # type: (str) -> str """ Return the url used at location @@ -533,6 +745,7 @@ class VersionControl(object): @classmethod def get_revision(cls, location): + # type: (str) -> str """ Return the current commit id of the files at the given location. """ @@ -541,14 +754,11 @@ class VersionControl(object): @classmethod def run_command( cls, - cmd, # type: List[str] - show_stdout=True, # type: bool + cmd, # type: Union[List[str], CommandArgs] cwd=None, # type: Optional[str] - on_returncode='raise', # type: str - extra_ok_returncodes=None, # type: Optional[Iterable[int]] - command_desc=None, # type: Optional[str] extra_environ=None, # type: Optional[Mapping[str, Any]] - spinner=None # type: Optional[SpinnerInterface] + extra_ok_returncodes=None, # type: Optional[Iterable[int]] + log_failed_cmd=True # type: bool ): # type: (...) -> Text """ @@ -556,23 +766,20 @@ class VersionControl(object): This is simply a wrapper around call_subprocess that adds the VCS command name, and checks that the VCS is available """ - cmd = [cls.name] + cmd + cmd = make_command(cls.name, *cmd) try: - return call_subprocess(cmd, show_stdout, cwd, - on_returncode=on_returncode, - extra_ok_returncodes=extra_ok_returncodes, - command_desc=command_desc, + return call_subprocess(cmd, cwd, extra_environ=extra_environ, - unset_environ=cls.unset_environ, - spinner=spinner) + extra_ok_returncodes=extra_ok_returncodes, + log_failed_cmd=log_failed_cmd) except OSError as e: # errno.ENOENT = no such file or directory # In other words, the VCS executable isn't available if e.errno == errno.ENOENT: raise BadCommand( - 'Cannot find command %r - do you have ' - '%r installed and in your ' - 'PATH?' % (cls.name, cls.name)) + 'Cannot find command {cls.name!r} - do you have ' + '{cls.name!r} installed and in your ' + 'PATH?'.format(**locals())) else: raise # re-raise exception if a different error occurred @@ -587,14 +794,18 @@ class VersionControl(object): return os.path.exists(os.path.join(path, cls.dirname)) @classmethod - def controls_location(cls, location): - # type: (str) -> bool + def get_repository_root(cls, location): + # type: (str) -> Optional[str] """ - Check if a location is controlled by the vcs. + Return the "root" (top-level) directory controlled by the vcs, + or `None` if the directory is not in any. + It is meant to be overridden to implement smarter detection mechanisms for specific vcs. - This can do more than is_repository_directory() alone. For example, - the Git override checks that Git is actually available. + This can do more than is_repository_directory() alone. For + example, the Git override checks that Git is actually available. """ - return cls.is_repository_directory(location) + if cls.is_repository_directory(location): + return location + return None diff --git a/venv/lib/python3.8/site-packages/pip/_internal/wheel.py b/venv/lib/python3.8/site-packages/pip/_internal/wheel.py deleted file mode 100644 index 6f034cd..0000000 --- a/venv/lib/python3.8/site-packages/pip/_internal/wheel.py +++ /dev/null @@ -1,1125 +0,0 @@ -""" -Support for installing and building the "wheel" binary package format. -""" -from __future__ import absolute_import - -import collections -import compileall -import csv -import hashlib -import logging -import os.path -import re -import shutil -import stat -import sys -import warnings -from base64 import urlsafe_b64encode -from email.parser import Parser - -from pip._vendor import pkg_resources -from pip._vendor.distlib.scripts import ScriptMaker -from pip._vendor.packaging.utils import canonicalize_name -from pip._vendor.six import StringIO - -from pip._internal import pep425tags -from pip._internal.download import unpack_url -from pip._internal.exceptions import ( - InstallationError, InvalidWheelFilename, UnsupportedWheel, -) -from pip._internal.locations import distutils_scheme -from pip._internal.models.link import Link -from pip._internal.utils.logging import indent_log -from pip._internal.utils.marker_files import PIP_DELETE_MARKER_FILENAME -from pip._internal.utils.misc import ( - LOG_DIVIDER, call_subprocess, captured_stdout, ensure_dir, - format_command_args, path_to_url, read_chunks, -) -from pip._internal.utils.setuptools_build import make_setuptools_shim_args -from pip._internal.utils.temp_dir import TempDirectory -from pip._internal.utils.typing import MYPY_CHECK_RUNNING -from pip._internal.utils.ui import open_spinner - -if MYPY_CHECK_RUNNING: - from typing import ( - Dict, List, Optional, Sequence, Mapping, Tuple, IO, Text, Any, Iterable - ) - from pip._vendor.packaging.requirements import Requirement - from pip._internal.req.req_install import InstallRequirement - from pip._internal.download import PipSession - from pip._internal.index import FormatControl, PackageFinder - from pip._internal.operations.prepare import ( - RequirementPreparer - ) - from pip._internal.cache import WheelCache - from pip._internal.pep425tags import Pep425Tag - - InstalledCSVRow = Tuple[str, ...] - - -VERSION_COMPATIBLE = (1, 0) - - -logger = logging.getLogger(__name__) - - -def normpath(src, p): - return os.path.relpath(src, p).replace(os.path.sep, '/') - - -def hash_file(path, blocksize=1 << 20): - # type: (str, int) -> Tuple[Any, int] - """Return (hash, length) for path using hashlib.sha256()""" - h = hashlib.sha256() - length = 0 - with open(path, 'rb') as f: - for block in read_chunks(f, size=blocksize): - length += len(block) - h.update(block) - return (h, length) # type: ignore - - -def rehash(path, blocksize=1 << 20): - # type: (str, int) -> Tuple[str, str] - """Return (encoded_digest, length) for path using hashlib.sha256()""" - h, length = hash_file(path, blocksize) - digest = 'sha256=' + urlsafe_b64encode( - h.digest() - ).decode('latin1').rstrip('=') - # unicode/str python2 issues - return (digest, str(length)) # type: ignore - - -def open_for_csv(name, mode): - # type: (str, Text) -> IO - if sys.version_info[0] < 3: - nl = {} # type: Dict[str, Any] - bin = 'b' - else: - nl = {'newline': ''} # type: Dict[str, Any] - bin = '' - return open(name, mode + bin, **nl) - - -def replace_python_tag(wheelname, new_tag): - # type: (str, str) -> str - """Replace the Python tag in a wheel file name with a new value. - """ - parts = wheelname.split('-') - parts[-3] = new_tag - return '-'.join(parts) - - -def fix_script(path): - # type: (str) -> Optional[bool] - """Replace #!python with #!/path/to/python - Return True if file was changed.""" - # XXX RECORD hashes will need to be updated - if os.path.isfile(path): - with open(path, 'rb') as script: - firstline = script.readline() - if not firstline.startswith(b'#!python'): - return False - exename = sys.executable.encode(sys.getfilesystemencoding()) - firstline = b'#!' + exename + os.linesep.encode("ascii") - rest = script.read() - with open(path, 'wb') as script: - script.write(firstline) - script.write(rest) - return True - return None - - -dist_info_re = re.compile(r"""^(?P<namever>(?P<name>.+?)(-(?P<ver>.+?))?) - \.dist-info$""", re.VERBOSE) - - -def root_is_purelib(name, wheeldir): - # type: (str, str) -> bool - """ - Return True if the extracted wheel in wheeldir should go into purelib. - """ - name_folded = name.replace("-", "_") - for item in os.listdir(wheeldir): - match = dist_info_re.match(item) - if match and match.group('name') == name_folded: - with open(os.path.join(wheeldir, item, 'WHEEL')) as wheel: - for line in wheel: - line = line.lower().rstrip() - if line == "root-is-purelib: true": - return True - return False - - -def get_entrypoints(filename): - # type: (str) -> Tuple[Dict[str, str], Dict[str, str]] - if not os.path.exists(filename): - return {}, {} - - # This is done because you can pass a string to entry_points wrappers which - # means that they may or may not be valid INI files. The attempt here is to - # strip leading and trailing whitespace in order to make them valid INI - # files. - with open(filename) as fp: - data = StringIO() - for line in fp: - data.write(line.strip()) - data.write("\n") - data.seek(0) - - # get the entry points and then the script names - entry_points = pkg_resources.EntryPoint.parse_map(data) - console = entry_points.get('console_scripts', {}) - gui = entry_points.get('gui_scripts', {}) - - def _split_ep(s): - """get the string representation of EntryPoint, remove space and split - on '='""" - return str(s).replace(" ", "").split("=") - - # convert the EntryPoint objects into strings with module:function - console = dict(_split_ep(v) for v in console.values()) - gui = dict(_split_ep(v) for v in gui.values()) - return console, gui - - -def message_about_scripts_not_on_PATH(scripts): - # type: (Sequence[str]) -> Optional[str] - """Determine if any scripts are not on PATH and format a warning. - - Returns a warning message if one or more scripts are not on PATH, - otherwise None. - """ - if not scripts: - return None - - # Group scripts by the path they were installed in - grouped_by_dir = collections.defaultdict(set) # type: Dict[str, set] - for destfile in scripts: - parent_dir = os.path.dirname(destfile) - script_name = os.path.basename(destfile) - grouped_by_dir[parent_dir].add(script_name) - - # We don't want to warn for directories that are on PATH. - not_warn_dirs = [ - os.path.normcase(i).rstrip(os.sep) for i in - os.environ.get("PATH", "").split(os.pathsep) - ] - # If an executable sits with sys.executable, we don't warn for it. - # This covers the case of venv invocations without activating the venv. - not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable))) - warn_for = { - parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items() - if os.path.normcase(parent_dir) not in not_warn_dirs - } - if not warn_for: - return None - - # Format a message - msg_lines = [] - for parent_dir, scripts in warn_for.items(): - sorted_scripts = sorted(scripts) # type: List[str] - if len(sorted_scripts) == 1: - start_text = "script {} is".format(sorted_scripts[0]) - else: - start_text = "scripts {} are".format( - ", ".join(sorted_scripts[:-1]) + " and " + sorted_scripts[-1] - ) - - msg_lines.append( - "The {} installed in '{}' which is not on PATH." - .format(start_text, parent_dir) - ) - - last_line_fmt = ( - "Consider adding {} to PATH or, if you prefer " - "to suppress this warning, use --no-warn-script-location." - ) - if len(msg_lines) == 1: - msg_lines.append(last_line_fmt.format("this directory")) - else: - msg_lines.append(last_line_fmt.format("these directories")) - - # Returns the formatted multiline message - return "\n".join(msg_lines) - - -def sorted_outrows(outrows): - # type: (Iterable[InstalledCSVRow]) -> List[InstalledCSVRow] - """ - Return the given rows of a RECORD file in sorted order. - - Each row is a 3-tuple (path, hash, size) and corresponds to a record of - a RECORD file (see PEP 376 and PEP 427 for details). For the rows - passed to this function, the size can be an integer as an int or string, - or the empty string. - """ - # Normally, there should only be one row per path, in which case the - # second and third elements don't come into play when sorting. - # However, in cases in the wild where a path might happen to occur twice, - # we don't want the sort operation to trigger an error (but still want - # determinism). Since the third element can be an int or string, we - # coerce each element to a string to avoid a TypeError in this case. - # For additional background, see-- - # https://github.com/pypa/pip/issues/5868 - return sorted(outrows, key=lambda row: tuple(str(x) for x in row)) - - -def get_csv_rows_for_installed( - old_csv_rows, # type: Iterable[List[str]] - installed, # type: Dict[str, str] - changed, # type: set - generated, # type: List[str] - lib_dir, # type: str -): - # type: (...) -> List[InstalledCSVRow] - """ - :param installed: A map from archive RECORD path to installation RECORD - path. - """ - installed_rows = [] # type: List[InstalledCSVRow] - for row in old_csv_rows: - if len(row) > 3: - logger.warning( - 'RECORD line has more than three elements: {}'.format(row) - ) - # Make a copy because we are mutating the row. - row = list(row) - old_path = row[0] - new_path = installed.pop(old_path, old_path) - row[0] = new_path - if new_path in changed: - digest, length = rehash(new_path) - row[1] = digest - row[2] = length - installed_rows.append(tuple(row)) - for f in generated: - digest, length = rehash(f) - installed_rows.append((normpath(f, lib_dir), digest, str(length))) - for f in installed: - installed_rows.append((installed[f], '', '')) - return installed_rows - - -def move_wheel_files( - name, # type: str - req, # type: Requirement - wheeldir, # type: str - user=False, # type: bool - home=None, # type: Optional[str] - root=None, # type: Optional[str] - pycompile=True, # type: bool - scheme=None, # type: Optional[Mapping[str, str]] - isolated=False, # type: bool - prefix=None, # type: Optional[str] - warn_script_location=True # type: bool -): - # type: (...) -> None - """Install a wheel""" - # TODO: Investigate and break this up. - # TODO: Look into moving this into a dedicated class for representing an - # installation. - - if not scheme: - scheme = distutils_scheme( - name, user=user, home=home, root=root, isolated=isolated, - prefix=prefix, - ) - - if root_is_purelib(name, wheeldir): - lib_dir = scheme['purelib'] - else: - lib_dir = scheme['platlib'] - - info_dir = [] # type: List[str] - data_dirs = [] - source = wheeldir.rstrip(os.path.sep) + os.path.sep - - # Record details of the files moved - # installed = files copied from the wheel to the destination - # changed = files changed while installing (scripts #! line typically) - # generated = files newly generated during the install (script wrappers) - installed = {} # type: Dict[str, str] - changed = set() - generated = [] # type: List[str] - - # Compile all of the pyc files that we're going to be installing - if pycompile: - with captured_stdout() as stdout: - with warnings.catch_warnings(): - warnings.filterwarnings('ignore') - compileall.compile_dir(source, force=True, quiet=True) - logger.debug(stdout.getvalue()) - - def record_installed(srcfile, destfile, modified=False): - """Map archive RECORD paths to installation RECORD paths.""" - oldpath = normpath(srcfile, wheeldir) - newpath = normpath(destfile, lib_dir) - installed[oldpath] = newpath - if modified: - changed.add(destfile) - - def clobber(source, dest, is_base, fixer=None, filter=None): - ensure_dir(dest) # common for the 'include' path - - for dir, subdirs, files in os.walk(source): - basedir = dir[len(source):].lstrip(os.path.sep) - destdir = os.path.join(dest, basedir) - if is_base and basedir.split(os.path.sep, 1)[0].endswith('.data'): - continue - for s in subdirs: - destsubdir = os.path.join(dest, basedir, s) - if is_base and basedir == '' and destsubdir.endswith('.data'): - data_dirs.append(s) - continue - elif (is_base and - s.endswith('.dist-info') and - canonicalize_name(s).startswith( - canonicalize_name(req.name))): - assert not info_dir, ('Multiple .dist-info directories: ' + - destsubdir + ', ' + - ', '.join(info_dir)) - info_dir.append(destsubdir) - for f in files: - # Skip unwanted files - if filter and filter(f): - continue - srcfile = os.path.join(dir, f) - destfile = os.path.join(dest, basedir, f) - # directory creation is lazy and after the file filtering above - # to ensure we don't install empty dirs; empty dirs can't be - # uninstalled. - ensure_dir(destdir) - - # copyfile (called below) truncates the destination if it - # exists and then writes the new contents. This is fine in most - # cases, but can cause a segfault if pip has loaded a shared - # object (e.g. from pyopenssl through its vendored urllib3) - # Since the shared object is mmap'd an attempt to call a - # symbol in it will then cause a segfault. Unlinking the file - # allows writing of new contents while allowing the process to - # continue to use the old copy. - if os.path.exists(destfile): - os.unlink(destfile) - - # We use copyfile (not move, copy, or copy2) to be extra sure - # that we are not moving directories over (copyfile fails for - # directories) as well as to ensure that we are not copying - # over any metadata because we want more control over what - # metadata we actually copy over. - shutil.copyfile(srcfile, destfile) - - # Copy over the metadata for the file, currently this only - # includes the atime and mtime. - st = os.stat(srcfile) - if hasattr(os, "utime"): - os.utime(destfile, (st.st_atime, st.st_mtime)) - - # If our file is executable, then make our destination file - # executable. - if os.access(srcfile, os.X_OK): - st = os.stat(srcfile) - permissions = ( - st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH - ) - os.chmod(destfile, permissions) - - changed = False - if fixer: - changed = fixer(destfile) - record_installed(srcfile, destfile, changed) - - clobber(source, lib_dir, True) - - assert info_dir, "%s .dist-info directory not found" % req - - # Get the defined entry points - ep_file = os.path.join(info_dir[0], 'entry_points.txt') - console, gui = get_entrypoints(ep_file) - - def is_entrypoint_wrapper(name): - # EP, EP.exe and EP-script.py are scripts generated for - # entry point EP by setuptools - if name.lower().endswith('.exe'): - matchname = name[:-4] - elif name.lower().endswith('-script.py'): - matchname = name[:-10] - elif name.lower().endswith(".pya"): - matchname = name[:-4] - else: - matchname = name - # Ignore setuptools-generated scripts - return (matchname in console or matchname in gui) - - for datadir in data_dirs: - fixer = None - filter = None - for subdir in os.listdir(os.path.join(wheeldir, datadir)): - fixer = None - if subdir == 'scripts': - fixer = fix_script - filter = is_entrypoint_wrapper - source = os.path.join(wheeldir, datadir, subdir) - dest = scheme[subdir] - clobber(source, dest, False, fixer=fixer, filter=filter) - - maker = ScriptMaker(None, scheme['scripts']) - - # Ensure old scripts are overwritten. - # See https://github.com/pypa/pip/issues/1800 - maker.clobber = True - - # Ensure we don't generate any variants for scripts because this is almost - # never what somebody wants. - # See https://bitbucket.org/pypa/distlib/issue/35/ - maker.variants = {''} - - # This is required because otherwise distlib creates scripts that are not - # executable. - # See https://bitbucket.org/pypa/distlib/issue/32/ - maker.set_mode = True - - # Simplify the script and fix the fact that the default script swallows - # every single stack trace. - # See https://bitbucket.org/pypa/distlib/issue/34/ - # See https://bitbucket.org/pypa/distlib/issue/33/ - def _get_script_text(entry): - if entry.suffix is None: - raise InstallationError( - "Invalid script entry point: %s for req: %s - A callable " - "suffix is required. Cf https://packaging.python.org/en/" - "latest/distributing.html#console-scripts for more " - "information." % (entry, req) - ) - return maker.script_template % { - "module": entry.prefix, - "import_name": entry.suffix.split(".")[0], - "func": entry.suffix, - } - # ignore type, because mypy disallows assigning to a method, - # see https://github.com/python/mypy/issues/2427 - maker._get_script_text = _get_script_text # type: ignore - maker.script_template = r"""# -*- coding: utf-8 -*- -import re -import sys - -from %(module)s import %(import_name)s - -if __name__ == '__main__': - sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit(%(func)s()) -""" - - # Special case pip and setuptools to generate versioned wrappers - # - # The issue is that some projects (specifically, pip and setuptools) use - # code in setup.py to create "versioned" entry points - pip2.7 on Python - # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into - # the wheel metadata at build time, and so if the wheel is installed with - # a *different* version of Python the entry points will be wrong. The - # correct fix for this is to enhance the metadata to be able to describe - # such versioned entry points, but that won't happen till Metadata 2.0 is - # available. - # In the meantime, projects using versioned entry points will either have - # incorrect versioned entry points, or they will not be able to distribute - # "universal" wheels (i.e., they will need a wheel per Python version). - # - # Because setuptools and pip are bundled with _ensurepip and virtualenv, - # we need to use universal wheels. So, as a stopgap until Metadata 2.0, we - # override the versioned entry points in the wheel and generate the - # correct ones. This code is purely a short-term measure until Metadata 2.0 - # is available. - # - # To add the level of hack in this section of code, in order to support - # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment - # variable which will control which version scripts get installed. - # - # ENSUREPIP_OPTIONS=altinstall - # - Only pipX.Y and easy_install-X.Y will be generated and installed - # ENSUREPIP_OPTIONS=install - # - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note - # that this option is technically if ENSUREPIP_OPTIONS is set and is - # not altinstall - # DEFAULT - # - The default behavior is to install pip, pipX, pipX.Y, easy_install - # and easy_install-X.Y. - pip_script = console.pop('pip', None) - if pip_script: - if "ENSUREPIP_OPTIONS" not in os.environ: - spec = 'pip = ' + pip_script - generated.extend(maker.make(spec)) - - if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall": - spec = 'pip%s = %s' % (sys.version[:1], pip_script) - generated.extend(maker.make(spec)) - - spec = 'pip%s = %s' % (sys.version[:3], pip_script) - generated.extend(maker.make(spec)) - # Delete any other versioned pip entry points - pip_ep = [k for k in console if re.match(r'pip(\d(\.\d)?)?$', k)] - for k in pip_ep: - del console[k] - easy_install_script = console.pop('easy_install', None) - if easy_install_script: - if "ENSUREPIP_OPTIONS" not in os.environ: - spec = 'easy_install = ' + easy_install_script - generated.extend(maker.make(spec)) - - spec = 'easy_install-%s = %s' % (sys.version[:3], easy_install_script) - generated.extend(maker.make(spec)) - # Delete any other versioned easy_install entry points - easy_install_ep = [ - k for k in console if re.match(r'easy_install(-\d\.\d)?$', k) - ] - for k in easy_install_ep: - del console[k] - - # Generate the console and GUI entry points specified in the wheel - if len(console) > 0: - generated_console_scripts = maker.make_multiple( - ['%s = %s' % kv for kv in console.items()] - ) - generated.extend(generated_console_scripts) - - if warn_script_location: - msg = message_about_scripts_not_on_PATH(generated_console_scripts) - if msg is not None: - logger.warning(msg) - - if len(gui) > 0: - generated.extend( - maker.make_multiple( - ['%s = %s' % kv for kv in gui.items()], - {'gui': True} - ) - ) - - # Record pip as the installer - installer = os.path.join(info_dir[0], 'INSTALLER') - temp_installer = os.path.join(info_dir[0], 'INSTALLER.pip') - with open(temp_installer, 'wb') as installer_file: - installer_file.write(b'pip\n') - shutil.move(temp_installer, installer) - generated.append(installer) - - # Record details of all files installed - record = os.path.join(info_dir[0], 'RECORD') - temp_record = os.path.join(info_dir[0], 'RECORD.pip') - with open_for_csv(record, 'r') as record_in: - with open_for_csv(temp_record, 'w+') as record_out: - reader = csv.reader(record_in) - outrows = get_csv_rows_for_installed( - reader, installed=installed, changed=changed, - generated=generated, lib_dir=lib_dir, - ) - writer = csv.writer(record_out) - # Sort to simplify testing. - for row in sorted_outrows(outrows): - writer.writerow(row) - shutil.move(temp_record, record) - - -def wheel_version(source_dir): - # type: (Optional[str]) -> Optional[Tuple[int, ...]] - """ - Return the Wheel-Version of an extracted wheel, if possible. - - Otherwise, return None if we couldn't parse / extract it. - """ - try: - dist = [d for d in pkg_resources.find_on_path(None, source_dir)][0] - - wheel_data = dist.get_metadata('WHEEL') - wheel_data = Parser().parsestr(wheel_data) - - version = wheel_data['Wheel-Version'].strip() - version = tuple(map(int, version.split('.'))) - return version - except Exception: - return None - - -def check_compatibility(version, name): - # type: (Optional[Tuple[int, ...]], str) -> None - """ - Raises errors or warns if called with an incompatible Wheel-Version. - - Pip should refuse to install a Wheel-Version that's a major series - ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when - installing a version only minor version ahead (e.g 1.2 > 1.1). - - version: a 2-tuple representing a Wheel-Version (Major, Minor) - name: name of wheel or package to raise exception about - - :raises UnsupportedWheel: when an incompatible Wheel-Version is given - """ - if not version: - raise UnsupportedWheel( - "%s is in an unsupported or invalid wheel" % name - ) - if version[0] > VERSION_COMPATIBLE[0]: - raise UnsupportedWheel( - "%s's Wheel-Version (%s) is not compatible with this version " - "of pip" % (name, '.'.join(map(str, version))) - ) - elif version > VERSION_COMPATIBLE: - logger.warning( - 'Installing from a newer Wheel-Version (%s)', - '.'.join(map(str, version)), - ) - - -def format_tag(file_tag): - # type: (Tuple[str, ...]) -> str - """ - Format three tags in the form "<python_tag>-<abi_tag>-<platform_tag>". - - :param file_tag: A 3-tuple of tags (python_tag, abi_tag, platform_tag). - """ - return '-'.join(file_tag) - - -class Wheel(object): - """A wheel file""" - - # TODO: Maybe move the class into the models sub-package - # TODO: Maybe move the install code into this class - - wheel_file_re = re.compile( - r"""^(?P<namever>(?P<name>.+?)-(?P<ver>.*?)) - ((-(?P<build>\d[^-]*?))?-(?P<pyver>.+?)-(?P<abi>.+?)-(?P<plat>.+?) - \.whl|\.dist-info)$""", - re.VERBOSE - ) - - def __init__(self, filename): - # type: (str) -> None - """ - :raises InvalidWheelFilename: when the filename is invalid for a wheel - """ - wheel_info = self.wheel_file_re.match(filename) - if not wheel_info: - raise InvalidWheelFilename( - "%s is not a valid wheel filename." % filename - ) - self.filename = filename - self.name = wheel_info.group('name').replace('_', '-') - # we'll assume "_" means "-" due to wheel naming scheme - # (https://github.com/pypa/pip/issues/1150) - self.version = wheel_info.group('ver').replace('_', '-') - self.build_tag = wheel_info.group('build') - self.pyversions = wheel_info.group('pyver').split('.') - self.abis = wheel_info.group('abi').split('.') - self.plats = wheel_info.group('plat').split('.') - - # All the tag combinations from this file - self.file_tags = { - (x, y, z) for x in self.pyversions - for y in self.abis for z in self.plats - } - - def get_formatted_file_tags(self): - # type: () -> List[str] - """ - Return the wheel's tags as a sorted list of strings. - """ - return sorted(format_tag(tag) for tag in self.file_tags) - - def support_index_min(self, tags=None): - # type: (Optional[List[Pep425Tag]]) -> Optional[int] - """ - Return the lowest index that one of the wheel's file_tag combinations - achieves in the supported_tags list e.g. if there are 8 supported tags, - and one of the file tags is first in the list, then return 0. Returns - None is the wheel is not supported. - """ - if tags is None: # for mock - tags = pep425tags.get_supported() - indexes = [tags.index(c) for c in self.file_tags if c in tags] - return min(indexes) if indexes else None - - def supported(self, tags=None): - # type: (Optional[List[Pep425Tag]]) -> bool - """Is this wheel supported on this system?""" - if tags is None: # for mock - tags = pep425tags.get_supported() - return bool(set(tags).intersection(self.file_tags)) - - -def _contains_egg_info( - s, _egg_info_re=re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', re.I)): - """Determine whether the string looks like an egg_info. - - :param s: The string to parse. E.g. foo-2.1 - """ - return bool(_egg_info_re.search(s)) - - -def should_use_ephemeral_cache( - req, # type: InstallRequirement - format_control, # type: FormatControl - autobuilding, # type: bool - cache_available # type: bool -): - # type: (...) -> Optional[bool] - """ - Return whether to build an InstallRequirement object using the - ephemeral cache. - - :param cache_available: whether a cache directory is available for the - autobuilding=True case. - - :return: True or False to build the requirement with ephem_cache=True - or False, respectively; or None not to build the requirement. - """ - if req.constraint: - return None - if req.is_wheel: - if not autobuilding: - logger.info( - 'Skipping %s, due to already being wheel.', req.name, - ) - return None - if not autobuilding: - return False - - if req.editable or not req.source_dir: - return None - - if "binary" not in format_control.get_allowed_formats( - canonicalize_name(req.name)): - logger.info( - "Skipping bdist_wheel for %s, due to binaries " - "being disabled for it.", req.name, - ) - return None - - if req.link and not req.link.is_artifact: - # VCS checkout. Build wheel just for this run. - return True - - link = req.link - base, ext = link.splitext() - if cache_available and _contains_egg_info(base): - return False - - # Otherwise, build the wheel just for this run using the ephemeral - # cache since we are either in the case of e.g. a local directory, or - # no cache directory is available to use. - return True - - -def format_command_result( - command_args, # type: List[str] - command_output, # type: str -): - # type: (...) -> str - """ - Format command information for logging. - """ - command_desc = format_command_args(command_args) - text = 'Command arguments: {}\n'.format(command_desc) - - if not command_output: - text += 'Command output: None' - elif logger.getEffectiveLevel() > logging.DEBUG: - text += 'Command output: [use --verbose to show]' - else: - if not command_output.endswith('\n'): - command_output += '\n' - text += 'Command output:\n{}{}'.format(command_output, LOG_DIVIDER) - - return text - - -def get_legacy_build_wheel_path( - names, # type: List[str] - temp_dir, # type: str - req, # type: InstallRequirement - command_args, # type: List[str] - command_output, # type: str -): - # type: (...) -> Optional[str] - """ - Return the path to the wheel in the temporary build directory. - """ - # Sort for determinism. - names = sorted(names) - if not names: - msg = ( - 'Legacy build of wheel for {!r} created no files.\n' - ).format(req.name) - msg += format_command_result(command_args, command_output) - logger.warning(msg) - return None - - if len(names) > 1: - msg = ( - 'Legacy build of wheel for {!r} created more than one file.\n' - 'Filenames (choosing first): {}\n' - ).format(req.name, names) - msg += format_command_result(command_args, command_output) - logger.warning(msg) - - return os.path.join(temp_dir, names[0]) - - -class WheelBuilder(object): - """Build wheels from a RequirementSet.""" - - def __init__( - self, - finder, # type: PackageFinder - preparer, # type: RequirementPreparer - wheel_cache, # type: WheelCache - build_options=None, # type: Optional[List[str]] - global_options=None, # type: Optional[List[str]] - no_clean=False # type: bool - ): - # type: (...) -> None - self.finder = finder - self.preparer = preparer - self.wheel_cache = wheel_cache - - self._wheel_dir = preparer.wheel_download_dir - - self.build_options = build_options or [] - self.global_options = global_options or [] - self.no_clean = no_clean - - def _build_one(self, req, output_dir, python_tag=None): - """Build one wheel. - - :return: The filename of the built wheel, or None if the build failed. - """ - # Install build deps into temporary directory (PEP 518) - with req.build_env: - return self._build_one_inside_env(req, output_dir, - python_tag=python_tag) - - def _build_one_inside_env(self, req, output_dir, python_tag=None): - with TempDirectory(kind="wheel") as temp_dir: - if req.use_pep517: - builder = self._build_one_pep517 - else: - builder = self._build_one_legacy - wheel_path = builder(req, temp_dir.path, python_tag=python_tag) - if wheel_path is not None: - wheel_name = os.path.basename(wheel_path) - dest_path = os.path.join(output_dir, wheel_name) - try: - wheel_hash, length = hash_file(wheel_path) - shutil.move(wheel_path, dest_path) - logger.info('Created wheel for %s: ' - 'filename=%s size=%d sha256=%s', - req.name, wheel_name, length, - wheel_hash.hexdigest()) - logger.info('Stored in directory: %s', output_dir) - return dest_path - except Exception: - pass - # Ignore return, we can't do anything else useful. - self._clean_one(req) - return None - - def _base_setup_args(self, req): - # NOTE: Eventually, we'd want to also -S to the flags here, when we're - # isolating. Currently, it breaks Python in virtualenvs, because it - # relies on site.py to find parts of the standard library outside the - # virtualenv. - base_cmd = make_setuptools_shim_args(req.setup_py_path, - unbuffered_output=True) - return base_cmd + list(self.global_options) - - def _build_one_pep517(self, req, tempd, python_tag=None): - """Build one InstallRequirement using the PEP 517 build process. - - Returns path to wheel if successfully built. Otherwise, returns None. - """ - assert req.metadata_directory is not None - if self.build_options: - # PEP 517 does not support --build-options - logger.error('Cannot build wheel for %s using PEP 517 when ' - '--build-options is present' % (req.name,)) - return None - try: - req.spin_message = 'Building wheel for %s (PEP 517)' % (req.name,) - logger.debug('Destination directory: %s', tempd) - wheel_name = req.pep517_backend.build_wheel( - tempd, - metadata_directory=req.metadata_directory - ) - if python_tag: - # General PEP 517 backends don't necessarily support - # a "--python-tag" option, so we rename the wheel - # file directly. - new_name = replace_python_tag(wheel_name, python_tag) - os.rename( - os.path.join(tempd, wheel_name), - os.path.join(tempd, new_name) - ) - # Reassign to simplify the return at the end of function - wheel_name = new_name - except Exception: - logger.error('Failed building wheel for %s', req.name) - return None - return os.path.join(tempd, wheel_name) - - def _build_one_legacy(self, req, tempd, python_tag=None): - """Build one InstallRequirement using the "legacy" build process. - - Returns path to wheel if successfully built. Otherwise, returns None. - """ - base_args = self._base_setup_args(req) - - spin_message = 'Building wheel for %s (setup.py)' % (req.name,) - with open_spinner(spin_message) as spinner: - logger.debug('Destination directory: %s', tempd) - wheel_args = base_args + ['bdist_wheel', '-d', tempd] \ - + self.build_options - - if python_tag is not None: - wheel_args += ["--python-tag", python_tag] - - try: - output = call_subprocess(wheel_args, cwd=req.setup_py_dir, - spinner=spinner) - except Exception: - spinner.finish("error") - logger.error('Failed building wheel for %s', req.name) - return None - names = os.listdir(tempd) - wheel_path = get_legacy_build_wheel_path( - names=names, - temp_dir=tempd, - req=req, - command_args=wheel_args, - command_output=output, - ) - return wheel_path - - def _clean_one(self, req): - base_args = self._base_setup_args(req) - - logger.info('Running setup.py clean for %s', req.name) - clean_args = base_args + ['clean', '--all'] - try: - call_subprocess(clean_args, cwd=req.source_dir) - return True - except Exception: - logger.error('Failed cleaning build dir for %s', req.name) - return False - - def build( - self, - requirements, # type: Iterable[InstallRequirement] - session, # type: PipSession - autobuilding=False # type: bool - ): - # type: (...) -> List[InstallRequirement] - """Build wheels. - - :param unpack: If True, replace the sdist we built from with the - newly built wheel, in preparation for installation. - :return: True if all the wheels built correctly. - """ - buildset = [] - format_control = self.finder.format_control - # Whether a cache directory is available for autobuilding=True. - cache_available = bool(self._wheel_dir or self.wheel_cache.cache_dir) - - for req in requirements: - ephem_cache = should_use_ephemeral_cache( - req, format_control=format_control, autobuilding=autobuilding, - cache_available=cache_available, - ) - if ephem_cache is None: - continue - - buildset.append((req, ephem_cache)) - - if not buildset: - return [] - - # Is any wheel build not using the ephemeral cache? - if any(not ephem_cache for _, ephem_cache in buildset): - have_directory_for_build = self._wheel_dir or ( - autobuilding and self.wheel_cache.cache_dir - ) - assert have_directory_for_build - - # TODO by @pradyunsg - # Should break up this method into 2 separate methods. - - # Build the wheels. - logger.info( - 'Building wheels for collected packages: %s', - ', '.join([req.name for (req, _) in buildset]), - ) - _cache = self.wheel_cache # shorter name - with indent_log(): - build_success, build_failure = [], [] - for req, ephem in buildset: - python_tag = None - if autobuilding: - python_tag = pep425tags.implementation_tag - if ephem: - output_dir = _cache.get_ephem_path_for_link(req.link) - else: - output_dir = _cache.get_path_for_link(req.link) - try: - ensure_dir(output_dir) - except OSError as e: - logger.warning("Building wheel for %s failed: %s", - req.name, e) - build_failure.append(req) - continue - else: - output_dir = self._wheel_dir - wheel_file = self._build_one( - req, output_dir, - python_tag=python_tag, - ) - if wheel_file: - build_success.append(req) - if autobuilding: - # XXX: This is mildly duplicative with prepare_files, - # but not close enough to pull out to a single common - # method. - # The code below assumes temporary source dirs - - # prevent it doing bad things. - if req.source_dir and not os.path.exists(os.path.join( - req.source_dir, PIP_DELETE_MARKER_FILENAME)): - raise AssertionError( - "bad source dir - missing marker") - # Delete the source we built the wheel from - req.remove_temporary_source() - # set the build directory again - name is known from - # the work prepare_files did. - req.source_dir = req.build_location( - self.preparer.build_dir - ) - # Update the link for this. - req.link = Link(path_to_url(wheel_file)) - assert req.link.is_wheel - # extract the wheel into the dir - unpack_url( - req.link, req.source_dir, None, False, - session=session, - ) - else: - build_failure.append(req) - - # notify success/failure - if build_success: - logger.info( - 'Successfully built %s', - ' '.join([req.name for req in build_success]), - ) - if build_failure: - logger.info( - 'Failed to build %s', - ' '.join([req.name for req in build_failure]), - ) - # Return a list of requirements that failed to build - return build_failure diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/__init__.py index c1d9508..581db54 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/__init__.py @@ -32,15 +32,11 @@ def vendored(modulename): try: __import__(modulename, globals(), locals(), level=0) except ImportError: - # We can just silently allow import failures to pass here. If we - # got to this point it means that ``import pip._vendor.whatever`` - # failed and so did ``import whatever``. Since we're importing this - # upfront in an attempt to alias imports, not erroring here will - # just mean we get a regular import error whenever pip *actually* - # tries to import one of these modules to use it, which actually - # gives us a better error message than we would have otherwise - # gotten. - pass + # This error used to be silenced in earlier variants of this file, to instead + # raise the error when pip actually tries to use the missing module. + # Based on inputs in #5354, this was changed to explicitly raise the error. + # Re-raising the exception without modifying it is an intentional choice. + raise else: sys.modules[vendored_name] = sys.modules[modulename] base, head = vendored_name.rsplit(".", 1) @@ -58,12 +54,14 @@ if DEBUNDLED: sys.path[:] = glob.glob(os.path.join(WHEEL_DIR, "*.whl")) + sys.path # Actually alias all of our vendored dependencies. + vendored("appdirs") vendored("cachecontrol") + vendored("certifi") vendored("colorama") + vendored("contextlib2") vendored("distlib") vendored("distro") vendored("html5lib") - vendored("lockfile") vendored("six") vendored("six.moves") vendored("six.moves.urllib") @@ -74,7 +72,6 @@ if DEBUNDLED: vendored("pep517") vendored("pkg_resources") vendored("progress") - vendored("pytoml") vendored("retrying") vendored("requests") vendored("requests.exceptions") @@ -106,4 +103,8 @@ if DEBUNDLED: vendored("requests.packages.urllib3.util.ssl_") vendored("requests.packages.urllib3.util.timeout") vendored("requests.packages.urllib3.util.url") + vendored("resolvelib") + vendored("toml") + vendored("toml.encoder") + vendored("toml.decoder") vendored("urllib3") diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/__init__.cpython-38.pyc index 4c1bee4f0940bf0eb373c54baa7dc218ed79b74a..e6374119bdeb0f27237c5e5a0ededacdfd19f251 100644 GIT binary patch delta 366 zcmXYrze~eF6vuP<(Z;haRU{QDP9j!p4%DHoii4ZrR9svnUQQF6=ECJ#+tNXFaFlYR zZu$?DZZ7(FWbq#m5!}TK<bC0N_`V14eIKl+O6jy%go>=%-`n}u!lYDHSJlbZiKeoZ z>G&1cr06#80Z=5H8Cx0mGVZ5zwYE|_n60ae01QM^+bCPQ!i^4OEuf^j6IA;>Izt}q z62ykR-nEZnhLP)pJ_#^ooW%BEI6{3A_EF$pplHZF8t&K)6#JaiBL{b!D-w%aefQWf z)iNjpX36LyW7EFzf+X)mk?XTKDPRYC1k;c+D#w^G?qB+eiD^KY({+;hbVmkUe%ThE zdQ}+4<LudJ>vhOTOoKj=n?&cd8;lBRw@HYpOIYSyd0aa2J@>LamI?HHK{bJtq34!z Vrj^syG%<yT;sZkQ11sVkn*VDSZJ_`F delta 216 zcmbO&-Y&)$%FD~e00hs=HpJ-(P2`hd`o=g>$CsJ0=+nlUC5&t-%)tzr7MuN;gcupi zCMPm$@QJW6l(1%V6<IJc0O91B%%9~<^-FRK^b0ZzbTjjcOA>Q(bd54hN-K=>6G4KL z&$F0lbFwiBFbXghi2?1ZV%5?s&&avOlbo2Gk(!*JS5lOpbBiN6KPSH^F*k9tFRKhE zM^1inc3Ngm>f{X83G8eIl_mMPIh((;hOkVo<XR+B1T=<)orj5o5eQjX*hJVkq$cZg Kdrz+676$-hgga6I diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/appdirs.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/appdirs.cpython-38.pyc index fde8231b22b0f6b505ad327f9cd5ce00c667a7d8..00ddaff10a7f5b20fa2e746a6e9929acdb243bd8 100644 GIT binary patch delta 4710 zcma(UZEO_Bb!Tty!*}-CIL3hS#~Opp8Mp&%z8qsP27|#iw1xr~kz;)`KCgY=J<sj| zb`CBPBtnshNGGb4A4%<~Rphi)Q(5Yd_D3tVm7=Ou+o)2cO_fTODwVcURkf9(P_=z; z&L6~amDswsZ)V=ty!YnKoA<v?e)KkpUaF`FEASWl&ks@^?A2&}@nuy}sFGADNfM?~ zmHO@}jLi9{Hcw6}cgbCn)To~Zvi_uBegnw>^G^h+e~UtclWH==LcE`qCBrZqnJcHE zdBPt`%1AQ8B6Ah<KnJuypNz67P?Q11EDa|sr{85ooQS~0%d{LPXhpKp(oqzRPOAJJ z7MQ4_m53pOg{mXTO4>y?(CT|6xq&`SpQ1H@Rnu;|k=6qC6g^5e(anI>&>mVxw*t12 z9;5ZN0kB$noHo)Xz&4#$s9vPa_Y~U9HsAFnx6p00<(`tPquc2Y_->`Gv<<%XbSI6$ zw}DmC@TB^X@cXkhu*3Fj<5W|!i72c-sb5yC6Pm)BC&RG*5>fDfwo3Y8Te5{UNQ$}@ ziswrdtXP-SuPT;$MJYkLi|z(h+u07f2UMy2B^pn*(nPY2?oIAwF}jbDS_lg$jnVz` zyM?u~HrhcuANZ2(Z0AYkT77aCtR7&y*lyO&cHLFS)Dq7_GW`o!Ik?JKysLgLlRAyc z4lOf5Mtq(cb$UN=9A4(2RrJV%_4RCg(mHi|oCZdeSg&}fK3AOe?~8ZFJJSRccIgk2 zRq??u4L_$AKtZ_{y-i%D0Ezk)aQU=Kl@Vou49AG)Gc7l!dTM;H7j#%=idpW0!u`PY z$<@TTJ;f4yCZC@$6An)&s9~8bo3^>jocOJo*@S+BSvL|{b2O2gamQ_|BYrsHm@eCs zGt!erhB@Mm^3APf-5F-FTRGmd0Zq~XXo{-vARr!zKZ1`k{7AI=5@nt*oi#nxa>XUz zpU4Y~J=zD_Azg3LZLZ%*#M8DlW@ZxIy}8`5F~xdz>*kp5jx*f`z;$XfN4IQOXSYnp z6<zh)7mt*UsH8$Xh_nZzpk}u5j(EPhL3|i#A~Eqea;pU$B==ha0T_A}d57^7HC!V_ zO}<b3v^+tY7ynuQX0WjWZS`vUMg~p}ruxng4V@oO^<KDeviD+dKaYxcYaX0I=Pmg8 zMieZi*P+Y+cU*4fJfFjI3o6F|dF0kw&Ef7WSe~}0ay_q$dm9HPkT-)7ti}jVkU6zL z?kn@^tLn5iQZjtO_k^x3sI?8i0^#+Dqct3N#bW^8fS(LN00U44qga^N;Oa*4n`4`b z9QE<70K8z%aL2(|&+p{2rn?X*$!kD@MkFYk%4b~@spK}j5Ta;)N#`ykEV&a?V#S@~ zFz*}$pfrU@h-jn=ej!q=R*{hSRqb}NPkbCNEao<S=ntT`!K+_tXemk~n{g~1izcpm zm*cj<=W@p@7V@SQBI$({S9p~&z@==$5WfS2P89&9Aw;Uw8n7q|Hbn_XL(`D4;vWsQ zU9Z8wg<D`Uz}sC20~{#zwsv3P4+|=P=&BRGIjx`-)Onb-#$0vIPt|#nJ4k(^w{ffg z22fF9G`5iYi!V0D0%X7V?)Jl1w}Vs};`-a9K)ALX<~bi=aKp@#CxXq9S_XJc>d5du zhD8T`j^Wir*N)@GFOWdIeMP1W+KQi~%>SZHJhQ7Q6Dp<5K4e=>bD4TFE_-lcH-h*u zLMd=HA1Y-&ta|^qK;vNOl*SMVgWs$CQBn&rz$jF!0M!uThhhDqcpR@Q{{vt$3@V=$ zc58jn^*dc|prE<IyDIN;Lj~<Fxvdox{$7DlZL*ACamj=_R|c^m1!dj`(TT3iz+nPf zAAfIohWcgvhCxLDF4ec>e3%C3mt-!}fh3G`tJ^{5A~du_1{b#!2+BWA2<ChQ3Gh*A zcCoE(bFfBM6J8Db>G%A7MjDD(RE)$E#aQ{$sf49cnr}jEGXT$b;cAB$HXYM)T*FE; zFPOK?v`v{;ow{jSDLjTL*G`SjK$(^&WA#*j=8SkjJ7-#^ZI!evof8OP>F7pF2L&y| za}t7k#=*cU%}Zz32j@h55Z6iX;>YpVFr^<H*b(bQV-Fx$68LF(U^f;7lb;eF9@s+q z7XNj?3Qo!T9KDkmG)K9?XA*;U#^LCpeosT(^JVQ!EV$M&GVNs9lGULXwH{kXb-COM zh(N`*`1R3Uq<`_>M=QxQ9CoF|)~_B3Tnc!a!?I)RmKP*gyUS221wM6Csc#5+?D}!6 zma-Os4r${$WeUpmna@g+<lh$B@pO+ABCYXrdGOW<k#?M0M+6doPki(Evq#PX1}0!h zTX!q#aU=2fMR)J@BZDPwJcetz|F3Q&{vmMJiNE!p?!+y`G%h2w#`^VCBi)b1#EGk& zLnX#O_^egE9wXBI3>X_kO<(sibN?4)M!KJidwtKG8vqP0HE!n^cV|kGlb)9jlzxy~ zk!DHptH~}gEX4dYfVV{Z$wUCLG!cJqcuMe-e<fuibt)0rfHd0>REyV7o%Zvm0T+Kf zb(UNfd;8lWt0Dtpw0|3UU%c4gMy`wR^#24TOrPExFpzmvynVXC&yOPWFHax4@(fOv zRuFp@fLAeYIH_?nGoDJ18{8vlj#u&8+^tV#m@DhZn4P822HiBFoaAPpvUKeKv!G}8 z5KDaZ%(rxG9v<Pjd(?tJ2J{kOCNy_SKTnHm0|O)@-X3T_B(34F=0(zuNwX=a{f_JT zM)PAl3)6fG*EAUJf6^QgI;*RGRkWXtliT9z*~eY7VS%P~!ZKn+)`mye?MnVn2x^7V z#n?vAZ*XqRctPl-;!fV;cf>2_>Yxu?IJY;zkYh~z{#-ZPfoKMR7dpqd#j+jyxe3Eq zgiD)W!1X%_unu`4urTGAvy4B7bE62*wNGp!Fe&AHY8%fFHjpOq=3t`uDiDL=E_^=I zvg4Z*Q^~>1qVTS~7Qanqs|v~-^cnNyGTi6{+ICHGi3^XF$uQqrdLLa?rnM{ZE5K?@ zHNHj^<&=f@fqvPvsD0DXWhbY*c2SpiLR>#@WoLA#hg7#M{eo=W_5Ja1ScktM+cj?( zE?fz^=>U^H%5;nuG<NVf&@mmB+HE`-Kxk!jX9gCh9Q`I-V63E0$}(VNWF1@Q%*}JF z2nr2n*@%ndAm6xQn-nbM_GlI*OqsV(ptMsrEUI5B-EC4F%Q~#2!n9=DkGmW-92VF6 z;ejw^gF4Dw!_0zU;H9RM&N~in#bGS07h!wd<F1=?x)O;DY$QJlPl_pcyyT2T&deoD z$H_A%(b0LZqi4w-17kWvZ=zLsxN|dl??~UkfRsOUqHjbWLv_2Cc366ha5H0CMt0eD z>5w?=0QAFK%P$3Z8gj>cUO<Y6%X?|3rP!U~+~!_n(6%S@IXQ@_@{0CC%jP_pV~{eu z2f!&f4o*2BN;pJRXsxTEosugaTuS11gIk-Lkye(lUc^?bm#l4vMeR@@85YT*honLL zWhj1W5C1aId687=2IJ_<RLb+a`COLqJ-AS{x?oykHmv#}9b{kVl`pg4iY#rg=yHBk zWQX_2mfq7Wc*uQ$;_3zL(FvAzWkKcF(R2&JZ3K9(I2IUrv}BvaCt#S2EERw_R1A1q z+EdaO{5+CgT)BfhKUR4MKkyv(G-wbUPs2GrhLo#CSYlY$y-@d*P4ijSgCnN^KnrVR lvoOxrZ6GzifEv)khr%bq?cvVwQE~r#v(Fc*5$~Me`9GEYRW|?t delta 3640 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 J!5in={|mT8DBJ)5 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/distro.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/distro.cpython-38.pyc index 8313b27c55b21c69f22d8afaa93d498d73b9fd0d..cc7402b3154ac010bed0de514227eb2141f64651 100644 GIT binary patch delta 5591 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 CD$)@E delta 5462 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 V)(mI4V~BrpvDH4USR6%8@_!<5ke2`e diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/ipaddress.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/ipaddress.cpython-38.pyc index dce6895cbdda13d509c3fa4ac61db8415d7f8913..6ceac1d49bc87440932dd03f308b1beac47f4a88 100644 GIT binary patch delta 820 zcmWlWYfy}F6vp4@|CY<TOztLQF@_mb?-&VV3=Lx#mqBtD+qP7j-R!%Wb}enzEmBQK zxvX+&NaX{L(rlT@B_sEkvL?bX$zq0aZ;03V^qg}(obx=t{T*^uhuk~1S1+BU)tFA- zI(hPi-m_&)p!4ofvdY6|u2vGQn@oz$k(QR6q^LHdl3=hTnNo~ao86>Fq&u9-7L#R* zl9Cj!q&n=0R?CEl$%>j}H-)DfjAp||lgj7h+_YKiwF}NDmy|5IkSv*Ho8FEDxU_DA z7$|wL1KM0@dtrt(Qq!`gWpnUyDMkvC>_KLoZ53^EoDLcM|5qVIPYCG#1__FAmSPn( zJIfHq?yb{+c!Fm*wYoZC;pf{7fP<%JEChCOj(a?i$90)AfMX0#I?$7yJ7s}7-oAUP zz;*WR-7V0<(ffzX_|EY;ZNO-no3|B1xIV9&z$Ch#e-Pu?NQ;3PRC&;Wxug^%VgVg4 zs6`pa7XFd3f?|$V!Nodn6p+c$$5fzzDvPYhrcuSYIK-93kw6g#j)wtfdC<xJ0CU)> zLBJK7Rg#S*+*mSS;5O;cTtpi+p7A3<<)s1fJ(v!+>*>;2Hv~;Av!g4Omt~*_jV;eb z2>HqnU;xdj$j2>isaUMTSPri$1v04Va++phUbSA}04Mtv3EbeC+PE%g=FsbYf$99E zzEs9a_BIp=6w{QuUSx68-7i2DHQc|363%{*0@Tp2hnsMNHZ~^W7CmgN#(B<qG&rco z<F1mVhW^LXm)0H~N)63M{G{+FX8fTePkiV@OZ}VCjc)o=(T^uR{R#}_uoeptN#19% zTBx6&jRc}-K&y&q%4$u=d=@X_faPp>nFA#7r&n5#DkZ!=fqNYMW|@G8*0i03mpa?7 z;W%A=+k^@_)SiXQG~%5dwN&^{MIGq^9@JA#AX5u8<o!N8An*G<cuXTd6l!>UABJ>C kJ2!vJhQ`<U!;P8r=7$r0UiZ^15W{ymMhL8=kH7W*08Fh%NdN!< delta 786 zcmWksX-L#@5dFX3-@CNSs8lu~`d}EAsRdnP6h$IhsB4h4<p*`Q*4#DBTUS)n+;G$n zUTLQ55mZi@nP6&c2pt%hcH5zwX;73MYSG{M^ybYBym>QSb8^X?>=x<j>LMv&J9j;H zX8R4d12X(+MWzSo<@Kr{KjY~nzodku%?W1=MvYFl**`uYC3Tx#vq<u=Y)%P@Rff|7 zGNeQ)1BsGWPWCb)4jD>j5+>w9VTDo^TIl^1EGt;n+DA)AB|FJzr*%nI)0OkhOWhYm z2qBij4HT1RK@1_i4ad17eK(*XUz0aEXa2)!cFNKKshpS{2ITXdoUMSFr*ngW8um4% z0!z3#Ul!=&wt}4k13XbwAn<~9CEhY-`9j$wu#t=x)8WBiFFFYX(Vy}PY~nJC0QS;& z#d#d0W0mm;rNPQxv~o_>Um4MqRo#Vj4y*|Ra#&Yu04iv_PLC1_uQ#KL$Lj-tT3+4Y z3s^X$(H-dI=*w$>UeY&}B7zs1LIsBCP)jE!XrX0HOxe>Hn+JWhJi#p8YrO=}i8dn~ zXrwJ0E)>~r#xj~{zW{eKbd=)(J6w%$fe)*@EI?LycZ#yZxo(v}DOdJ{3k>pPZ>$4G zc>my-z#djvEi%+>9jX(kqqv7PDC&Il9k@k59uMF$-+rQl=y9ZX6{~2+a0~{id^jEt zXnwdG*ZAhswRU()kDe9d7pX_JSfKl(Jy=fJV`t$=-^P-#l21PW0eErr%QL_>vc8H` zob-CV0SKhvHwFaL%{QqytTcP_!MFQ>C@vi@15UB$d&R+IGJj~mL*DW+N+6F4CmT^s zKDGhW(~NCIv^!CMtBT%zN<<fhP8o5R`lk%&qrlH5+^0LAa}_&xP8Z`bS*HsXtzk1& z%5f%UJe^@<{49lX-LhXf2%%-a(=f`#zqP{oh_fUab}9cxjXmp{*31j2Y3*Ote-f`h A8UO$Q diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-38.pyc index 2f464de71a96002004c71b7b25787ad15725e8a1..3a680d5a181edc04e26d9bbcbfd890498b52f913 100644 GIT binary patch delta 75381 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 delta 56072 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 QLPN;T$WG5rrN7?)2MrTB00000 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/retrying.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/retrying.cpython-38.pyc index 83cfa7beb0d494cb989ec93f56a7a5c1901b4a58..8795633b0f761708c2e072c17ee6da742c5a7c5c 100644 GIT binary patch delta 94 zcmX?X_ri`Rl$V!_0SGkz?TX*Xlf&d3rJs?Xo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5(l8q-=C0R0ys!T<mO delta 57 zcmaE1ci4_6l$V!_0SKO#ZHU{*lfxuus$Y^@pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JyqjsQ3;+$w6HWjC diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/six.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/__pycache__/six.cpython-38.pyc index b4424e17cec5f139ec5eef9403e7b1d61adc8670..4b3d4f0624a479902676075f19d48837f5b52a0c 100644 GIT binary patch delta 7043 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 delta 6358 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 ZF%sjSlg%ar(B>r1O-@Np5wqO${vR(;9ZCQI diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/appdirs.py b/venv/lib/python3.8/site-packages/pip/_vendor/appdirs.py index 2bd3911..33a3b77 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/appdirs.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/appdirs.py @@ -13,8 +13,8 @@ See <http://github.com/ActiveState/appdirs> for details and usage. # - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html # - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html -__version_info__ = (1, 4, 3) -__version__ = '.'.join(map(str, __version_info__)) +__version__ = "1.4.4" +__version_info__ = tuple(int(segment) for segment in __version__.split(".")) import sys @@ -37,6 +37,10 @@ if sys.platform.startswith('java'): # are actually checked for and the rest of the module expects # *sys.platform* style strings. system = 'linux2' +elif sys.platform == 'cli' and os.name == 'nt': + # Detect Windows in IronPython to match pip._internal.utils.compat.WINDOWS + # Discussion: <https://github.com/pypa/pip/pull/7501> + system = 'win32' else: system = sys.platform @@ -64,7 +68,7 @@ def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): for a discussion of issues. Typical user data directories are: - Mac OS X: ~/Library/Application Support/<AppName> + Mac OS X: ~/Library/Application Support/<AppName> # or ~/.config/<AppName>, if the other does not exist Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined Win XP (not roaming): C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName> Win XP (roaming): C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName> @@ -150,7 +154,7 @@ def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): if appname: if version: appname = os.path.join(appname, version) - pathlist = [os.sep.join([x, appname]) for x in pathlist] + pathlist = [os.path.join(x, appname) for x in pathlist] if multipath: path = os.pathsep.join(pathlist) @@ -203,6 +207,8 @@ def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): return path +# for the discussion regarding site_config_dir locations +# see <https://github.com/pypa/pip/issues/1733> def site_config_dir(appname=None, appauthor=None, version=None, multipath=False): r"""Return full path to the user-shared data dir for this application. @@ -238,14 +244,15 @@ def site_config_dir(appname=None, appauthor=None, version=None, multipath=False) if appname and version: path = os.path.join(path, version) else: - # XDG default for $XDG_CONFIG_DIRS + # XDG default for $XDG_CONFIG_DIRS (missing or empty) + # see <https://github.com/pypa/pip/pull/7501#discussion_r360624829> # only first, if multipath is False - path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') - pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + path = os.getenv('XDG_CONFIG_DIRS') or '/etc/xdg' + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep) if x] if appname: if version: appname = os.path.join(appname, version) - pathlist = [os.sep.join([x, appname]) for x in pathlist] + pathlist = [os.path.join(x, appname) for x in pathlist] if multipath: path = os.pathsep.join(pathlist) @@ -291,6 +298,10 @@ def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): if appauthor is None: appauthor = appname path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + # When using Python 2, return paths as bytes on Windows like we do on + # other operating systems. See helper function docs for more details. + if not PY3 and isinstance(path, unicode): + path = _win_path_to_bytes(path) if appname: if appauthor is not False: path = os.path.join(path, appauthor, appname) @@ -567,6 +578,24 @@ if system == "win32": _get_win_folder = _get_win_folder_from_registry +def _win_path_to_bytes(path): + """Encode Windows paths to bytes. Only used on Python 2. + + Motivation is to be consistent with other operating systems where paths + are also returned as bytes. This avoids problems mixing bytes and Unicode + elsewhere in the codebase. For more details and discussion see + <https://github.com/pypa/pip/issues/3463>. + + If encoding using ASCII and MBCS fails, return the original Unicode path. + """ + for encoding in ('ASCII', 'MBCS'): + try: + return path.encode(encoding) + except (UnicodeEncodeError, LookupError): + pass + return path + + #---- self test code if __name__ == "__main__": diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__init__.py index 8fdee66..a1bbbbe 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__init__.py @@ -4,7 +4,7 @@ Make it easy to import from cachecontrol without long namespaces. """ __author__ = "Eric Larson" __email__ = "eric@ionrock.org" -__version__ = "0.12.5" +__version__ = "0.12.6" from .wrapper import CacheControl from .adapter import CacheControlAdapter diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-38.pyc index a2198cdf65aa535f88391bb559492ac2658315fc..c1e46750213bd8b8211e338ebd27cb52f4a45418 100644 GIT binary patch delta 97 zcmeyzyqJY2l$V!_0SGkz?TVks^Ni7K;^&pl>G~P@xvBa^m8GRwnfk>=$@(dYd6}s> z$@xVksl|E~l~wv>sd;7kIhjfN1(hWk`FX~A7W&1RC8@dviOJcC>8Zt&cQLvE0F(tI AiU0rr delta 60 zcmZ3?@{gG(l$V!_0SKO#ZHSx5^Ni7S;^&oePWmOe1^NY<1-hAe#U+V3Il4v}CZ!d| M`H3LG$@dvu0A2GH6#xJL diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-38.pyc index 9a8ae56cf7ec857d17e2b0a7fae09765936a0d41..c42b9d49b97bf0b2c409d123c2b9f4ef7c0a18d1 100644 GIT binary patch delta 94 zcmZqVS;oT?%FD~e00f%<cExYxX<&3t*3Zb#P1P@|EG^B-)Gsbd)=x>y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7cOiZPr80I=2|n*aa+ delta 57 zcmZ3+)5yaU%FD~e00hs=HpFe@X<(GI(=W*_&@ad=(9O&%E=kPE(KX62DXlQhPXq~W JKF=7=0s!9k5+?uv diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-38.pyc index a2aa8c594262f0d174ca9695fb977f7f5baaddbb..1f583848cb8f5b422949e8c01b74f44d2ecfb33b 100644 GIT binary patch delta 169 zcmca3-YLNs%FD~e00f%<cEt+`Z{(|Hv<m@pOBhNRYZ#iDvY2YvYdHEC85wFAQy8*2 ziWEwin;G($YJjrwEH$h^lC_4dz$gX8XRBc@u$jD{@w0Q9enx(7s(w*rX=zrbesNK< zeoA6qW@=7yeo;wkv0g=Gm3~=jUYUMQW|DqEWl2VUp0S>VesN|=s%}AIa&}^RYVqU? OOlFKCo7tJKasU7?KQj*i delta 124 zcmeB_xFgON%FD~e00hs=HpKlG+Q?VUXyyatmN1ks)-W_PWii#T*KqVPGBVUK7D$ya zH#5{Q#Iw|}0!h{ywgRmbpsIMb8s-9%$;TN#%Q@<o<QC``WESXV<`tJD=H%!aWtfy! V80RN~1SkJxGGpY~Y{Gn%0{{}~BhUZ< diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-38.pyc index 6d2055cc1037e5d34d869b1f0a714a83558a72d7..6c4b3851105946dc801cc50dbc61cf5acb5b6181 100644 GIT binary patch delta 94 zcmX@l`-PV$l$V!_0SGkz?TX*XQ_kp|qMwnUo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5(lA)_8E0Ox8U00000 delta 57 zcmeyud!Cmkl$V!_0SKO#ZHU{*Q_d)7uV0c|pkI(#pqrUjT#}fRqid95Qd(i0p9m7% Je2h_#6#)O;5{v)< diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-38.pyc index 0a7d40c9415c9d0d9678eec464bdbf6421751ae0..6eebb9e95e849a61bf77b3ccfbc827a4737f3d95 100644 GIT binary patch delta 109 zcmX@h`iYe%l$V!_0SGkz?TX*X^M{e~)?`j52VZ`mP!Wjum8zeSpPQ;*R9RY@m8oA` zl&qhUn3tKFlbl~vl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2(-keHmEn4VfZ IxsWLa09B<VnE(I) delta 72 zcmeywdX|+Zl$V!_0SKO#ZHU{*^M{c!YBDF2g9aZ^s0c*-a?mfyEzmE>EYQu&D=taQ V$<Z~+Fe$At&QAmhPM*dT0|4306{7$E diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-38.pyc index 9590f54f23782cc4749284db77e6bad49e261cca..f6d7703c6767839cc47e319e85ff1357384b2714 100644 GIT binary patch delta 499 zcmaE9{nCanl$V!_0SGkz?TU9b-^ka@<eaIWk)NBYUsPFInw6<vT$HSzl9-p7nv<Mg zRFYb(S5aA|UzVCzrk|6Uq+d{3l98WhtY@KLoLQ2pTacKXotU0lym>v72BV${(A*lv z6ozb$BEAxaW`;bb8paxic*YtgAjwq2T%c6K+{^%Ev(&H@=uH00yn#_<^Ews>ekK;C z$sdHjSfp^*ur1(C;Ys0L$dt`Cfw4%aglPeD3g1FTMurroV4&74exRsN3V#h7Sl$OL zFEII!h@_}sFY`hsMuxmCHB4EIDMHyyK$SI<3q-{xJBaeDi-2`76)~iU)^LFJ9;@L< z5tU>}5zA%)syqfZNgQO7GR!2a6bYEF8nzS(NrnkP{a|&HAa%S@bs(2%N^QO&YQU&- zi&5(qOIc!3Wsxy3FsfvOQi}`n^NLdyGEx&$Qi~Ka5{ng-!hrHt3R;`l#pM_oGbXD^ z#4}b*Zj<m}VHaZL+I&VLiit6MvbuDics9_Cq8w0cu@*^z*kK?dck&r&dB)PoZ=@9% ggC_IJtYRw!3D->CE91l!T_gljFIrSTnN#)w0Cxh6k^lez delta 382 zcmaE9^U|6xl$V!_0SKO#ZHQ|!-N@I>B<G@El3So(kXfLcnO9trn3JPxlwnd@VVs`` z65M=+NrO>M2dJfnv4Eq5p_!qEA)c{@2}m;4Fc(ObFoQ){YFG+XCTp>5VB=wAW8`6+ zJdsU!^Jf+fex@gklVwG|NYpT7@lRkZ(n;a2VasL%u}YX0FsJZL{x2#i&D+bokcp8Y zZ%YkR7GnxuHWN@j1}x7%xmHwOT>z@*L5g4v2Uz#A8jch}Nrn`mY!;x}Wni_!AhVQV zW?7|(z;xBHrHDu}0M$JJs}lvO<AthAVG3r@6x*ySX27_)NnDnZF>Ue!iFn4MNs=C$ z{Ujrp7?UP1m+lkK1O`A+7Ld?nEs_GU!$3s#WFHxM#^T92G75~IlY3=WvE_q=t0vpZ TI&lRR34zp$7S&GflzjjI9TR9V diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-38.pyc index 0d9d3c4b132c7ccda783e27995ecb2226faced03..d0d0979df9abebc8e0abd8f29c01048aae5b1415 100644 GIT binary patch delta 94 zcmca1@K=B*l$V!_0SGkz?TX*X^OMOrOFtt&H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*kVGP5Zw02WsvEC2ui delta 57 zcmew>a6^D6l$V!_0SKO#ZHU{*^OH%=Rlg*+K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J*@M}X6#y5761V^W diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-38.pyc index 0ff4dd1fca3d40861a2a330e32044f1bdd547731..f8f230b35ee20219db0205c9764bae8079b0d339 100644 GIT binary patch delta 94 zcmcbv@<)Xyl$V!_0SGkz?TX*Xlf&qosh^Rbo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5(l8sk9$0Q~kL%K!iX delta 57 zcmeyPa$SWdl$V!_0SKO#ZHU{*lfx+IqF<6*pkI(#pqrUjT#}fRqid95Qd(i0p9m7% Jyqoc$000eO6ITEL diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-38.pyc index f66bc59feb61e0502ffab704aaef32c0470ec90b..deadc4e3b3b0a373ecb207dcf381fb9b66631dea 100644 GIT binary patch delta 167 zcmeyM(51*5%FD~e00f%<cExYr$m`1JoS~nQpPQ;*R9RY@m8oA`l&qhUn3tKFlbl~v zl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2(-keHmEn4Vg^xqvZ?gOOwMZO#dd zeUo#zb~8@dtifH%$hc(kJf3xoD<}K%Rx-|+e4MwLaRX3VesUIH1c#d@<1OZ*#PZ2k T`AiwNP3Gob#HcoT9seN!312$1 delta 140 zcmeBD{Gh-a%FD~e00hs=HpFRd<aK3~bJj1(EzmE>EYQu&D=taQ$<Z~+Fe$At&QAmh zZl21R#lgrniE9F5&*X_*yBQ~K_T?^RWLz})FwZ*1<&%qeD;Z}^e#6_$xDF^SKe?YT qLb!^xv?NW}LX+_pM`~VjeoAIu`sDX~ri@!AtMV^mRGEB&{}2G1rZ5x$ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-38.pyc index a04a09c211a0481d4072b80b415a51b98273394d..41c64ba6087d8377656a8abb5b66b31bded873f8 100644 GIT binary patch delta 129 zcmeywGM|+<l$V!_0SGkz?TX(tk+)CE3&^QqOkv38DB>$&XlBS`s$r~UtYIsVn7H<X zbDDleer~FMQDtdqR;GS&QL=tYVqRuyPI7)xNouiPMP-$KS!!OHeokhRenDkPMt+{L fo`rsKW=X1UL1J=tVtQ)v<lT(6j6#!tGFAcrDJ3gd delta 84 zcmbQw`iX@%l$V!_0SKO#ZHSvck+)CC3CO8oEZ`_%XlAHotYIq<n7H+WoTGk8Zh?M5 jW`S;IUU5lcPL8fohDm9Kaeg95aPkXATSl(QYD|>?8NwPP diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/adapter.py b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/adapter.py index 780eb28..815650e 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/adapter.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/adapter.py @@ -24,7 +24,7 @@ class CacheControlAdapter(HTTPAdapter): **kw ): super(CacheControlAdapter, self).__init__(*args, **kw) - self.cache = cache or DictCache() + self.cache = DictCache() if cache is None else cache self.heuristic = heuristic self.cacheable_methods = cacheable_methods or ("GET",) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-38.pyc index 11f06270da1e61e4ea5cfd86c3201719f0fb9866..fd9a08803169e6758c2c603b857eb84c08a61057 100644 GIT binary patch delta 91 zcmeyzxR{A2l$V!_0SGkz?TVksGub&$KO;XkRllgRv@|PIzqlw_KP53QGc_kUzo;a& tSg)e8O1~^MuS`EDGfBUovLquv&sfhwzc{lbRkt89IXf{uwRqxQM*xjVAkzQ< delta 54 zcmZ3?^pBAzl$V!_0SKO#ZHSx5Gg;14za+OnzaX<fH#4ueBrzvP*C@lJw8A()5hOVA Gks|=f01{sS diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-38.pyc index de16a74cf4510ae67a4f948c52f627c3a98ef686..3e288344c03cde53d8d38096b062747ebe0226eb 100644 GIT binary patch delta 117 zcmdlYc~Fu!l$V!_0SGkz?TWYD$ZN&qT%ezkpPQ;*R9RY@m8oA`l&qhUn3tKFlbl~v zl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2(-keHmEn4Vg^IhAP@lK@9fesXqN SW=?969MFPWVw=rbYuN$*y(eb? delta 104 zcmX>oxkZvUl$V!_0SKO#ZHNop$ZN$U=dE9oTcBT%S)iMlS6q^qlcQ^tVNzOQoSz61 s+}y>qib+ER$kK~1OU+BkFVf4&PtH!u%t<Yh1DbP730Z2h3u`Sq0MDW#YybcN diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-38.pyc index aaba3ec611b643e98de9c90c7902c1b3437065cc..e564a4fbf68bb73e44f0de75db83e2834ae89647 100644 GIT binary patch delta 94 zcmeyyJ)4Iol$V!_0SGkz?TX*XW5MWLsGpIao2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5&)iE#=G0L85!zW@LL delta 57 zcmbQu^NpJ)l$V!_0SKO#ZHU{*W5ForqhFF+pkI(#pqrUjT#}fRqid95Qd(i0p9m7% J+|D?K1pw>?5=#I8 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py index 1ba0080..607b945 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py @@ -69,8 +69,8 @@ class FileCache(BaseCache): raise ValueError("Cannot use use_dir_lock and lock_class together") try: - from pip._vendor.lockfile import LockFile - from pip._vendor.lockfile.mkdirlockfile import MkdirLockFile + from lockfile import LockFile + from lockfile.mkdirlockfile import MkdirLockFile except ImportError: notice = dedent( """ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/controller.py b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/controller.py index 1b2b943..dafe55c 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/controller.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/controller.py @@ -34,7 +34,7 @@ class CacheController(object): def __init__( self, cache=None, cache_etags=True, serializer=None, status_codes=None ): - self.cache = cache or DictCache() + self.cache = DictCache() if cache is None else cache self.cache_etags = cache_etags self.serializer = serializer or Serializer() self.cacheable_status_codes = status_codes or (200, 203, 300, 301) @@ -293,6 +293,15 @@ class CacheController(object): if no_store: return + # https://tools.ietf.org/html/rfc7234#section-4.1: + # A Vary header field-value of "*" always fails to match. + # Storing such a response leads to a deserialization warning + # during cache lookup and is not allowed to ever be served, + # so storing it can be avoided. + if "*" in response_headers.get("vary", ""): + logger.debug('Response header has "Vary: *"') + return + # If we've been given an etag, then keep the response if self.cache_etags and "etag" in response_headers: logger.debug("Caching due to etag") diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/serialize.py b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/serialize.py index ec43ff2..3b6ec2d 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/serialize.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/serialize.py @@ -107,6 +107,8 @@ class Serializer(object): """ # Special case the '*' Vary value as it means we cannot actually # determine if the cached response is suitable for this request. + # This case is also handled in the controller code when creating + # a cache entry, but is left here for backwards compatibility. if "*" in cached.get("vary", {}): return @@ -179,7 +181,7 @@ class Serializer(object): def _loads_v4(self, request, data): try: - cached = msgpack.loads(data, encoding="utf-8") + cached = msgpack.loads(data, raw=False) except ValueError: return diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/wrapper.py b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/wrapper.py index 265bfc8..d8e6fc6 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/wrapper.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/cachecontrol/wrapper.py @@ -13,7 +13,7 @@ def CacheControl( cacheable_methods=None, ): - cache = cache or DictCache() + cache = DictCache() if cache is None else cache adapter_class = adapter_class or CacheControlAdapter adapter = adapter_class( cache, diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__init__.py index 8ccb14e..5d52a62 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__init__.py @@ -1,3 +1,3 @@ -from .core import where +from .core import contents, where -__version__ = "2019.06.16" +__version__ = "2020.06.20" diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__main__.py b/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__main__.py index ae2aff5..0037634 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__main__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__main__.py @@ -1,2 +1,12 @@ -from pip._vendor.certifi import where -print(where()) +import argparse + +from pip._vendor.certifi import contents, where + +parser = argparse.ArgumentParser() +parser.add_argument("-c", "--contents", action="store_true") +args = parser.parse_args() + +if args.contents: + print(contents()) +else: + print(where()) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-38.pyc index 7b8bf127e20ba272d794289ce51c258bd5002959..90625c8a0b1a922742e70b7c6506dd541969ddd9 100644 GIT binary patch delta 207 zcmcb~IFX4rl$V!_0SGkz?TWXX$SYef0pz4Gq%h_%<T6Gv<}yVwF*2kuMKPx^2Qz50 zykrEaWxB<YoS#>cnpaYMi?uu>wJ5cU%gDgUK+nKT&&a?}ljRmma(+>25fe~x5i^ju z#T_4CmReMtnV%OQzmlPd4I}{~ekJK=<maa97gd&)W@YLZ7a1q(rzGZOrse<*C`m2W vtEjBfFH6lU)6dCF(l4ki$;i($*0azr&MZmQEl5nxPE1cNp18!ANq`9e&Wk(p delta 155 zcmbQpbd!-cl$V!_0SKO#ZHP0O$SYef0_3DHq%h_%<T6GvGBTtvMKPr?2Qz50ykrDQ zX)@koEzd|TO0D8DGBC8%GceOLH1pGBzQvN9UzA$J1XOa1J3hWFwWv5VKQBIhB|{M_ sPz+4`vehriEzmE>EYQu&D=taQ$<Z~+Fe$At&QAmhg7L(MdQ3b_0Bn0HkN^Mx diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-38.pyc index f630e9ed435ec8efed59df978c8660cb666db3d8..1ad86ff9adbe239444b2899bf221ff1606b43a92 100644 GIT binary patch literal 450 zcmYjLu};G<5Vf5q4N+Sm@f8^o4=fA_!ODP;5EAMVrSZ|aBu;d83hCOJe<&lrz^8a+ z;ujbIr&NfO{O<1Ae(&9m#}RQAf4ybjuD|!o|MJ~(?vB25Ac&wPnf9HPv|>|Mc~g%P zAltzUnfl-_1L28*@I~<4^Zs_|_z=P+!%H{-wjmoziHh9p{mz2kka+mv)X7!MY*^IF zfHK<pj|)Ipv!qx@N%BWW+SCY{!4_g_gS;@ZR&iv*9Oq4r8thRcn>1U25;dj;ppo|y znbSwlft_67ysezYb^jV|u=|B}lnaqLk=>n*c5J_EJJ_M$pj76S;G~!8;d90pbp;%| zwp~iDvEU+C63U`R13G=`*4)Kd@lwus)0suBj?)varGcc$i-&v;n!B)kAC~XK@+_-z gsj@6>Ivbu=wP;H?qs~$Hwjn!YAw8ra3+Rab03{EDm;e9( literal 220 zcmWIL<>g`kg6Cx$;!J_`V-N=!FabFZKwK;ZBvKes7;_kM8KW2(8B&>28JiiJfvgm! zU<OU*mq2+2O~zZS<r%3(seYQww}cBa3-sd4Qu9*si}aFHi%K%nGK)aw-C`{$%FHWS z$xy@!<bjD_w)!Qx1^Pf8x|w;!C5bsXx<(l$r4`2ci6B8Rh8m?0HA+7|J~uHlFFszc Ypz;=nO>TZlX-=vgBhbWRkR?2f09vOvvj6}9 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-38.pyc index aea1b4e8ba4a1716300eaf28279fdc796eb37928..0815dc090f9a78113cb2951c8935ac6e7e0e76fd 100644 GIT binary patch literal 1170 zcmZuv&2AJ&5bo}o*`1wTI|Ps=q9__g2x$)4K|)B8h!DuK1Q#nICN_JZHB7g?ZO=}R zs(T5x3>W)q@d~y$`4xDSzH;Ife27v#vj!)kR#p2||4e`NRXtx?N(fr^&qqES5c0_< zS1rcm5xNl=1ep*)1*_<U9^6J0RBRSZ!dWzlC=smaq4z~7qGK|NH%WabByzBqz+aU3 zpBRb0h>z(c5`*r{3sSQ!A`&sg8;M|ll5FWfCZz<cw$-@VPu_j8B-xlMlg_l5S26`@ z=TMu}PGzcUV~eUPtkQK_>9PZQJ1q<UrEw!?sfJWpla{)+vbJWNe8z&vdd6JX6n5$c zAPd2*d}B+$an%A$R?*GR7%Zx=7sF4MdL@on!E9jJX?RACXo0&}L9l*sqfyP6zm~Po zFkV!1k$k0-MQ+4bAFr-G+u*-H-gx5T9cg(>WO%v0y0PT~W5EqLN6Hd7KPTYZ)rO0g z`Bcwj4*T=@uF4IRxhQHSt5SoNX8dOVAV&hP^GdzSn|(Xg^}X@0xlvaB(iG)hu_H~6 zH1h?`d_gnE`x2FR(ce=E@_S#np8^uc!-S3)j1ar1Fr`wZm*&z!1fE?h)m;RZSbBs5 zbI1fc3Er=~4Gx1-c1AV{BlpQ4<Qe&Za`}H8flfF_;hefy)}<Dz-pK+N>PFVxo1t$} z7P>y~X23<QVsH)La-k?}@l_od;v#r@IlA%O2)$0*mC`4dMiKbkmh}$^EZL=}*wi!n zw!`5e)^O%WldXe4ip^u%07K~dLP1^3q>DM<R+Z%3g}YkS8Fh5~|8%@^_t6)0M(jUK zaDznXEt6#gIBGazA`sz8fUigEuD|F}O9Phh419+n>*~7lTstLR0vBIS`~%F4=S(R4 zh!HRO4`f5slM7vP4l9_u8*0|z1mV<-K^i@WQg*dM54T$Zq3@CB+BIhQw7s$hprQTt hx0(Fbwe4Ym7tKu!VJ~KkUSlB*+341Cl=PN+{{nHu4Cep< delta 250 zcmbQlxsll`l$V!_0SKO#ZHT)Cq#uJg$bbpRaRB0C2_TWe5XF$fn8K997{!>voWjz= z5XF?j6wIK>S`|8RS}=zm*Gr%(2EWN)nXDzMxRMi-Q;SOU3Q}`5S#L4r7vEwjNG!>i z?7%FiwvwTU1E}(srG80nfqp?|fo^7AaY<rMj;>LLNoj>~ej-S4@_$C<AReH)Viu6O zj66(5AlGU#-(ruCPsvY?k1qnb4=e~a4~gIeO5EbG$<0qG%}KRm2J*m$u&{A30{{TS BHg^C3 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/certifi/cacert.pem b/venv/lib/python3.8/site-packages/pip/_vendor/certifi/cacert.pem index 9ca290f..0fd855f 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/certifi/cacert.pem +++ b/venv/lib/python3.8/site-packages/pip/_vendor/certifi/cacert.pem @@ -58,38 +58,6 @@ AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== -----END CERTIFICATE----- -# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Label: "Verisign Class 3 Public Primary Certification Authority - G3" -# Serial: 206684696279472310254277870180966723415 -# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09 -# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6 -# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44 ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl -cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu -LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT -aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD -VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ -bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu -IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b -N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t -KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu -kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm -CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ -Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu -imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te -2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe -DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC -/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p -F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt -TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== ------END CERTIFICATE----- - # Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Label: "Entrust.net Premium 2048 Secure Server CA" @@ -152,39 +120,6 @@ ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- -# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network -# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network -# Label: "AddTrust External Root" -# Serial: 1 -# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f -# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68 -# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2 ------BEGIN CERTIFICATE----- -MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU -MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs -IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 -MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux -FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h -bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v -dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt -H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 -uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX -mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX -a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN -E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 -WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD -VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 -Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU -cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx -IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN -AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH -YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 -6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC -Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX -c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a -mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= ------END CERTIFICATE----- - # Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. # Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. # Label: "Entrust Root Certification Authority" @@ -771,36 +706,6 @@ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep +OkuE6N36B9K -----END CERTIFICATE----- -# Issuer: CN=Class 2 Primary CA O=Certplus -# Subject: CN=Class 2 Primary CA O=Certplus -# Label: "Certplus Class 2 Primary CA" -# Serial: 177770208045934040241468760488327595043 -# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b -# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb -# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb ------BEGIN CERTIFICATE----- -MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw -PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz -cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 -MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz -IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ -ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR -VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL -kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd -EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas -H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 -HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud -DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 -QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu -Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ -AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 -yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR -FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA -ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB -kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 -l7+ijrRU ------END CERTIFICATE----- - # Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co. # Subject: CN=DST Root CA X3 O=Digital Signature Trust Co. # Label: "DST Root CA X3" @@ -1219,36 +1124,6 @@ t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== -----END CERTIFICATE----- -# Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center -# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center -# Label: "Deutsche Telekom Root CA 2" -# Serial: 38 -# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08 -# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf -# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3 ------BEGIN CERTIFICATE----- -MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc -MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj -IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB -IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE -RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl -U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 -IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU -ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC -QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr -rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S -NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc -QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH -txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP -BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC -AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp -tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa -IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl -6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ -xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU -Cm26OWMohpLzGITY+9HPBVZkVw== ------END CERTIFICATE----- - # Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc # Subject: CN=Cybertrust Global Root O=Cybertrust, Inc # Label: "Cybertrust Global Root" @@ -1559,47 +1434,6 @@ uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- -# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden -# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden -# Label: "Staat der Nederlanden Root CA - G2" -# Serial: 10000012 -# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a -# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16 -# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f ------BEGIN CERTIFICATE----- -MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO -TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX -DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl -ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv -b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291 -qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp -uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU -Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE -pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp -5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M -UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN -GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy -5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv -6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK -eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6 -B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/ -BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov -L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG -SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS -CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen -5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897 -IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK -gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL -+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL -vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm -bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk -N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC -Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z -ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== ------END CERTIFICATE----- - # Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post # Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post # Label: "Hongkong Post Root CA 1" @@ -2200,6 +2034,45 @@ t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 -----END CERTIFICATE----- +# Issuer: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes +# Subject: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes +# Label: "EC-ACC" +# Serial: -23701579247955709139626555126524820479 +# MD5 Fingerprint: eb:f5:9d:29:0d:61:f9:42:1f:7c:c2:ba:6d:e3:15:09 +# SHA1 Fingerprint: 28:90:3a:63:5b:52:80:fa:e6:77:4c:0b:6d:a7:d6:ba:a6:4a:f2:e8 +# SHA256 Fingerprint: 88:49:7f:01:60:2f:31:54:24:6a:e2:8c:4d:5a:ef:10:f1:d8:7e:bb:76:62:6f:4a:e0:b7:f9:5b:a7:96:87:99 +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB +8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy +dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 +YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 +dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh +IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD +LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG +EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g +KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD +ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu +bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg +ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R +85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm +4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV +HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd +QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t +lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB +o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 +opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo +dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW +ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN +AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y +/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k +SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy +Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS +Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl +nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= +-----END CERTIFICATE----- + # Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority # Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority # Label: "Hellenic Academic and Research Institutions RootCA 2011" @@ -3809,47 +3682,6 @@ CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW 1KyLa2tJElMzrdfkviT8tQp21KW8EA== -----END CERTIFICATE----- -# Issuer: CN=LuxTrust Global Root 2 O=LuxTrust S.A. -# Subject: CN=LuxTrust Global Root 2 O=LuxTrust S.A. -# Label: "LuxTrust Global Root 2" -# Serial: 59914338225734147123941058376788110305822489521 -# MD5 Fingerprint: b2:e1:09:00:61:af:f7:f1:91:6f:c4:ad:8d:5e:3b:7c -# SHA1 Fingerprint: 1e:0e:56:19:0a:d1:8b:25:98:b2:04:44:ff:66:8a:04:17:99:5f:3f -# SHA256 Fingerprint: 54:45:5f:71:29:c2:0b:14:47:c4:18:f9:97:16:8f:24:c5:8f:c5:02:3b:f5:da:5b:e2:eb:6e:1d:d8:90:2e:d5 ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - # Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM # Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM # Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" @@ -4616,3 +4448,173 @@ L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG mpv0 -----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G4" +# Serial: 289383649854506086828220374796556676440 +# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88 +# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01 +# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88 +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw +gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL +Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg +MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw +BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 +MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 +c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ +bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg +Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ +2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E +T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j +5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM +C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T +DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX +wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A +2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm +nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 +dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl +N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj +c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS +5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS +Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr +hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ +B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI +AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw +H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ +b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk +2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol +IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk +5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY +n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft ECC Root Certificate Authority 2017" +# Serial: 136839042543790627607696632466672567020 +# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 +# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 +# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 +-----BEGIN CERTIFICATE----- +MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD +VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw +MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV +UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy +b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR +ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb +hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 +FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV +L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB +iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= +-----END CERTIFICATE----- + +# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation +# Label: "Microsoft RSA Root Certificate Authority 2017" +# Serial: 40975477897264996090493496164228220339 +# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 +# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 +# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 +-----BEGIN CERTIFICATE----- +MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl +MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw +NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 +IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG +EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N +aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ +Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 +ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 +HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm +gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ +jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc +aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG +YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 +W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K +UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH ++FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q +W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC +LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC +gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 +tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh +SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 +TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 +pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR +xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp +GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 +dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN +AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB +RA+GsCyRxj3qrg+E +-----END CERTIFICATE----- + +# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. +# Label: "e-Szigno Root CA 2017" +# Serial: 411379200276854331539784714 +# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 +# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 +# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 +-----BEGIN CERTIFICATE----- +MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV +BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk +LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv +b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ +BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg +THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v +IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv +xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H +Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB +eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo +jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ ++efcMQ== +-----END CERTIFICATE----- + +# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 +# Label: "certSIGN Root CA G2" +# Serial: 313609486401300475190 +# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 +# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 +# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 +-----BEGIN CERTIFICATE----- +MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV +BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g +Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ +BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ +R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF +dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw +vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ +uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp +n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs +cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW +xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P +rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF +DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx +DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy +LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C +eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ +d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq +kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC +b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl +qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 +OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c +NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk +ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO +pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj +03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk +PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE +1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX +QRBdJ3NghVdJIgc= +-----END CERTIFICATE----- diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/certifi/core.py b/venv/lib/python3.8/site-packages/pip/_vendor/certifi/core.py index 7271acf..8987449 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/certifi/core.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/certifi/core.py @@ -4,12 +4,57 @@ certifi.py ~~~~~~~~~~ -This module returns the installation location of cacert.pem. +This module returns the installation location of cacert.pem or its contents. """ import os +try: + from importlib.resources import path as get_path, read_text -def where(): - f = os.path.dirname(__file__) + _CACERT_CTX = None + _CACERT_PATH = None - return os.path.join(f, 'cacert.pem') + def where(): + # This is slightly terrible, but we want to delay extracting the file + # in cases where we're inside of a zipimport situation until someone + # actually calls where(), but we don't want to re-extract the file + # on every call of where(), so we'll do it once then store it in a + # global variable. + global _CACERT_CTX + global _CACERT_PATH + if _CACERT_PATH is None: + # This is slightly janky, the importlib.resources API wants you to + # manage the cleanup of this file, so it doesn't actually return a + # path, it returns a context manager that will give you the path + # when you enter it and will do any cleanup when you leave it. In + # the common case of not needing a temporary file, it will just + # return the file system location and the __exit__() is a no-op. + # + # We also have to hold onto the actual context manager, because + # it will do the cleanup whenever it gets garbage collected, so + # we will also store that at the global level as well. + _CACERT_CTX = get_path("pip._vendor.certifi", "cacert.pem") + _CACERT_PATH = str(_CACERT_CTX.__enter__()) + + return _CACERT_PATH + + +except ImportError: + # This fallback will work for Python versions prior to 3.7 that lack the + # importlib.resources module but relies on the existing `where` function + # so won't address issues with environments like PyOxidizer that don't set + # __file__ on modules. + def read_text(_module, _path, encoding="ascii"): + with open(where(), "r", encoding=encoding) as data: + return data.read() + + # If we don't have importlib.resources, then we will just do the old logic + # of assuming we're on the filesystem and munge the path directly. + def where(): + f = os.path.dirname(__file__) + + return os.path.join(f, "cacert.pem") + + +def contents(): + return read_text("certifi", "cacert.pem", encoding="ascii") diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-38.pyc index 01375eee9a1b63d5e6247452240dbbf677394f55..ea262e3e7f288a80cff864cb2b771bd432a1512b 100644 GIT binary patch delta 93 zcmZ3*cAkwVl$V!_0SGkz?TX*X<HqEiq@R(Wo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu vTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?1M)fN2*1m*gO= delta 56 zcmX@lwu+4>l$V!_0SKO#ZHU{*<HjUst6!2^pkI(#pqrUjT#}fRqid95Qd(i0p9m71 IJe6q|0Mfk@IRF3v diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-38.pyc index fc301050cf55858ba1e085668f8fa4bb405174a4..3c66a226855ba1799d0234c802ba9db9f0a7e926 100644 GIT binary patch delta 95 zcmZp^!nooJBTpzVFBbz4X#U$3zmaEArgM^hMt*Lpeo<v<X;!9waZ$2<N@8ASYEE)~ xQAujCUPWb<epzZ>nSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B&J@#Hg^<^W8XBLDyZ delta 58 zcmZ2+g|YbxBTpzVFBbz4JTKc2w~=R2rkt&QNp69DL1uw&W?pegVor{(QHDurg>il& KNO1DUOmhG_*A$EZ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-38.pyc index fa4ccca9fad3e1dad96b5b6479f334db1dfcc2c1..e71ec28b21d4eb344bd327af96be0a332f45b43d 100644 GIT binary patch delta 94 zcmX@c@tT7tl$V!_0SGkz?TX*XbDz;UML#1yH&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*i<CzCA`0Qr6(!2kdN delta 57 zcmaFOag2i}l$V!_0SKO#ZHU{*bDvSpUcV%_K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj JS&zw<2>=HK5={UA diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-38.pyc index ded55b9093011b7b823adab8eb2c72cb29b7d892..8c15c305ed583d1449bf05f7dbcff71553a0480c 100644 GIT binary patch delta 94 zcmZ2taMFM$l$V!_0SGkz?TX*X^PSl_OFtt&H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*kVA`7z!00!wG-v9sr delta 57 zcmX?Uu*85Tl$V!_0SKO#ZHU{*^PO4FRlg*+K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J*^Px+1ON^M5^Dee diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-38.pyc index e71d10b848b37b3f6d615074b379e21d3ebcaa79..c89ffac10df9b735603bb56c51e1b30bb3a86118 100644 GIT binary patch delta 94 zcmZ21ctVgTl$V!_0SGkz?TX*Xvy;&|M?WJ!H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lAW5xq)0OA!P&j0`b delta 57 zcmX>hxLA-Ul$V!_0SKO#ZHU{*vy)NIUB4u^K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj JnS<#78vyrd5?lZP diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-38.pyc index 9efd0514f40702468ac84ef4deb9f8bc63f0cad9..f204cbc08da403ef5f05802b5ebc7343aa8f07c7 100644 GIT binary patch delta 94 zcmew?HA9*wl$V!_0SGkz?TX*Xvy{;}T|Xl~H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lAdB!E&0PR5`z5oCK delta 57 zcmbOs{aK19l$V!_0SKO#ZHU{*vy@TJNxvkwK))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J`3vI`ZU6z{6G{L8 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-38.pyc index a427742fe3d5becb9141c256176b554521e9adfc..d7a44b5035214ce660396f034744fca7b3033e99 100644 GIT binary patch delta 94 zcmdlcc3X@ml$V!_0SGkz?TX*X<H6>fqo0wVo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5)Qi0udq0Ma8NDF6Tf delta 57 zcmcaDwoQyDl$V!_0SKO#ZHU{*<H089u3wT{pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JJe}<b3jp*W614yT diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-38.pyc index fd577770ca6a514381b0be41bbf3d0c6183020df..53e4c4f0933874790c71ac5914ac8a24aadfaa8a 100644 GIT binary patch delta 91 zcmdnZ^ni&cl$V!_0SGkz?TVksbIv(IKO;XkRllgRv@|PIzqlw_KP53QGc_kUzo;a& tSg)e8O1~^MuS`EDGfBUovLquv&sfhwzc{lbRkt89IXf{uwRqwWX8@Q)Avgd4 delta 55 zcmaFBw3~@1l$V!_0SKO#ZHSx5b571$za+OnzaX<fH#4ueBrzvP*C@lJw8A()5hOTS HmeCmi-n$XU diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-38.pyc index c3c7656f7fd4130cc451d24cef4b577a8940dc42..385500e09077b4a16cab12ad270f21472e89e8a7 100644 GIT binary patch delta 94 zcmX@h@ri>cl$V!_0SGkz?TX*X^N7(oRX-y?H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*i<50fJk0RPb-+5i9m delta 57 zcmeywah8K8l$V!_0SKO#ZHU{*^N3N-LBAxoK))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J*^tSR2>=Sc5@rAZ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-38.pyc index ade15ee856f0cf8f5e479daa1ff74a484dfc482f..829c2134a0c1fdbad617c7c6431063d2da16e613 100644 GIT binary patch delta 94 zcmdlWa#e&Ul$V!_0SGkz?TX*X!_DLzub+{ho2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5)wl<7A+0JRw)!~g&Q delta 57 zcmcaAvO$C=l$V!_0SKO#ZHU{*!_6dTrC*X;pkI(#pqrUjT#}fRqid95Qd(i0p9m7% J9L4mT9RTF45>NmD diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-38.pyc index 5b58c0a8fa7f3e65cc1d79d3bcd214ccfacbf074..494c97e4db945607fa0408b609c9b397eeb38c12 100644 GIT binary patch delta 94 zcmZ1|a!iCLl$V!_0SGkz?TX*XBf#REte=seo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5)wisd;g0Ig0Sq5uE@ delta 57 zcmX>mvQUI4l$V!_0SKO#ZHU{*BfuhOr(cp=pkI(#pqrUjT#}fRqid95Qd(i0p9m7% J9MAHc6#(C$5-tD$ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-38.pyc index 5b5748c8df6783ff84662f33139cb03a2ec98c1e..0eee0c3dce9ae98538456d2d50bda72a06fc4d71 100644 GIT binary patch delta 94 zcmeCOT5rV@%FD~e00f%<cExYxSs>*cub+{ho2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5*5l#~M#0O*AwUH||9 delta 57 zcmZ2))n&yK%FD~e00hs=HpFe@Ss*26rC*X;pkI(#pqrUjT#}fRqid95Qd(i0p9m7% J{9ej|2>|~W66yc| diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-38.pyc index 8a89ff8522ff9641ef40450636aff078828ba050..30a3c33c335c7dc228491e85c2042e119bf9dffe 100644 GIT binary patch delta 94 zcmaDYG(ngrl$V!_0SGkz?TX*Xlh5Rws-Kaco2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5(lCetN00MQ#ETL1t6 delta 57 zcmbOr{91@7l$V!_0SKO#ZHU{*lg}jQpkI<(pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JypQP;8vyb@66XK_ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-38.pyc index a3f150952b6fe8e3d4a6f7428138bb0e134070b5..4380bae0979d3812b28645a22e8a956d3ad47894 100644 GIT binary patch delta 93 zcmew!J134Ol$V!_0SGkz?TX*XGgZ$ySwAB`H&wr=va~cSQ@^+<SwAH)FEceKIlrhR vwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*l9emx5S1ZyGd delta 56 zcmbOe_dS*;l$V!_0SKO#ZHU{*GgVK{PQN6#K))cfKsPh5xFj(rN7pFBq_n~~KM^E2 I`H7wd01r(QcK`qY diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-38.pyc index 81ee6d8e9cf13cb67867d7ed6bff569ad394367c..c495c53f1da5f5626fb7b47b56b0d317f5299343 100644 GIT binary patch delta 94 zcmX@d@tK1sl$V!_0SGkz?TX*X^N7(oRX-y?H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*i<50euU005jI-2eap delta 57 zcmey&agKv0l$V!_0SKO#ZHU{*^N3N-LBAxoK))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J*^tSJ2>=T(5@`Sc diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-38.pyc index 10d48d055a382295300cb3385a9bf3ba26bf1810..ff38a78cf64f06b311354c8884da69e21ee7fb2a 100644 GIT binary patch delta 95 zcmZp_!no!NBTpzVFBbz4X#U$3zmaEYrgO4>Mt*Lpeo<v<X;!9waZ$2<N@8ASYEE)~ xQAujCUPWb<epzZ>nSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B&J@#OQF764GQBM<-p delta 58 zcmZ2;g|Yn#BTpzVFBbz4JTKc2w~=RQrktIANp69DL1uw&W?pegVor{(QHDurg>il& KNO1C(ObY-#HWZuy diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-38.pyc index bf876747c70343cabd33aa3c77f302864c44dd31..6a21f6c3667e0c2264ec902d1022fb90fbc1e3b8 100644 GIT binary patch delta 94 zcmX@d@tK1sl$V!_0SGkz?TX*X^N7(oRX-y?H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*i<50euU005jI-2eap delta 57 zcmey&agKv0l$V!_0SKO#ZHU{*^N3N-LBAxoK))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J*^tSJ2>=T(5@`Sc diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-38.pyc index f742a8c06c0ddf97b87aeb2f8179c86ff943716a..2d1e270a2988273a92f048a85518624b79ed3c34 100644 GIT binary patch delta 95 zcmex8g>k`DMxIb!UM>b8(EPV6ej|^Bmvf4KMt*Lpeo<v<X;!9waZ$2<N@8ASYEE)~ xQAujCUPWb<epzZ>nSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B&J@nk12O8^#BA)^2Q delta 58 zcmZ25mGSo!MxIb!UM>b8cwV+4ZX=I`mz=$RNp69DL1uw&W?pegVor{(QHDurg>il& KNN{qxmn8rlWD_p{ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-38.pyc index f9187e6182857304d756697306e72ec27f839cd5..a4fe00dffa68755960fa016242b0ba39d8bd72c1 100644 GIT binary patch delta 94 zcmcb{@tcDul$V!_0SGkz?TX*X^OVs!O+O<)H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*i<Ka)EX00*le`2YX_ delta 57 zcmey(agBo~l$V!_0SKO#ZHU{*^ORA}QNJX&K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J*@VfR2>=gT5`_Q& diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-38.pyc index 69b57d7cc0ae8ee07a9e4f378a4296ae1420f6c1..7fd5f8da8e691e8605471a979442654bc6c7610d 100644 GIT binary patch delta 94 zcmZ23eny-pl$V!_0SGkz?TX*XGoQ&hO+O<)H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lANv3-o0N^4a%K!iX delta 57 zcmX>jzFeFql$V!_0SKO#ZHU{*GoMM$QNJX&K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J`5n_e4gmWK6ITEL diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-38.pyc index bfb51211eb73ba2335c48a4c54ad2a02d2919789..65edc6bc95fd187384f8e57cc472999d4aae2501 100644 GIT binary patch delta 95 zcmX@VhVjc9MxIb!UM>b8(EPV6ek0HOQ0GMbjQreG{i4d!(yUDV;-X~zl*GKu)STq} xqLS2Ny^6{z{j$`&GX0#)B>jTQl8pR3V?7J~;>?m%-GapA?8Nlc;>nU>W&m|NBDnwn delta 58 zcmeyehVlFwMxIb!UM>b8cwV+4ZX?h8P&pg@lH3CQg3JQl%)H`~#GD*mqYRVM3gi4l Kkl<vyFf#y9`V>U~ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-38.pyc index 5733daeba61a1030fc6ec46422c311942cb76c33..bc529b083513971fe9a020e895cb46190f246abb 100644 GIT binary patch delta 96 zcmX@Gl<DbGCZ14UUM>b8(EPV6ej|@-yK{nmMt*Lpeo<v<X;!9waZ$2<N@8ASYEE)~ yQAujCUPWb<epzZ>nSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B&J@#g&YKyCnMry}D3 delta 59 zcmaF5l<B}yCZ14UUM>b8cwV+4ZX=ItyPUOtNp69DL1uw&W?pegVor{(QHDurg>il& LNO1F%_CRg`Oo0?{ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-38.pyc index ffe4bfb63d3cda6b38001387696d14f44c9696e7..0837bad864d41ba60d5cbd43e2f55d5678621dc7 100644 GIT binary patch delta 95 zcmZ3ngYoPRMxIb!UM>b8(EPV6ek0HPXy+XLjQreG{i4d!(yUDV;-X~zl*GKu)STq} xqLS2Ny^6{z{j$`&GX0#)B>jTQl8pR3V?7J~;>?m%-GapA?8Nlc;>jnY;{j1nBO(9* delta 58 zcmX@RgK@<UMxIb!UM>b8cwV+4ZX?h9XgPQNlH3CQg3JQl%)H`~#GD*mqYRVM3gi4l Kkl^HZ(eVI1_!O=H diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-38.pyc index 12796e953d2266b3e2834d37b7772a1f169a41b3..1f6ddbfef43e703895194aaadfb4e0dfbe71b8fb 100644 GIT binary patch delta 95 zcmZp8%((P1BTpzVFBbz4X#U$3zmaE0fpfNgMt*Lpeo<v<X;!9waZ$2<N@8ASYEE)~ xQAujCUPWb<epzZ>nSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B&J@#IGZ^8jGaBf<ax delta 58 zcmZ4bn6cq8BTpzVFBbz4JTKc2w~=Q@ft;IuNp69DL1uw&W?pegVor{(QHDurg>il& KNN_TH;XD9C8Wc|e diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-38.pyc index fd7eb0fe63f8fd03964cf81217151e172d0da99c..effb46dba7763e3b843c8e23c525ec721cee7f74 100644 GIT binary patch delta 95 zcmeyjopJFFMxIb!UM>b8(EPV6ej`t1v~z}jMt*Lpeo<v<X;!9waZ$2<N@8ASYEE)~ xQAujCUPWb<epzZ>nSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B&J@#MwP(EwF8BKZIS delta 58 zcmZ3ygYn;XMxIb!UM>b8cwV+4ZX-`+w4AekNp69DL1uw&W?pegVor{(QHDurg>il& KNO1Cr=x6{yJQRfh diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-38.pyc index 65037fafa735b8c0d024828349ab0a6a8797998e..9f774340eaa2af302231a3cd11771d3f23c2cb0d 100644 GIT binary patch delta 95 zcmZ3umhsqHMxIb!UM>b8(EPV6ej|@|m~*CnMt*Lpeo<v<X;!9waZ$2<N@8ASYEE)~ xQAujCUPWb<epzZ>nSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B&J@#N4j9{?WxA@%?O delta 58 zcmX@MmT}=)MxIb!UM>b8cwV+4ZX=I&n4F7#Np69DL1uw&W?pegVor{(QHDurg>il& KNN{phm=6FV#S?-6 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-38.pyc index ce11a8ae18027689290bdfefe7a5009b4a4651f4..4864d4b54c411c6f3cfaacec7e1976eff3bf5c42 100644 GIT binary patch delta 95 zcmbQcgYnP~MxIb!UM>b8(EPV6ek0G6Xy+XLjQreG{i4d!(yUDV;-X~zl*GKu)STq} xqLS2Ny^6{z{j$`&GX0#)B>jTQl8pR3V?7J~;>?m%-GapA?8Nlc;>r7>;{iqZBK80P delta 58 zcmX@KgK_Q-MxIb!UM>b8cwV+4ZX?f>XgPQNlH3CQg3JQl%)H`~#GD*mqYRVM3gi4l Kkl^IU(eVH`WfXz{ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-38.pyc index 3cf85fd820ee52e4475cb963b7132983cb041e50..1ab86d31201d09f098576ed528aa3ce66822e53d 100644 GIT binary patch delta 95 zcmeBK%eZkZBTpzVFBbz4X#U$3zmZ2G%sE{@BR@A)zo@dbG%HiTxF}gaB{45EH77a0 xs3f&mucER_zbrMcOg|?xNxz`7BqKl1SkFSgII|>Gw;(Y&J25@Ac(PNN7XS%gA)){P delta 58 zcmdnEma%6oBTpzVFBbz4JTKc2w~<F8OwLKaB)34nAhSR>Gq1QLF(*gYD8r<*!Z<$> KBse)e%nJY(LK7|k diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-38.pyc index 1ff1acb560bf041b722530f6ac160ed89e41dbb6..3f41239c5c2dd84cb7553684edf0d8ca804d9f6d 100644 GIT binary patch delta 95 zcmZ3ymhr?|MxIb!UM>b8(EPV6ej|@gm~)nXMt*Lpeo<v<X;!9waZ$2<N@8ASYEE)~ xQAujCUPWb<epzZ>nSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B&J@#L^DUjQKpA^rdW delta 58 zcmX@HmT~b~MxIb!UM>b8cwV+4ZX=IQn4GJANp69DL1uw&W?pegVor{(QHDurg>il& KNN{p>m@fb$@)L>x diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-38.pyc index f61d25e3d3a10526731d9761325565cc24f4e354..5041a34b4731a21a362bbeef40d77ea06af1b0c6 100644 GIT binary patch delta 94 zcmZ21bwY|Kl$V!_0SGkz?TX*Xqs{7^rk|0Yo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5&)l=U1t0K8lv)&Kwi delta 57 zcmX>hwOEQLl$V!_0SKO#ZHU{*qs=Pks9%y>pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JT*Z2h9RTO!5@G-V diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-38.pyc index b2031b9a929358e827236bceaf462644b3799f62..70f4ad21810a0aff1da8f884476e0ff74981d2a8 100644 GIT binary patch delta 94 zcmdlacwLYul$V!_0SGkz?TX*X^Ow;%Q$Hg=H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*kVI#V|r0Q|TiJ^%m! delta 57 zcmcaExJi&Fl$V!_0SKO#ZHU{*^OsT1MZYAsK))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J*@vl{4FCvT63PGo diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-38.pyc index e2d88b8f4cd3ae6a57f2d20ea088c3e94c1b5659..6f38ffada6cdd8d526c0be94a37decc5781dae2a 100644 GIT binary patch delta 94 zcmX@i@q&XVl$V!_0SGkz?TX*Xlg8wnsh^Rbo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5(l0@G$j0N9oxL;wH) delta 57 zcmaFCahQWAl$V!_0SKO#ZHU{*lg1?HqF<6*pkI(#pqrUjT#}fRqid95Qd(i0p9m7% Jyp?G)BLMe`63_qu diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-38.pyc index 5810f530d7bf07ef605fc4b55e1bb5beab4b8ff8..bc7010072fef513b988879ae1ec7b78b6d96ad9c 100644 GIT binary patch delta 96 zcmX@r#Q466ktdXwmx}=iH2>|2-^erH+Brc#BR@A)zo@dbG%HiTxF}gaB{45EH77a0 ys3f&mucER_zbrMcOg|?xNxz`7BqKl1SkFSgII|>Gw;(Y&J25@Ac=Ji?Mpgh?10wYR delta 59 zcmaFg#CWQSktdXwmx}=io|kQi+sHHDTFzR(B)34nAhSR>Gq1QLF(*gYD8r<*!Z<$> LB)IvVbt5YPL|YVr diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-38.pyc index ff84b92b88c8fdbcf82c52a73c7157db130a5604..3b691456f6edc1b2221e78c4f199dc6fde1066c4 100644 GIT binary patch delta 94 zcmZ21enOlll$V!_0SGkz?TX*X)5zqUsh^Rbo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5(lHPa6c0M!H`qyPW_ delta 57 zcmX>hzF3?ml$V!_0SKO#ZHU{*)5s*}qF<6*pkI(#pqrUjT#}fRqid95Qd(i0p9m7% Je1Yi)2LSZ@6EFY( diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-38.pyc index e7ed4676a2bc5a6eea8c69f291ac0b358d189637..cadf341fda18dc1227543188606c252826f6b76f 100644 GIT binary patch delta 94 zcmdnWbBl*3l$V!_0SGkz?TX*X^Nra#Q$Hg=H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*kV0*fdU0Qk=!wg3PC delta 57 zcmcb`vz3P@l$V!_0SKO#ZHU{*^Nm@~MZYAsK))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J*_B0<2>=Db5<&m~ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-38.pyc index 089fcfb1226647deb93fb9a6fd617dde71c57746..d8cf0c8c18f364f0aad9d985f079f678b1645829 100644 GIT binary patch delta 94 zcmeAd-XhEs%FD~e00f%<cExYx$!2m+(a*@wP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7a&mFX870K04<LjV8( delta 57 zcmdlY+%L=%%FD~e00hs=HpFe@$!3zX*DuK}&@ad=(9O&%E=kPE(KX62DXlQhPXq~W J-o^Bb4FKjk63+kt diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-38.pyc index 89dc24d8d1115dc9fe528bae6accb6464cf8841e..181d9c3d8cd0247918758a575dd2f0951b2cfa29 100644 GIT binary patch delta 94 zcmbQQdqkHfl$V!_0SGkz?TX*XGm*_XTR$T|H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lAZnh`<0O)@q<p2Nx delta 57 zcmX@2J71S4l$V!_0SKO#ZHU{*Gm%ZsO}`|!K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J`2pJ#egFU?6LA0l diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-38.pyc index 1c2e2e910d4769c34968801f8890df370eda5669..ffb7b4ccc39ced7c747b04e211bc2b2cc24bbf24 100644 GIT binary patch delta 94 zcmZ3$f0Umml$V!_0SGkz?TX*X^NrCtML#1yH&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*kV0#gGk0P2h&_W%F@ delta 57 zcmX@gzkr`7l$V!_0SKO#ZHU{*^Nmr?UcV%_K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J*_Ek*6#)IF5`zE$ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-38.pyc index 5c5de7d39bdc298105089f4af6ceef08ffdcdf7f..b7319fd5abca5fcf2bdec8dc38e322130f232f0d 100644 GIT binary patch delta 93 zcmeBY-onfi%FD~e00f%<cExYx(Pwl{)X&JzP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS vE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc5Dt$!G=udRZU5 delta 56 zcmdnO+|SGt%FD~e00hs=HpFe@(Pxyi(J#p@&@ad=(9O&%E=kPE(KX62DXlQhPXq~0 Iu46O<0Kt0^NB{r; diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-38.pyc index 671cb8e19f38edb878684af7510c0f7534fcc162..cbb12d09573159635fde4bb057719786f3247293 100644 GIT binary patch delta 91 zcmbQkc#x4Nl$V!_0SGkz?TVksW9^)#pOK%Ns$W!DTAG!qUtE-|pOToDnVOTFUsRG> ttXEN4rC*ksSEiqnnWSG(S(1^TXRK$TUz}Nzs#}nloSm4ST0Ak;8~|A0AIty% delta 54 zcmX@eIERrZl$V!_0SKO#ZHSx5V=d>XUy@s(Uyxa#o0(T!l9-dDYm{M9T49`@2ojvw GWexzXZ4p=i diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-38.pyc index 320a7028dc57f8760b4cb3de9069688212e4cb8f..24a4adc70e31a31a4f5eca13b08feafe33738c7d 100644 GIT binary patch delta 94 zcmaDT(k99i%FD~e00f%<cExYx>1T1y(9g)vP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7cOlVt@f0M<kyX8-^I delta 57 zcmZn@eJH{c%FD~e00hs=HpFe@>1UC1)-TB|&@ad=(9O&%E=kPE(KX62DXlQhPXq~W JzQ?kH6#(>K67v86 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__init__.py index 2a3bf47..34c263c 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__init__.py @@ -3,4 +3,4 @@ from .initialise import init, deinit, reinit, colorama_text from .ansi import Fore, Back, Style, Cursor from .ansitowin32 import AnsiToWin32 -__version__ = '0.4.1' +__version__ = '0.4.3' diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-38.pyc index efa7702364d069835a56d971615c5aa0bd3b504f..cf0e06e4d9abb3e8281e13845c31766d7580cb74 100644 GIT binary patch delta 97 zcmbQjypx$Hl$V!_0SGkz?TVksbBxh=;^j=|Wc`f%+*JLd%F@!TO#R}bWc`%Hyv)>` z<ou$N)MCAg$}0V`)VwnNoXjNsg36MN{5)el3;p8El2qM-#N_P6^wi?XQH)jqOFbe) delta 60 zcmdnVJcXGjl$V!_0SKO#ZHSx5bBxh&;^j;^JN=T}0{w!_0^Q8K;*!Li99^RflhO*~ M{6vu8<a$Oc05#4N&Hw-a diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-38.pyc index 469e689323846514b21bded48f29c369cad58646..0db81f98a19743b0b15fe681c074d252b873e406 100644 GIT binary patch delta 94 zcmew=F-wvsl$V!_0SGkz?TX*Xvyjm_UOyv0H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lAX~tDt0O`~rvj6}9 delta 57 zcmbOw`Bj1^l$V!_0SKO#ZHU{*vyf5FO1~txK))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J`2*uBE&u>96F&d| diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-38.pyc index 00b902adc2373b9c1c551e5683c26b833ac27254..0f35ee1e8e002a4d005f6a80bf75b8d6660b70c1 100644 GIT binary patch delta 94 zcmbPav)zU#l$V!_0SGkz?TX*XbD7CGO+O<)H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lAUnWs$0Qv<Xod5s; delta 57 zcmdmPGs%W0l$V!_0SKO#ZHU{*bD2rbQNJX&K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj JS&3Ox8UO^_5-I=y diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-38.pyc index b631a8dc76f5778788467c63a6c9bcca171e7f43..3bef049b3336b32985df552d7d0b4f5a177f59e2 100644 GIT binary patch delta 94 zcmZqVUB=53%FD~e00f%<cExYxkzjOA)z8S!P1P@|EG^B-)Gsbd)=x>y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7c;#Awe70Fl=pxBvhE delta 57 zcmZ3++sMlk%FD~e00hs=HpFe@kzkZ_&@ag?&@ad=(9O&%E=kPE(KX62DXlQhPXq~W JPG_`d1pv-$5kvq0 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-38.pyc index 0cfea7753dd665d6f353cdb383810bdb2fe1faf1..73259043b844043b63c543e92af45ebc28d7e7cf 100644 GIT binary patch delta 94 zcmaDV*Co#r%FD~e00f%<cExYx@nUjL(9g)vP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7bD!t{{`0LaiGJpcdz delta 57 zcmeB@e=5fl%FD~e00hs=HpFe@@nVv*)-TB|&@ad=(9O&%E=kPE(KX62DXlQhPXq~W Jp2_r)2LSF$63GAn diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-38.pyc index ca849fba1d3fe7469a1d4ace48cb00f040e12e35..d9fb8abe8420d01fa3a34744ce44890fd97bd9e4 100644 GIT binary patch delta 94 zcmbQJvQ332l$V!_0SGkz?TX*X6UFG9q@R(Wo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5)Qg|Sxv0KzOF-~a#s delta 57 zcmdm{GEs#ml$V!_0SKO#ZHU{*6U8WJt6!2^pkI(#pqrUjT#}fRqid95Qd(i0p9m7% Jyppk3008P>5^Mkf diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__init__.py index a2d70d4..63d916e 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__init__.py @@ -6,7 +6,7 @@ # import logging -__version__ = '0.2.9.post0' +__version__ = '0.3.1' class DistlibException(Exception): pass diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-38.pyc index 3fde1c8a274c8e7a45179cc30ed0b7e201aa3749..a38142a2ec5c259d2a4fc2b5feb3941ef9965d1f 100644 GIT binary patch delta 104 zcmZqVSir#>%FD~e00f%<cE!6+<ekCBYM^JVXE<?Vk#mxMMt*Lpeo<v<X;!9waZ$2< zN@8ASYEE)~QAujCUPWb<epzZ>nSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B&J@n%QH G155zG10#0; delta 73 zcmZ3$(a6CY%FD~e00hs=HpF>P<ekC8ZJ=kQXQ@|^UtD4^adnZLt$s;vfqp?|fo^7A ZaY<rMj;>LLNoj>~ej-S4a{}W5CIAdT7c>9> diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-38.pyc index 3c776525ae28bb86719c2d0d03ef77930d52bf33..a4480439af4d1586daa40a869d9ab23b4a853e2a 100644 GIT binary patch delta 489 zcmZ4SoAKUnM&3|fUM>b8(EPV6{=i1wJXY3{+|sDh$qlU1!X>$7QDuw_RRSptDIPiH zxfM~Blh?7zdsjv><S|7sxHF{qr1-Wlr1++mH8V$*LPWu;{c@^utD~wJ8NwOzJXjb~ z*|NDNuoa0gGJqgdMGZ*BWC=ET$!dsBB>jOoCAqaxwUYzbWF6~r>!TXLCMm&9%7T~# zbXQPLBSapmTLLH+oYR!s9MzoL64jF18r3>^9h<sz8_<QdP&FbzHDNjJxgAj*xt&p+ zlRvP@hj%Sxit0{@NQrD=i0TCTEGi`$=(FflkiMRj^pu#C*cQg9UZ6}|N<2^|KD7@h z(+}h)q$C3QiK!ES{E0w*Qc5zApPU*9<acaNV~=5UPSDTD&rQ`Ysw^$d%G56|O4d(F z%*#y8NzN}SNiEi^sI1a2OU*0O&&f>EFQ_cZ$j>v@v(PWjEJ@WZNKDR7OiwM|{D7k- ypK;RW*or@ljJGC7RqYYrPtMQDNlh-v%+D*<OH4|htW;gady5-Mbn~2Q9wq=n6QHjE delta 434 zcmYk1yG{Z@6ozNeT_ZwbA_ayhiH#K@Q9COuNf09%1rEr?omJ79g~)>If`YIL-ZA?G zc2-0~%TxFOwzl?II9y_!slM}Ha?WQLzjm>G+itfa{=N!t@y@$l5riaDK{YFaYbwd| zkjF@$B#8KEft`Y8wgk6diy*}kMyrUdk${0nK+e}jKpjl`?sa;`bkH#hA;mX}WbxSA z6i*x&_5RRN>^V%Q=$_UG$$$AEO|lY{%nfm7<(yqWx!*MR*K{;!;(Kk<%0M5coqV=M zFIg3;tOhk^fMK@8dDj)+ur%~IxMzo6vpUpS0~+SH=nmbySm2g~NyI?V;Fkf3^2?%f zFLy@{NQ~?n81A_eCkd`3<Oi-ia!!&I=al@!xygBtNSq}($hqF$AB*AHWv|Mz-fTMS zNh>)uMX6`ua4D}XW>URjTNp28@N>JW{a_4cS?|~;qzt99q^2`U&h!`c_D9iX`30A! BiUj}w diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-38.pyc index bf5044d5dacfad654f57c2661b159f641f594a96..771e0d75475a0e0bdcbff495c0a1967880751c4c 100644 GIT binary patch delta 2670 zcmZuz4Nz276n^*Zzks2HsEMuN-&1y1QzrZ=1BAv_Hz7c<CT7`vz{0Y--S_yB7Mi3P zooNi^L}7|9IO;T6rca%TG^Nrp%P};k@m1nX|7Du}Oq0!2_uNfTi<$j6_uO;NJ@=gN z+}**G;xq4yNhL{1qXhOR{ncNg>`QW*@+w_5;d<Fc*EBTL23!jDx%}QxKo0uCRFxHH z^O_b{qa12<1p}3?$QrdK9Gd6Mb}0c>c0|0sI&ZbCXyv9c(}@msvrmx@@Ft~+bR#^H z=_i}wi%vM5S#@Ipu);CCcmYm3hRwP(xAQTJxr3$0{P$(0Ozc8&3qlV<451HUDr{Ps zqFv4kTge`H{DE}|dr&(a;UHXjAf4>i5|=ndvJw{Mw0qRVUeaocn*2hYm2Ojweo-A2 zB~{`$p`ENHYEo=;)D*j;SLh`jV_VH?a@6cM_>CLHR&kY(B@_xpLYbhBQO8Dwb}^O$ ziMbOh?u;^PB1DZbo8L4X-4+!pQq^&_mRMSp_|3gytA($|M=iZ%BcaRH2~msR(k^z~ z*=mhiV-tIY*j;`r^S6zh6t%@BL0j%jcq2E<cHPvVRynezboeGW$C-#1EJAn`p%}r2 zuoGb%0<VDsr5#Y1XE)LPOok`(7Me9w?uLDNg~suuWirey9S27i*x=}lWXM_?COz8D zrOhUCN}K%f2gG~|t<Py!-J)nehw|G9V;D$Ant}3D40MrJ(E)9YXN5?PL&eI)%zf+1 z7$Il1`-_f=<S_hIoI%dRJta~C4{#7Yk3wn5G;#o<CCka6_I^p5!Fq)0iwo!=JW`%k z*2@-BGChp8c7)Fm&Ldo4pqm1Uw^E^ns6a<L3$^BeQWXfwx<OGXy@cw`2sa=5c6nOn zSE&3N!H)1P!XSgy30|Mt;0;zNffku^J`HGO^)H4J+RwIMA-Yu#`NIA{sG43zCj$fB z7V_513L6AjO1LRup4t^OFf$j~r^M4ZihjosHiP?#8Dv0Hp6C~+=}hC1O!NTzuN&B) z>6RMV>zApbTNED+L{x=pP~^>6{W1DtI`n6>C8Pd(Y6<RML>NNgr7={?D*X+YSPk9O zMA`UCws;@EK>e3+#yg1&z_sKQ?QgG4SRZ9yjv)biz$z+7SjPLRa>;q^*Q$Q9@V3^R z#SlLt@QZ)WBz7In5?*dQZheF>h$q0GHM_`m9AOfJLxIB7k?G}g{vKMMg-NyP4`aXS z_XyVz{y<=JCs58$P6-PxV{Ah=hbwDkpBjH64x#DPVc4y;*ESl+F1TJlm+XYhki_1I z(va6U`c-D*;g*s}Prz}yKJ6G&=_babK!oCDC@*R^_?1keX`7UTWGps;O~P<d8L7(} zCX?^9riKJU`k}osj~6e_vLP63%p&{2(qvENjODBxp~G9SxT!Qgp##v}^ecHM{&M!f zu4bS4T})wpT=O2xT(hU_2d2565(p`(HyD)t4kW(fRGU>k55)zN`F1k$Q+YL!5jVQ? z6Gk2xhDzR(YubY?ZqXU1iZ2*eWXdyr4UJ!CpxbKXW`BUa{HkP#UvL24jBaD&Ue?;i zF8@iZJ^xc?=#i5CH;<93C9~$~)=-$%N4#pyzjelQJP1RuxNTwr O1K@2-Cl|D* z+gygnhsU5rbh-*WjLsvh<TT`0zV#?N9m#?%l`Nc}x|O{o;b4O*^D^j0rH=KSp93@2 zYK)(su5~ZpfroSM@#i%WgY=+|GnF%wmv)$n)P^SftLi^Ir0uCjat6DpZC|&5m}jBs zZ0+LuN-=@U*dV5GKX-;qI)m~|1l~47e5f+f<t08!%Qnd5U2X4%dBi>swIdO(GB4dm z+2~e;*c-$KSnS9&Z^u}3V1CC`GG8n2m}N*p5B8+0a=k)7gpHl4>>1eAIp<$X?X%9` zMREc@?wUqU!u77*<`Wp96`3;sBomJq1wmmS!7PY^WQ`}V0Am`10X9PXHhg|c(J>3I zyf}+2h6yiSTEcTh)40)ml(2I*zG3b|MJ9SJL}_H0r=hL~vb$GF4&0fGa4!O{0S~kY zmpKT$Q~VbLk>JDbDMZq)bblgFcoCy81EHW;N~IQDNoenYi(Br=-iYf?1VHFQ2q9Pz zx)C-bNC;0N#Iu0xt@n|aA+i-nzGm#{CsXn<=xheMArg+n8)>1rsO6W-gQ0CQaclY8 z>q$-ls@X?iBaBt0cO&o+yj&0AKIg(MAyE4=S}ucMVynmsaQB{0<+l9y0S_YMz6TtA z>1GewKhFu|>$9_;Nze9WOx}z8d|rxB!g1Fv!Ekjoe&rp8<9*x6Iq>iBOypJKDY-Gu O3WSviQ+dRp9rPcJ0^q;^ delta 2588 zcmZuzdvKK175~n+Z<d5dOac~SXaMuYJb-}G^g;6=wJ`+3WC^57y4n4bY~1Xw_xnNu zY%+z+6dWf8ILO1<hTTAMtdCZ%{86ZOeK3lSnovgV*A{DSYt?EI%XDfx)82Cz613f! z{mr@Oo^$TG=lssy-F04_d|A!%Wo6A!#OM8OKileiDy!U4@XZRdH&zh~#mYhv!}N#4 zWh=T@_6<}<{iNhWjyX%A4foyl3OtBww$Fo6G)sf9Ps;o8N@?dc`2e!A>oVe%vg<Yn zd93_<F7JclP&P`iA17Dk%zl`}1i>+a6n^ZQ$LHK0b;D!0>sx!Y$4I-B;AsI?R(pFO z>^F>n9uBv+v&FO_;Ur(ard)*v{C@RtQ&3I8pd;=GD)+kCm}w8%%o%a$RP&T!*bU~) zWLDgf%uXpO7@a%lG-t(~L3_|Kq7JI9$||K<*{Ez*%-QCgxH7CJ=i>63`CD@0!Wxvg zJ?RNLr=ok}O8ZS_ZjURO7l)uLr4G8}DnIT@!9HO1=DfHo=pI%_vj^RAcXED88T3q_ z5%(l-#z$+4XISoaYg?-8s#~gYvSyX4eFbOLR->=>rrZ;B!#o06gff!Gaj3QskJnZ? zPto!uzE|69p9?z*aPm9(xV~-=B=}o(0}eRPH#EEo&hun-fiG%Q)xrxTKSMA_fM#b! zB<~bpsjQQwaaSORZ)ΠYHlP;Tv!sn`?9UyBkITCV6yYT7|Q?%vS^#vBjr(Wguz{ zdlvWlmH@{meT^`||K%I9xql(_E%j^ycWuevoD>UfHaknUg#^DLxJdA}0Lu|F{2c~s zCIvaN64E+DMrSCjTQ<XF>>W}cA-M6_%UkkG|47O|5fl=<PcR{%&Fc@Ceg1H}5!#_M zNu@NeZ2QdC`njXe>?~XTC|GVi5{L#vkuLTTx!D9*o`}C!H)8&Pu6b`rStj=}890TD z9xyVAJWGDRBshXQx84eAethd0b;+-Vrb%-!P7bzksKat~>;9n549jH%SSV&1>=f?y z7q$J0d_N_)LbfpDe^2$%?(YaL5y;}$x^$CWr6twFa`dy1scW80NB=<j_wYad1tOmX z9Rnc9@KB)I=A{mZdg?Ke?Yo^daFH+WIs;W-YRn|L|CK;q`nN(7SCL$i#V(|+HwY$h zUg+mAM!bPz_~%e_?)1ne$lwKnNo?#{*g&0T9}rw7_$PrFDuqdgN;0@;Nl$_0jCS<s z0h6W3>NJ5IbO|Rp@7ZR9A7e>mIh??|BO09KKaBY8**_76P0~_R**Uz*_U2P-EQerF zD8}d_OcwJn9yChf6o1Y*4RfjZViu-~Np$WjfWPoZ`n&+2BHvak3zy;7C4~M}@D$$B zUzjVoD)~4~gEJWJ-;|lnG``&bcX&>|k_misAOO!})%Jz(0&d>^_~sAAv7hH$dvEn% z8FAexHwR2P0xk8L^ULg$$H_7h1+KT`Z*;3^{&&b`T;{PIcd6wWZUn+nLuWF@$I18! z0hXs*9|(rJbi>qanVY5YgZP-3@V$dW;?}OA!nKw#Y|^s+ZywX-nk~9!xg$~58}pmp z*9uJMG!b0F@X*a(nO_gB)3|?VA-v6hI#gl1dy4lv)bfh@Cc)onDoXCjD}V7Qwv<>x zz0_Qilx=SDctpc}rY_51*^PTev*kJ1x|<7PdWY|79H+x2>Ev5FlY%5jCn+i^DN8%W zLFOTo6q%eRxRHS4!?|{Nof^w0_N)e{My4e^`~D8qn~}+*gztRd4Os9x$;DD3KvY{! z(rx5&2s=jx;CcSeNF@}mAkDP*C&JkBFfps`5%J)NiCr;T>Kvmu6&M^{43+%;(Gpu0 zd59O()O!u~Dy9$QLK@#Zu<V*8pNaoa;T+lzErFM?<j^C|a};5aShDgZAwFYQ6hnL! zr=lvFJCnd_ifIpr#M}_oGCkcy(n>5iTmoOm?;igB8ksAZW{fIHqOM*4VY!_YrR4QB zlBNr|gmek)KGM3lly;U8EGLjPkb$ab`E7y({VjlE{P&SXP|ORCzNOB8hysW`rM^YW zWiDD3lW8etC%(Em^ACfR2M7)lL<rmjhY92_iAK_W1epY|J8=gb#bg4Zj<5XD8CX<D zK}!T!wpcVKuPI1ZEsr9<8k}`ZhX&qvtQV@+l3IKfF}YMwb_;<FAuCl+`*L!>5Q4Nv z$?{GtO0_~G?o7RwD{VbfL3EPV;XUIEo$JVc1b;AI3G4Cc@uGq!X-|&GMv`d4Emt_& l)kQyRXYuOz7+k=E$D8tGg=9Jn6r+(~J>Vy<Jj^~}{1+_p$X5UW diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-38.pyc index ae7743e5a3a80215f035053ac35ee6c95a7390ef..57341a5a814563cb6db013b6d1bc7809698f2388 100644 GIT binary patch delta 96 zcmcc9&e+(&$P>!T%f$c$n*VmiZ{&H$>Kw11k)NBYUsPFInw6<vT$HSzl9-p7nv<Mg yRFYb(S5aA|UzVCzrk|6Uq+d{3l98WhtY@KLoLQ2pTacKXotU0lyjg<nh%Ep?Y$8zr delta 59 zcmZqdV7$}L$P>!T%f$c$&&xK%ZRB~!Drco%l3So(kXfLcnO9trn3JPxlwnd@VVs`` L65MRdcElC{GK3S| diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-38.pyc index 8f4af00fa294584d095ccc0ad2bcc6a4f039fbae..50a4b87d27cc2796dbdf6377f649e28529108ba5 100644 GIT binary patch delta 2385 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 delta 2408 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 UC{c<odm5fR)(o3)?pVS90XN58=>Px# diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-38.pyc index 06b0962e9b5aaf7e84b616a2c886078e6c21cc51..9e7a13b0e8100cb5bd3758295fca373e72ab4d5e 100644 GIT binary patch delta 94 zcmccQ|J|P_l$V!_0SGkz?TX*X^M=_uNk1b$H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*kV7|R}I06KXhBLDyZ delta 57 zcmezFf61RGl$V!_0SKO#ZHU{*^M+Z@R=*^-K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J*_vgKG5{_S6R!XO diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-38.pyc index ff7b6b18faaa6f7598a2297b150d008dfe09998a..cb9aa7e5001e876b7a2304f791bc8b4d95d85265 100644 GIT binary patch delta 94 zcmaE*)UV7F%FD~e00f%<cExYxIl$<gsGpIao2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5*56=MTG0P@%&%m4rY delta 57 zcmeBIex<|{%FD~e00hs=HpFe@Ilw4qqhFF+pkI(#pqrUjT#}fRqid95Qd(i0p9m7% J%+J)o4*&qX5?KHM diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-38.pyc index 3b865dadd1845b4060e63bc2726dcfc4617cefa0..920af04d3dc48715ff01d014d26cb6a2cbccc721 100644 GIT binary patch delta 6104 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 ViTJM5mM`<~kCnJiVFcK1{|6cB=Ai%p delta 6604 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 bi9?b9PKSzrm+G~9^9r+c%gx%nl4Jj0C}2t# diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-38.pyc index 1888ccf1e10ed4e5cad10f198343b6c80aba8b7a..28cb4a1812ac32dac5ca4b09d5d1b6993a9c28d2 100644 GIT binary patch delta 94 zcmcZ^`Y)6xl$V!_0SGkz?TX*Xqs{D`te=seo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5&)l(|J601PQ1hX4Qo delta 57 zcmewtdNY(Kl$V!_0SKO#ZHU{*qs=U5r(cp=pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JT*cg?4geRw6B7Uc diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-38.pyc index 9c941759794a127fad87b2fdb3c295068a0b1e47..67fe40241426d80d994caa70c1d45e2742256125 100644 GIT binary patch delta 1731 zcmZuxTW=dh6y90yt~cvT96N67)JYttuCt937qv8$wvb{-)fQ5Ei5e=E;CR>RCidFQ zu2XDnC~84@;el#|5J6N<B`Wm+(aNeSK_x1o0uP9XKA_4Hh>H-ag!l!h;T*fEC}L;l z+i%W%GjrzbnOQqtpYl)nd<qAT`rz}KXy&3nO0HcT{-|5ud@6c?)4ZDRZBFy)y%$`k z`mX<QTF7M6XG%pqO{<m4ypgtOF0ExvLoeh?)Yh%hH>$PtqHZpx3&w1^T(!@X%pIdo zr7gqON6OjULUvBK*ikV?f(=W&LCATgx~sD7pYL?InND`uJxBuVYxmhu(`8kyrgu@N zmQgZi3^QM1`{ezJN$}N*qQ|^M9u~fv$ZG<x5I@u)Ft#e+A}RK2M~2KaE_c)jG<rQ- z$sBv$bBAP@;vMs(U<%rW5Mi$;Lu|&okywqh-ij+kw}H7SmkU`tU!q0TO;c>GvrNvh zav)1iu)Bee^Nv8T*qx4efh>uRSPy8*DlpqK@6|jDJiV)V9e%+LUtjy{@S1;&TjCwA z-sOl6zsfI3HNPX(gE*3KCpj}NaCT@xd5=&(;jq}<?3b>{;LB~DLmuk3KGID-()9-a zCSleS8kTnAmUgkjp}yqPNO3RpC_*Q~A%qP8O-VO%B~7O%*-B_MjNxd?Et6r+(PJnZ zV?Tz*q)R}pY1Y%7B0hGo`!|T?NO+k1#9j#(qqtgAp3PdinJwx~xd_RS*DYIhLCk&) zr^)Y);D)_CIn9o2x=#+W-H|8OJuFA|NaMK7es(?bBFy?AvO?~&4}0Dxf3o!Ecg{K7 ze21n)xIDjs!>wx`u(%f_ddumk%Mf6BUD5jbK<R2L9T&apxayqd*E(16X9SiMQ_#AW z6bQfKbU2dZc6diw6=7EHIHv|D=``*nV3@W}%Txzs>1g2aX|P@;bPWCMK?Rwv2?;A< zQG%w;05v&bjU=p5u({B-9blsADp$|a8c@|kcc6I}TaG3NhLL{IHn%d6qTyYH)*8py zz33sS7bdq-Y^Zlo3P5VheB-6wB=0=}vJ>q^rrBHl6YG)uu3z0Uj#Dfn>_vDMVFaKl zQ$4E{3{!_VM`9`RB%6pG@a=;x)lXY4Tw*J+gmeW*9AkH4dq6@4K8@jMm9!<@*x7<G zGVC(g_X9_cUPlq%5;eueY@wpJWshr%xE~&*98dA==2{%v@VKE0P%}`i*O(d4#PLX3 zr?d{o<p}uqmn2(qqzmLcam0By{4a%l5#N@o4NaNZ*@7OkOR>CRYB8!?r3%gIv4j;f z%-F*V2U@Dk{)ndoREIU1;%pVJs@AC<7))d^LhWHqSJ9gLum5ktkP7<02?$60MB)YF zbp?P4Q1~^8mm8JAX@1}u^wT<kDz*dSv&wqT$Q!w=4R;tEr@s<$vfSv}x|<|#|4Zk8 zOlP$-p_LO~!qqfDRv1g}2x5Xxs$~6*(VOgE^0_T(Fw_4#=@`%UaX-nP8QQ+5j&1Z2 zZZ=vf>(s8cGeoj<8}gmTQ80+G1pzlsZzFugt`0>fUI1$C0+5Ly2)w|<4aIS5N|)^R z64?u-Um2H0ftLk&r?N@j$rHsTK<yLcpc0}RL9O;Pj~bP30Hxd5h&nZL6X`fWQ?zVq ll<Bv~-MLb+Y!r0*33h*jfOi%vi(&Sex}Ef~pVfYF;UCX7p05A^ delta 1557 zcmZuxT}&KR6rOu$XLgvK9Tt`!!KExLf3uWA3k_AO1Tlr0%1@Ajgo?w?KnIrH&7A=X z8LSa&qwzs<W12{aizXTqjkcRAiH#;Ew)UkD`Zf=|m{@%`zNo49?21_9%-nCzz2`e~ z&;8E5lO2CBrj7@LGRLm_E1$jaUhkF~K_73mZifaqLotG{az@aMZ1Phz*S!nABd6P) zrA&Lq%CuQ2+tHKBwi6e-mM?Xtbr_`ULKKH*a@)d9gx2Y(e~o_ck0F)*=3k{ROMT)w zHjQ0P??^TDC+QZ7)Ax(|(RA*9(K=$C*+3IA=<9)RQ6C*vy4lE8r3+<px0Gc*?D6)R z?Ma!W?#!jhlIACI`gACRTzWI4qZesq$<Ad*SP-+tuCR+X1lLDyI3ZWq1Y5|K7&44H zfd$0~EMl^6C@x;~vv;uYcCn#$a~s&@vZb!z;$6HUuB)z?4MQa2Cb(3+k8{cv<+l*2 zMjYHuxl!zj72GCz1wGHD+VLdkB12x}8D+W<?4rMeoBj!&ItZrcOaDL>bS&IDeu4=@ zx)^xUyy?tjbmyX{f|W?8=B)Xd6`hb%z!?S@0VoC-WZ+3DCP+fJO;Q0}(M%=MhDpxT zyWwNy@jN3xWTocGC`6s4N?EtK%}jfWo-I4dV}++HWj`{-r^;K=5A?P2r3j?tNwe&; zDSgTGq$NFN&6&2N@l5&Rigx7XdMi$2G)>({enA6tuIjj0SO(px>JguWiF)aN)j9Un z*6MfAKD}N2Hu{-PKYC@+DO!*Xxr&>^6&&be1YB;xzbKMDw<s&I(nxs*+k02=A<N~- zJ(tgNhH4b=Vsg(2ZOAE~QL-Vkq6OR{S9JX@cI91xeUTgEw9+9mK}RA{X__VT5n}7U z6p1tljdok3P0m7s#~7UP_{`cWS!brEkmE4iMZb(R$3bh)zhV;GN~g#*@COL!NeIB3 z04D)PDPQx9Sc;gQEp)6Vh9fBF)-+?~S>}C?@W7d%pVpo^5a{<>tsyVaRd78H@B~0B z15YBRZX~Ug$>bZ19z~sWIXV#RVJ=NAO#d#u8*LOngosi4YqSSxw4?5mC`4<hKq&)f z9?HQ2*9H1#-SFrQAmKd86IS%(vRR-#%++Bnm{B=QA`BCG8~W@LS@W^h&ze0*ck27) z1rbgele~!HSR8A9IvHyZc*5+OW7?X?cFeU{V>=mV5&xa;B{pWkbSg7Aq#_afkiv&h zDEA;XiR-RI%q{~>C}bV9GiJh?vl6-kbzwzqsz<B2?WV_2^Vk34sSok&LaFja`-*NU zVXC&M=nY!a(pfseqJ}hd@I=WToo#ulp$%sKzf;!-4mf)3jD6SAQ4ZM=$dmn_NIGK@ zXN|PdpcaimKI9vK!-5<tUCA8%bVREh2}ynhNea7b<x`U2!;(+xk}IVyjAY)&+7X|m z%3%T#+7S<1X#y4T{K@qEJe=!#=wV`#&zV7n=@;5~+a8#(%{;+&h?OCC!1gE7OBpL^ Vk`KUr8vuSAbSU0|BJ^^+_Aga5dfNa1 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-38.pyc index 18d44b54880e960fb01127f75fcce46225c3e88a..34e1b46aa083ed4f178c1edbe0ea975742d5a8c9 100644 GIT binary patch delta 722 zcmYk3Ur1AN6vywmbLyQ8(=5>}D>9U^UH=pmCWe(2q!yN%e_Cr>ZqqioyK1YI;7IDh zH9NGN+uWA;7cKSruY`Iq@gW0?2<o9fQqdGDN~nyapU^|+;mbLn?>UFxpN~Ii-%nb4 zLMoL|BvMxHE2oE~Q<8nBSe@ydmgOw9wFW(F=G3f4Wz=h{)h3SDnic0Q7uY(jv5u|Q zpJ8h(yv}6IQ0!vOdR{B9QK_p`m0Gj#S@L2JOyKmvi{i5KdU=JAb4Yyv%CW1NlQ;5= zKZ<7zYXWdd#E0{YMr@-wr&Sa}8KMbaTR_p2GTKTRBDsFdw8zQj35~Fdl<TY_!+OFc zn$TtdiWigFFb!=Jar1=I)(}lNHrV5s5>mxFfGfd(Jua46^#U|d#gs8MgyIvbB*ZJi zr*;`g@Q;13^i@Q`QDuICvas+-T{>o6e=p{eX^KLHqX|-R)R6%>7<6m_iNLg!0*nco z8?!V_3TZcE0OXkKWZ^N^IgK!iADqkZ2H)N)h1ZzbIu|M@dpHF~xe{Oz6|Upb1u;dL z38cb-%f}X93}$;7>~}ffJ7%@*mwx-tFZ|~#aIP&6Slr}}C%W661k0#&_mZ6Pu&czA zMUGML*$FE+;4#53+~^Gu{?IFf2we0&AbDT=>g;rT3hDgPE`vzi;HxC}xA{I1UhP*9 zb^Ei3zVxTTW{e0NgG8(d%)kyzy1fLs7~jzVhq0~WG-M0EJIVm^vAC0mlQ`QMBwst$ zrGq?7><&UDGCd1Wg-bmuI4czOrU6_QuJ#21t{~Sx3^q&}n1oh*H!uP&blz!(M%;FH z9s)wx;C6s+R1CF(MVJ{%1{e{(4nG5!5T-_E0iK{^>>3PW{P;cczR$;-AYCY%(1}2X Ik0!VN1-mB;Q2+n{ delta 694 zcmXAlYe-XZ7{<?YHqC7;OS{d)ZWh{f%S#`G3^65%rPVAg%O%a!<&D$Hq$W~^&<CCN zmQI~+)3nyb+tJjNAo>u6RHTFi^&!HV1W^Q8Wb{Au|M2iWKc4sb!|Pt;=YR6r!&<GH zWA9VdV1DC}_K7+o$tadp8Y@dGV@t}<iUp;mvGK);=c*Gb3S=mSYToR^C@t*0$R9s1 z*)mS0;}E@Q5Vll{D$hz$Wn1Azjl!-_a<&lWLbEuYvxL|=Td>egWsN%h9HSb$!m`?~ zu&rTSZ4GDuI59v}Sp%(nokEynl(#Fb%V?-kmz2re+9n8@7b3-VY!3A3yquh<<Jnf2 zXT3E@c3$RkxbhuJP7FVzW_c4S9D1n8=tv>E<D>SiChLGDGs|K&o2ufeu&EwK`qGqu z6x!IlN!rtV6d08{uTArKDA{hT0%EAP#faxL&{B>OifH|f_oQ<k!#fh4uQV|{#|g2r zcqwjQXuvEx;sO=5Wy4QXZ4>xTRqbi`Mw9Iw;RZPt%mPBTJjqd?LYR?(frO5&_(jeR z9}JZ0GBOoh$?Wq%*G??aysH9>bfnYE_+qCXYKrW7^uN#~cR?;uGKmfna%5njzg^L6 zJ<6@ea>{lWu@g+WKeP2-kAdl|Cz)x8Hx3&p&3h0L)Z%@L1j_IJfpjwW)FOjsdQM`u zlz1}_*iTKpB62C9&yPI%+E)w{<=*n+G^O5NfQ@2(1t^ppzBr&pdVI$ZT%o)7hH;tl z?@ywY!um(xq?i2-xI`xgKENZT3~mGZsA$NE>fzxiK$4=R*T9(cXJi_fre_bXVt~wJ W6YSF3@p{Bb*T;($*iK86oBsjYUieo4 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-38.pyc index 788e5ebcd5b5b0608e064c2d379b7823ed0c96d8..8040e0ac7a17fef3cf19ce3a12531d924c43e003 100644 GIT binary patch delta 96 zcmaDckFj??BTpzVFBbz4X#U$3zmX?`#W_(wBR@A)zo@dbG%HiTxF}gaB{45EH77a0 ys3f&mucER_zbrMcOg|?xNxz`7BqKl1SkFSgII|>Gw;(Y&J25@AcyklWGcN!!Tq2nO delta 59 zcmeC3&-h{<BTpzVFBbz4JTKc2w~;4;Mb1XQB)34nAhSR>Gq1QLF(*gYD8r<*!Z<$> LB)EAw%QG(kE#DL+ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-38.pyc index a64c7d2b64ed2468206ea493b2d330af568037da..b7743fab7346da60a233e69722e6e1d1961e61f3 100644 GIT binary patch delta 7105 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 delta 7040 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-38.pyc index 228d895ded86a1f2d1bc8550fb50a2d44975021b..1833c6836a93dc8c914121a513aec8160709a300 100644 GIT binary patch delta 93 zcmdnP{E(R^l$V!_0SGkz?TX*X6UykEqo0wVo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu vTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?1M)p3xQnsWTvS delta 56 zcmaFJyoZ@5l$V!_0SKO#ZHU{*6Ur#(u3wT{pkI(#pqrUjT#}fRqid95Qd(i0p9m71 IyoAvf0Ng$j00000 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-38.pyc index 86472ba632c540bee44acbe416c5e4891df7de84..6cd1781d55b95b78b76b1c08492ac68f63d49139 100644 GIT binary patch delta 94 zcmbQwafE{>l$V!_0SGkz?TX*XGnLUfLq8)wH&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lAe#QhQ0L!%@1poj5 delta 57 zcmX@YF`t7cl$V!_0SKO#ZHU{*GnG-!S-&K=K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J`3YkJ69Ddz5|ID^ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-38.pyc index d03c5271054565e6c886569b57faddf00d174ee5..f6000a78fa8ca4cc578e4f33432f8865df43c06f 100644 GIT binary patch delta 5201 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 OtFvG3Rq|i^-u^Fbe#glG delta 5033 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 A5dZ)H diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-38.pyc index 5e177521cf434537f336175fc62a5c88a0535bdf..6829852bffc8235e80273fa3084d1ae1ba941f0e 100644 GIT binary patch delta 652 zcmZ9JOGs2v7{~8-9d9~0W4VY5(;3IBj`O&_9cO%%mOY>cJ)oNqlmA=J`0QSlW(ovH zi8fIjT1bmBS{T^EP75ojHZ5A@A~1+{Es8eLu0>FNhD3DEf#3i8@rT3Ve7?MR#e34@ zaVxxnKcAlcG<efnN=wV33{Aslxzc4&;h$4?DBBdX92FZTuwi_t{LlC;HSN8--U}>{ zS^0O;d8&e%tcGgVKu6WAVg^x-8fGnmsAYx_LYNsw1ku@P#f-o}9g8UTqaF>jWEyD1 zCN_0wLNl`-Eofyn-~eLqa-$J#aItAZ93Eyf5-4Q0SdpB<k7+-jhYq;8+4_&^L;;%^ zx}b5l4c*9(bBJR%HZv30gCb@-deF=4z+UWQc3NHN8&Yqm_M+99Q;07(t^^Otw`!Vt zMvTF+5zDYMlauL`;n)KPlA|eWcwo$)u$<_nOxBpPMyHJ7)H!23Gch<e+8B))PHMu6 zj3)<%k{2vTnyxO*pDoax=%4c?kN+u~|0mnK*0W1@bVtm4WAcOh2+=hWDjK1jm@j%s zLYkg(qT3?teL)XIyco17?iA0_vedWq5<L^?t>0)xo+-&{v?kwee@=8r-r5;Z>6Cm@ zdXLDK{bd(bnvttMjc7rv`R~(1k*&B+k7Qw>k7z|4t6Zg5(x-pb=#4B6+eAm@Oys?r tPK*B7clsetw0%^6sWKKnOr(jci7<7G$BEZ8By;Tn()=aFTP$@Xeghak!-oI> delta 584 zcmYk2OK1~O6o%(a<Fuy9w2C0n*yh<b&9m>MlQgYX>qZM|K}HY)e~L+4O=}ciSfS}c z1W_&`2uc!Nh%T&LR|T~TL0zajMJ)(|6c>s+K@dIJh-Yy>{*NEd;od#Bc2=LT+pP-E z+R3HE2Xa?+CsiK?Pt$zXl5Z)uRuqs!F<rF;6|O~<lRN9GS$^FPWwT;>vT9y0d%5GQ zkm>)I+BmgC&2&ID1Mt9GQp`^H;AaNWhIVEM9SAVP=tPhiK?q^yd=xtoL9|3>3^CNR z>OvQ~nce6?FS7@`&<C9xz37L9O&<neXZ9nG^~`~6WI^Gx6O(lqgq54||BQhKHVGu5 zad!|YtYaD&LSspZnMtH!W0ArzMwmm`jvdT&b{L~m>J@eFRyMt$5HHxT1jgj5nx~fC z(c(-YTF4c`xueI6nd#|p_mSQcr+SWMYEoXbq_z65b^P6P+r+AFNO$8n(Iqi!o1sPV z$+kk*WZB+IbW^P8PwBq6&;+_CzBDb8lvB;4M32SNh99&nD;v*f^iDb*Pl)!&k6XMd z9h85ZRidJ-w#=$jlAGKb(QUESbB7*?70+dQB*(pDM9bp3?=?M_lm71-y^#~4Iih{? zMfkmy4vA{~C;b*T5}#G7ljjHb5;cfdMu<klFXN^5ws!dk`7G%r&8w46&Ei|i_zQWg Bu`U1r diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-38.pyc index bd828f3386a4ced6df812a63ea5213fa593c4d19..fb881fb739aaf2751ea07e4fae016c65bf1bc69b 100644 GIT binary patch delta 96 zcmezHl6mSYW}Z-9UM>b8(EPV6ek0F*cIRyUjQreG{i4d!(yUDV;-X~zl*GKu)STq} zqLS2Ny^6{z{j$`&GX0#)B>jTQl8pR3V?7J~;>?m%-GapA?8Nlc;>|DF+1~;Hk>n%g delta 59 zcmbRGiuuD!W}Z-9UM>b8cwV+4ZX?frb~!iwlH3CQg3JQl%)H`~#GD*mqYRVM3gi4l Lkl<!M4)(VIVH6Z{ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/shutil.py b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/shutil.py index 159e49e..10ed362 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/shutil.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/shutil.py @@ -14,7 +14,10 @@ import sys import stat from os.path import abspath import fnmatch -import collections +try: + from collections.abc import Callable +except ImportError: + from collections import Callable import errno from . import tarfile @@ -528,7 +531,7 @@ def register_archive_format(name, function, extra_args=None, description=''): """ if extra_args is None: extra_args = [] - if not isinstance(function, collections.Callable): + if not isinstance(function, Callable): raise TypeError('The %s object is not callable' % function) if not isinstance(extra_args, (tuple, list)): raise TypeError('extra_args needs to be a sequence') @@ -621,7 +624,7 @@ def _check_unpack_options(extensions, function, extra_args): raise RegistryError(msg % (extension, existing_extensions[extension])) - if not isinstance(function, collections.Callable): + if not isinstance(function, Callable): raise TypeError('The registered function must be a callable') diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/sysconfig.py b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/sysconfig.py index 1df3aba..b470a37 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/sysconfig.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/_backport/sysconfig.py @@ -119,11 +119,9 @@ def _expand_globals(config): #_expand_globals(_SCHEMES) - # FIXME don't rely on sys.version here, its format is an implementation detail - # of CPython, use sys.version_info or sys.hexversion -_PY_VERSION = sys.version.split()[0] -_PY_VERSION_SHORT = sys.version[:3] -_PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2] +_PY_VERSION = '%s.%s.%s' % sys.version_info[:3] +_PY_VERSION_SHORT = '%s.%s' % sys.version_info[:2] +_PY_VERSION_SHORT_NO_DOT = '%s%s' % sys.version_info[:2] _PREFIX = os.path.normpath(sys.prefix) _EXEC_PREFIX = os.path.normpath(sys.exec_prefix) _CONFIG_VARS = None diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/compat.py b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/compat.py index ff328c8..c316fd9 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/compat.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/compat.py @@ -319,7 +319,7 @@ except ImportError: # pragma: no cover try: callable = callable except NameError: # pragma: no cover - from collections import Callable + from collections.abc import Callable def callable(obj): return isinstance(obj, Callable) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/database.py b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/database.py index b13cdac..0a90c30 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/database.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/database.py @@ -550,7 +550,7 @@ class InstalledDistribution(BaseInstalledDistribution): r = finder.find(WHEEL_METADATA_FILENAME) # Temporary - for legacy support if r is None: - r = finder.find('METADATA') + r = finder.find(LEGACY_METADATA_FILENAME) if r is None: raise ValueError('no %s found in %s' % (METADATA_FILENAME, path)) @@ -567,7 +567,7 @@ class InstalledDistribution(BaseInstalledDistribution): p = os.path.join(path, 'top_level.txt') if os.path.exists(p): with open(p, 'rb') as f: - data = f.read() + data = f.read().decode('utf-8') self.modules = data.splitlines() def __repr__(self): diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/locators.py b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/locators.py index a7ed946..12a1d06 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/locators.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/locators.py @@ -304,18 +304,25 @@ class Locator(object): def _get_digest(self, info): """ - Get a digest from a dictionary by looking at keys of the form - 'algo_digest'. + Get a digest from a dictionary by looking at a "digests" dictionary + or keys of the form 'algo_digest'. Returns a 2-tuple (algo, digest) if found, else None. Currently looks only for SHA256, then MD5. """ result = None - for algo in ('sha256', 'md5'): - key = '%s_digest' % algo - if key in info: - result = (algo, info[key]) - break + if 'digests' in info: + digests = info['digests'] + for algo in ('sha256', 'md5'): + if algo in digests: + result = (algo, digests[algo]) + break + if not result: + for algo in ('sha256', 'md5'): + key = '%s_digest' % algo + if key in info: + result = (algo, info[key]) + break return result def _update_version_data(self, result, info): diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/metadata.py b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/metadata.py index 2d61378..6d5e236 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/metadata.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/metadata.py @@ -5,7 +5,7 @@ # """Implementation of the Metadata for Python packages PEPs. -Supports all metadata formats (1.0, 1.1, 1.2, and 2.0 experimental). +Supports all metadata formats (1.0, 1.1, 1.2, 1.3/2.1 and withdrawn 2.0). """ from __future__ import unicode_literals @@ -194,38 +194,12 @@ def _best_version(fields): return '2.0' +# This follows the rules about transforming keys as described in +# https://www.python.org/dev/peps/pep-0566/#id17 _ATTR2FIELD = { - 'metadata_version': 'Metadata-Version', - 'name': 'Name', - 'version': 'Version', - 'platform': 'Platform', - 'supported_platform': 'Supported-Platform', - 'summary': 'Summary', - 'description': 'Description', - 'keywords': 'Keywords', - 'home_page': 'Home-page', - 'author': 'Author', - 'author_email': 'Author-email', - 'maintainer': 'Maintainer', - 'maintainer_email': 'Maintainer-email', - 'license': 'License', - 'classifier': 'Classifier', - 'download_url': 'Download-URL', - 'obsoletes_dist': 'Obsoletes-Dist', - 'provides_dist': 'Provides-Dist', - 'requires_dist': 'Requires-Dist', - 'setup_requires_dist': 'Setup-Requires-Dist', - 'requires_python': 'Requires-Python', - 'requires_external': 'Requires-External', - 'requires': 'Requires', - 'provides': 'Provides', - 'obsoletes': 'Obsoletes', - 'project_url': 'Project-URL', - 'private_version': 'Private-Version', - 'obsoleted_by': 'Obsoleted-By', - 'extension': 'Extension', - 'provides_extra': 'Provides-Extra', + name.lower().replace("-", "_"): name for name in _ALL_FIELDS } +_FIELD2ATTR = {field: attr for attr, field in _ATTR2FIELD.items()} _PREDICATE_FIELDS = ('Requires-Dist', 'Obsoletes-Dist', 'Provides-Dist') _VERSIONS_FIELDS = ('Requires-Python',) @@ -262,7 +236,7 @@ def _get_name_and_version(name, version, for_filename=False): class LegacyMetadata(object): """The legacy metadata of a release. - Supports versions 1.0, 1.1 and 1.2 (auto-detected). You can + Supports versions 1.0, 1.1, 1.2, 2.0 and 1.3/2.1 (auto-detected). You can instantiate the class with one of these arguments (or none): - *path*, the path to a metadata file - *fileobj* give a file-like object with metadata as content @@ -381,6 +355,11 @@ class LegacyMetadata(object): value = msg[field] if value is not None and value != 'UNKNOWN': self.set(field, value) + + # PEP 566 specifies that the body be used for the description, if + # available + body = msg.get_payload() + self["Description"] = body if body else self["Description"] # logger.debug('Attempting to set metadata for %s', self) # self.set_metadata_version() @@ -567,57 +546,21 @@ class LegacyMetadata(object): Field names will be converted to use the underscore-lowercase style instead of hyphen-mixed case (i.e. home_page instead of Home-page). + This is as per https://www.python.org/dev/peps/pep-0566/#id17. """ self.set_metadata_version() - mapping_1_0 = ( - ('metadata_version', 'Metadata-Version'), - ('name', 'Name'), - ('version', 'Version'), - ('summary', 'Summary'), - ('home_page', 'Home-page'), - ('author', 'Author'), - ('author_email', 'Author-email'), - ('license', 'License'), - ('description', 'Description'), - ('keywords', 'Keywords'), - ('platform', 'Platform'), - ('classifiers', 'Classifier'), - ('download_url', 'Download-URL'), - ) + fields = _version2fieldlist(self['Metadata-Version']) data = {} - for key, field_name in mapping_1_0: + + for field_name in fields: if not skip_missing or field_name in self._fields: - data[key] = self[field_name] - - if self['Metadata-Version'] == '1.2': - mapping_1_2 = ( - ('requires_dist', 'Requires-Dist'), - ('requires_python', 'Requires-Python'), - ('requires_external', 'Requires-External'), - ('provides_dist', 'Provides-Dist'), - ('obsoletes_dist', 'Obsoletes-Dist'), - ('project_url', 'Project-URL'), - ('maintainer', 'Maintainer'), - ('maintainer_email', 'Maintainer-email'), - ) - for key, field_name in mapping_1_2: - if not skip_missing or field_name in self._fields: - if key != 'project_url': - data[key] = self[field_name] - else: - data[key] = [','.join(u) for u in self[field_name]] - - elif self['Metadata-Version'] == '1.1': - mapping_1_1 = ( - ('provides', 'Provides'), - ('requires', 'Requires'), - ('obsoletes', 'Obsoletes'), - ) - for key, field_name in mapping_1_1: - if not skip_missing or field_name in self._fields: + key = _FIELD2ATTR[field_name] + if key != 'project_url': data[key] = self[field_name] + else: + data[key] = [','.join(u) for u in self[field_name]] return data @@ -1003,10 +946,14 @@ class Metadata(object): LEGACY_MAPPING = { 'name': 'Name', 'version': 'Version', - 'license': 'License', + ('extensions', 'python.details', 'license'): 'License', 'summary': 'Summary', 'description': 'Description', - 'classifiers': 'Classifier', + ('extensions', 'python.project', 'project_urls', 'Home'): 'Home-page', + ('extensions', 'python.project', 'contacts', 0, 'name'): 'Author', + ('extensions', 'python.project', 'contacts', 0, 'email'): 'Author-email', + 'source_url': 'Download-URL', + ('extensions', 'python.details', 'classifiers'): 'Classifier', } def _to_legacy(self): @@ -1034,16 +981,29 @@ class Metadata(object): assert self._data and not self._legacy result = LegacyMetadata() nmd = self._data + # import pdb; pdb.set_trace() for nk, ok in self.LEGACY_MAPPING.items(): - if nk in nmd: - result[ok] = nmd[nk] + if not isinstance(nk, tuple): + if nk in nmd: + result[ok] = nmd[nk] + else: + d = nmd + found = True + for k in nk: + try: + d = d[k] + except (KeyError, IndexError): + found = False + break + if found: + result[ok] = d r1 = process_entries(self.run_requires + self.meta_requires) r2 = process_entries(self.build_requires + self.dev_requires) if self.extras: result['Provides-Extra'] = sorted(self.extras) result['Requires-Dist'] = sorted(r1) result['Setup-Requires-Dist'] = sorted(r2) - # TODO: other fields such as contacts + # TODO: any other fields wanted return result def write(self, path=None, fileobj=None, legacy=False, skip_unknown=True): diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/scripts.py b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/scripts.py index 5965e24..03f8f21 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/scripts.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/scripts.py @@ -48,7 +48,7 @@ if __name__ == '__main__': ''' -def _enquote_executable(executable): +def enquote_executable(executable): if ' ' in executable: # make sure we quote only the executable in case of env # for example /usr/bin/env "/dir with spaces/bin/jython" @@ -63,6 +63,8 @@ def _enquote_executable(executable): executable = '"%s"' % executable return executable +# Keep the old name around (for now), as there is at least one project using it! +_enquote_executable = enquote_executable class ScriptMaker(object): """ @@ -88,6 +90,7 @@ class ScriptMaker(object): self._is_nt = os.name == 'nt' or ( os.name == 'java' and os._name == 'nt') + self.version_info = sys.version_info def _get_alternate_executable(self, executable, options): if options.get('gui', False) and self._is_nt: # pragma: no cover @@ -172,12 +175,20 @@ class ScriptMaker(object): if sys.platform.startswith('java'): # pragma: no cover executable = self._fix_jython_executable(executable) - # Normalise case for Windows - executable = os.path.normcase(executable) + + # Normalise case for Windows - COMMENTED OUT + # executable = os.path.normcase(executable) + # N.B. The normalising operation above has been commented out: See + # issue #124. Although paths in Windows are generally case-insensitive, + # they aren't always. For example, a path containing a ẞ (which is a + # LATIN CAPITAL LETTER SHARP S - U+1E9E) is normcased to ß (which is a + # LATIN SMALL LETTER SHARP S' - U+00DF). The two are not considered by + # Windows as equivalent in path names. + # If the user didn't specify an executable, it may be necessary to # cater for executable paths with spaces (not uncommon on Windows) if enquote: - executable = _enquote_executable(executable) + executable = enquote_executable(executable) # Issue #51: don't use fsencode, since we later try to # check that the shebang is decodable using utf-8. executable = executable.encode('utf-8') @@ -285,9 +296,10 @@ class ScriptMaker(object): if '' in self.variants: scriptnames.add(name) if 'X' in self.variants: - scriptnames.add('%s%s' % (name, sys.version[0])) + scriptnames.add('%s%s' % (name, self.version_info[0])) if 'X.Y' in self.variants: - scriptnames.add('%s-%s' % (name, sys.version[:3])) + scriptnames.add('%s-%s.%s' % (name, self.version_info[0], + self.version_info[1])) if options and options.get('gui', False): ext = 'pyw' else: @@ -367,8 +379,12 @@ class ScriptMaker(object): # Issue 31: don't hardcode an absolute package name, but # determine it relative to the current package distlib_package = __name__.rsplit('.', 1)[0] - result = finder(distlib_package).find(name).bytes - return result + resource = finder(distlib_package).find(name) + if not resource: + msg = ('Unable to find resource %s in package %s' % (name, + distlib_package)) + raise ValueError(msg) + return resource.bytes # Public API follows diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/t32.exe b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/t32.exe index 5d5bce1f4a65f0bea9636a5a825646c520903df4..8932a18e4596952373a38c60b81b7116d4ef9ee8 100644 GIT binary patch delta 28024 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 delta 25283 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/t64.exe b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/t64.exe index 039ce441b721ee180d373e5590289a6aa9249a51..325b8057c08cf7113d4fd889991fa5638d443793 100644 GIT binary patch delta 30704 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 W8H)=RS1fK=yuGlWv7c$80XqQBh9l$v delta 27635 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/util.py b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/util.py index e851146..01324ea 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/util.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/util.py @@ -703,7 +703,7 @@ class ExportEntry(object): ENTRY_RE = re.compile(r'''(?P<name>(\w|[-.+])+) \s*=\s*(?P<callable>(\w+)([:\.]\w+)*) - \s*(\[\s*(?P<flags>\w+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])? + \s*(\[\s*(?P<flags>[\w-]+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])? ''', re.VERBOSE) def get_export_entry(specification): @@ -1438,7 +1438,8 @@ if ssl: ca_certs=self.ca_certs) else: # pragma: no cover context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) - context.options |= ssl.OP_NO_SSLv2 + if hasattr(ssl, 'OP_NO_SSLv2'): + context.options |= ssl.OP_NO_SSLv2 if self.cert_file: context.load_cert_chain(self.cert_file, self.key_file) kwargs = {} diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/w32.exe b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/w32.exe index 4df77001a222c84ff3fef542618b3f45f4c1eb9e..e6439e9e45897365d5ac6a85a46864c158a225fd 100644 GIT binary patch delta 17543 zcmd^ndwh)7_V+W7TqZJ+h$M28L?lEIbI;sokPw$JBqoVVP{IhUU`A<6=!i;3>asai zR4GMUG@80AiKu9+ZBFa7N`tDhiB`0#DQe#DerCiu=lA>L{pbDbO+Rb)+H0?UTYK%b z*IxV4#fSVC*ZQwAh+0+~v&vryEm2*cq<#WBcKxMRBA@Z%XX*$c^{911`nh@lQp4uo z)Ka9X>l4+b0{tr=|3hE;NJvLbpKNDsa{u*b&E~jaB7g4r9)FKxMX~JX3df6rMeRB6 z7&2QJh2sXuNwO$|-|#LOCF;&g?vWQn$s#FvQ`AjVM(RYJ_=%#`U1Ld$NUXka1pHwD zR^1QqZ+}S~H!)+*lu3?BVCjv5MnDFjmSpffM86Unejk%Xd~Am!9YEe9@-}6y*};zy zt(J<{_yvoG5s6=HTu!5f+vZ5^$5qriV(o{5Ij)qmhjAj#zJ>Jji!<5mhFccS6FCfg z?v}0d1x{y7#eIj`J`N=|Po&U<x8T2;C_@toA~Bih7q9x$<FR|%ah#n^#!7F-aa>i! zBT%ih#N+X}PDPiBJdqshCijuz3pyT>`;-*=DY`uxB(OeYtTm7S7goRaWUpVGNJc*M zQy30mP*vHF6dt=ht{-QuT==MRVGAuqYl=_x4WVo6?6u$+Nu}ttlrQi&AJKIf3rp7% zt$#{KyEkX|gV0Jvd9<87=Pwl<BX9Y44fFSw*)UY+J(>_n8vUb0Kad;#Jw#_nXh2-w zjaYg#b%IqcV72!}2pyk^t3A#&Tev^Z+pIJIlbGrbJ`~?fiUN{DhIs1;>?LG*Kv#7< zIH&46Is$X_^>cr1ZdaMz!p2u0&vEYTmZAy8pVp6d-*(-W*h(`zPO;*CrL&b@Czk`# zdMBZ3RrWnAL|~<7gqH8QTUqVF9XZZ*DnkF*Ik+mj)p|nOOca4VBY6zabxNW??L61q zPH}%AW1UK72lfcb7nZ!@zEk3f%p&guW+sa{ZmS>Hk5ingT$*woId`@=&sL!D6ckiu zrNnz84diiPRE!c8p-vLlODSPxPJczMrI}aM+BMCjkGQ+05F@nGM_A6%tYTYLR*JH~ zO4ke*23P4wNpq_#s9$>D^Q{$yQ|LWNtHCd2K5>iVMQh0}aeR5T(1aUJ6cv?<>?IKv zt|2RB9JCgiYDH~SjApfaTMG&x*Mb6%1KoHcBT%Mqa2hcoU<HSnE{?2Pn?kWkMvb%< z*x8QrM5eJOmZn?*)ry+Y_C|DAK<geb<qPw~g5=IhNy*z*hV9^qOaVLCF#kf55ft0I zH}dwB+iaTOph{5@3d6j*eHQCB5+ZXOt^c%eM{{lyM^LJ$AK4JpJ2oFR@@So)sTH-* z)I56`NF(VWawRA-_Gb*Os0ea>BG5ehM?xRbB(!~G>;Ye~^Tt${nREZ?hzUIyP%5_4 zH;Jizw0-H5+G0iR)XD(YX}*B=edO`v{dwMg8_mRdO1Z)%H_E#7<3iWfTIrU*gt<<2 z>64w^QN?9S&I?^zYft)xP3vWpdfPcAK~t`J-qpaDhT84FkmK#U_FXP8^%I(qU>H*| z>h5eTS3`Ysh!$!$cVNUXNQdAFVM>U&Ii;$MZ|=y5#bjY{I!xoPU_)e6tH<L$uc)oK zh@sif3yo)xzk;RW76JeBPa>1Vch*4c?iNL@;-da{#u)!A8)`k7B1x5x?BMHIjNwkz zCOB^hbLwW#0TbqBr7yx1L7Vsq-a#diqmtOD`A<r7gi>!&3u%@}i*^gG`-85i)mEIx z5bfs~Hxu5S`%v!Cv3Ug$h=rqr0-18BRMa}>2}Y@^;x<%QFfdlyHB#7rUYgYtnNJ)c z-2%O0t|Xg75=DjNct}-V#2q%9fBgZowf`J?^X&gY_+>p8*mF>7v*pnrgIH_QJlY+? zKTF@k3ZK=7us!SKf3LrJJ_<HXVwbjHRBt7c%^jjbG7~wjfdieR7ZONahpy!hVB{*Z z#n>ky^zQ^#8jaHCPhm=@YW2<}N(CaTQu??myTxi}?bGnC!bF<4T0PD%4CMi8VYgIf zUu(#Iggxw`7#l3cHEKkc^{`uXCRmE<-5zWTo7*Xdsp&-B!DziSs<={0`zDZ?p(*^> z1hOVn*KsD67kU(FKZczHLFJI9(4P9c$*hS|F%1<Ex5q~Jr=pt{8=Z&LMk!`vqhkep zpzy2j#waP>NWU<%<zX+>N3-oQ9#7;C>V8}iRf1+;j9%<^{Lrl!JKK29d|QG2l^js2 z(>d<YM3fz$LTba(`PIG1?XcJmRwh<y7Ytuaf9^^mI;wE059!!DvM`0?w1JLa^bhBl zJei(v-REg`3UPPTh?k;~B@3^uBA<7R5w8_8SJso;9aV{cLr6tTNFV==owzWJbBNLG z4Mwe}{o{!xJg@zN-t4py)064s&G7EA4nacBXd6wyq}?rED`%x&#*(J+gakXd-7T>7 zkaM&)`;ns)ZNdS;CQr}Bl9*0OJVvGO)IB*(4Gjoz5A@Uf&kyRyIilPH#qN-@_V5yN z%Fy2{8N}6TU`R4*`&8$X81ikWIpIfC92a`9g(*eo!9Xj0PesN=6oqJF+88fJliG;N zp!%MWQUVQ0Bcmcya_3{<?$!#AvwNwe7-w)S`V7gVF-gMOINxm!q@$oJP>G>J;%=Bw z+#HcdTbVRyCTI<u1j?nT9Xr0BoQnKf6i!}`>J}^S{6v+$g|^=8&CUm>*harqk#kXb z3JlhL298H%Zma%tXJ@(}Obr~?mZR?hb#piO0@vn>=XMm#6<r%e#&qs3WA#qy>mBh8 z+}X3(86B<k4J=X-NI?x;Qxo*QR_xAgb)T=eh&^PCBKtbWCMel<h=#N~<_Uv%4~8C# z;cjV`Q2!`$vvWe!i?AD?diR6tb{Mu%Rc;FnAYGzI@vjAt+0oLFp|BP{k^dS&_C|LX zwUU2Dm+=xK85A={{Hg&0vC=B?ZcLnLJ^3WY(!K#CbVDz9BB8Nqfn`ibxd>v4O-U{F z6}{Z4t<hAVidyOqrvN)Nn$}6kE3qp6ZwWabJ3;gkNr+1cc`v+;JvW?;h>H(d@|2Pi zPUgq$jXMoz!#B?9%<nkkxmg0~+X`qi=@%a*dY2T&&*Kw1lE(OaI8dowl%kzvOqUVT zRcw5(;jn^L%@)I&V&6s5J|Os-Ys3+P=9<%(;?D{q-*-s~L8)L*K7xfQA`^xsg`NbL zuR;k>^4hTI(2Y-NCPv#oY(iIU25J<!T0M?rPwut(f$r=p%cGk+R%KtY=FxZ*5>;-W z(91YIe676<l+4b}81;4=?WUV)%o^l9&UgsT<BZThoR{v_49K(Dhublq)n2dF)e7H> zP6wk)lk6N%CjhI|H0Qgc3m7B0o7+XI@RjzUJy~gVb3#S!f-Z_rr&e}g)x&5w$PFBf z9Y^<vU@W7DB#Qs=wm+V<Pv{%=70wn>w!~Eu#ueFU(?BvfL7KW7It#^kLCd^Rr~_sk zx~{IOpQm_yJr0CwCiOSS=7cGt1*Bb~D)PG_9Jehx6lVSIU}ho~1kp)@Np50nYC7^o z?$+isD@|mmzF}UhJ7B8IFyH9x2zMH1cWw?@k=QMyku~}<_GM`x%_PSX^Fm(E;kc?Y zQ7LbuCtFB-(uhuBD6WT(R!~6CVn2X$6IqnBZg9seD2uz5?#4K5)K9_T?E3-T;XuJ) z{9Rvpn#0`#<FT89t@N2Yu#i*Zxgyt83CC=MFsByQ{Y5gat44H#tn1pZzf5r6#q<SO zBfEzQ@If=P?BFi6husCY2}7vLUXR0Nd836>+}Enk;6QK&+u-oyqO+7lC+C)56l|tb zTpCaF*vUYLVY5I>#ie1izd&e#@u-9wy-zNPPFxyCZ~X#JPvl}WyX_R(q|XnBfFqcI zKg{)UiRmfEMSBhP5rSw9Bb18ht8Ae9(+-$a@fLw;*AQ|$IX12ArpHs6eMRfM<_xgX z?kJ+U_-W2?XWw><-9eSPKUhc7_`xKjTU5M+75B!E??8sK({4dn06KO!nb_@A)_OL) zG7Jh`reJ_YrSNXof@r_?Pq?^|tAM(UjDf>+MU-Pa_8>p5))N_xG6-%3v8QCj1+#*p zZQHxEd!;j>)X!F_s%6vuEtl*|al}=kg~diOYsleG$AH_TV$5_(GqI$mM=lTMxFy3S z++sA-+}?FM3DVz0%2T7`#-hZXEm@M|EgWBujH@;YJ#Qi(re<`|VhORLUeXrwYiidH z?f-*R)1`Z(h##F#?(~p#wclc1t^{KYcAaj&<a2h@ZthnqwsT)wpm&3Bk$!1i`1D(3 zV%i}7#XRzEnkqudG$ju=S;a+#r*h#n$U#JYOY6t~9Y9n)%{<K^^Llnm-wt_H)NW<7 za(414t7+?Xtf7#vjIVBvbNf|48Fzh8on#S@b#M!<btFOQDn2TQSkj~TvUF0IzE8_m zrW9wScR8vm&cm_8oY{h4@L@PQC9a1aM_?Z9iraD#uFw+{UyP-OA4&gS-6B?it=N06 zcvLyz?9Ng~7WA4E5sB4D{eVNQ?fP*Lnz)|w#M4XP&c0Yr2J~JNzUMMr@8J@h|Lwj~ zNHp}#%j8Dy+2QFvvP~fCXzXQD+GlC_+Dl&UC*-A<)?{S!TW~gI6o&F6IPNgc0M0!? zOe02+y%`z&jwW&`V@mP_C;;=@6`v};R(L$u;Sb`DRLYIA4>Yk0&}%Eml)gEl?PO2i zl!R(b#&(?Z>&F$iO%)zTC)XlBkt3wQ^GyLgdWGESn;pCbEP@TN-X&&f&$Pu&5PcCm z%qry{tfDr-;pc8>ezr84UWN+7oarArL+N<3N}AHcyKv6V1@snXSwz!dPrdF%<@jsO z!Ih@wzykW!WpYuP6)}Txc+^lnCSi0bwwDowtXFu+FqoGF)U3CMTG-avMapDTgUY~G zUz%iJMJ~(cN;bep_Z=%nQY@FjTU;fN<##vL?3PPJ$Q@QB*mkihp2$N;PWo~1Z#}9M zf3||hKykOgmy7eL&U6yiRG_pm)Uxd9;`*&g;Acl%l+~kZ^m39u%9xZ>U~q*9t=*i5 zv10VqOt~-NQe#iS4)8?IB&A9VVjJ%(OGH_uqbh00JR?@H1^)1ThYnq_wmqt|ZT)*1 zVUwdvv3Xi?DB<cG*~oes?&qltXb!Sb%|%cZ_i-0LOI}pPgxtS?JR2oCKTo!*;>()_ z%D~=e2j;HHn^SsoUwLx|Z?4Xpvv_kg-dvV9_l`H0<ITP9&5bi^sD)$AE@On!5c=f< zq^^=joO_WSx)h6XMV`Zeu_;2Ac&wP51FKzhfs9n!c+my&uDVZWb`cT0)gY>b+o!0V zP;Yaqa>y@gy{MM-%<S5oEzLHzCR>?^8~jfJJ=WjCRSJUI=3RqBq%5;rNcp!Ok4MEA z+^St<OQxX*(-Hf^EJ$A<d%p8DZhNwVS@sCn30RyRI?_(lOVmjEYLcNSqck%9LJq0W zBx{E0pwR5L5>+)IOkY38gzMNNs`gPGed|2DwMuyi8p#HE4n`Sgw%fRiT-J1#ybb>V z8>I#2b{FZWO_FfGK_3Es$GP#zIbzhN@!QXlY1)Lqq!wI$l3K_LZDL>=!_yd^KpM5d zqFv+%?e4%N)PxnOS*dF;>SSP^f~!>&x-<|LptK$BHJI$y%fNa`&jO$#LquBHHJ>eZ zNEEeJ_D7R&u-oYL-W+E^ZNt2D8y(l17!7e_t6}93%)&H3w%@*p{v%+J;azqU=**zM z<Js>A4FoN;jkekzmc$~Ps8B#xWV0qD&Bb}_@8$xmL+L$Fq=nQN^s2q^KZ>kX6=F1D zg*47XSj?yvGpqXiSIkYvEb5r8#k3re$b2-2bTi7~%-W2-L^H_C_?=Jo8W-_fqDY2m zj_3;6Y8uWrMUuOwUc6*5NiZkyCk7Fdxf{P>5SeV=9{l22p<RjH@*4@ar1929VzBh? z-KLL^z4~aQ8I91|t?X)6Imqr-35fF=hIxjpwe*RfgyPCBez--s9zS*_H25==Szb>h zB~6xO(X}=G-tK)HQ$m<&sSPDn+0+Wvzv3fhf@Bvl`ha-EE4fbO%YNDX;cyb!|6%Z) zPlZuN*eCu*;s#{$VSP#d09}%AlpWmz?MCl75$OB^<E$*U=edn%$ld|3NBfvM31e?# z%RNiRXDI_aWBNsOG+CczhQ&FbwZV_Elgn8P$eru~1Lu8)6*_PX)1biv1vOpv5i+=R zb=F2ZJ6Y-IrwmK5wy-@1su{QODP8^<nLjYGpd%>mWoJ=%VljStHCX9m%*ws2(U)sM z&U2s^Ir=kDc%ANL=a4hb#~s)ar(Mr_W_`ZW4^lnAis-RV$*%*urM(XRBJG4nj&S!N zKMXDygM-0Y%*d{WFi)=7*<hoyKPB2hg`&k|&7chavoqx6pc4M!8PYRHg*`nXXPTn> zPi<$zr&looT%cB=7x%(2L`o$3hmIKi@3<IwQ06;A-X?$LEDf3Uln{QE%*st7?+p$M zm$y-GzQV?ue3k6WjqH`Z*}~C}q2johvfITV`qz)h;Brz#?*PN)#421)vNsdSkhor- z_)1ghQC1q=3<rEc-01+EF6?Tu14Q4|WH1>uBwy4*b`H^xI$~u()?q2)UT0iC2DYn< z`!u+&=;n4%g~-oHHX)nfh*oC9(~uPHdKs7Tb5~en@K11fNRrt6`$8diSsWqsFi{Te zpZ3>z47D~%-{O$aUj*EuZ*hje6QU=Iu>7zAfi^m$h-@C3!A~nBUk)A2tE?nuSTf&Q zK#arEqI@x@NV@29n-sfVCX<G1`20e$armwF6EC5UB#vfZA}dG4#4Szj$IVHkYEUbq zX*?3|2<eF?Qa_?+&|mN~P;j}4{4rwEz?I&d6Nzt$qJcK6-6#J^D|5s2b#oBdXSaNM z1`#Ru`J&44EeIGS&;ddX+>AInw25r8#`1p-BZsUzMEA&qk^6)13A@zUo<-#oN16E% zL&?NZuk!Q)xjkwa?;JvOc?mr<V5-c%2O%h*gn_Eqndi#A?ZF#@K3l?$!7x&ucl19R z%+Al}BL<U=`GaG!&_t<!F<u5b)2k4$Z?3n_lfUy*<G1_<-FXPId%W27@Ub(F?qiDp zVg2JgF^!Ij7lai{U-eOEJ#8WUJSiJ3j~?JFNfSzNXX2U<=24H0NH;{su7Pg^>x}4O zb7%VdcWu2t{En;~6O;Z7>eQp>JUXZVYwh)I@fv~oM$&45oi#}Fz9W5YDUxzfyfMXY z-;oKn7*lCaukmkyy5N$7P(m8hG+c~Xr0uBIDVf`Ws#vY$qDry*Zu5twQH5~u&I*5| z+Ljdb5|jbAmzx^$y=`I$yD*koN|TChbU+s}upm*iluRvnt_zdG!Wk#FBVomKTRgK& z@JdFy{Fjou1p|W_$4hTF2e`W|CH)K2MUTj{g(~>E+Y0kKS<tGx)#dRx`olXh!9+hI zK}CH~npu<_$ZC2bTgk+t*a2UTLc4JCpiP6$J&_iRljPz~9>%69!F_?lHBM-c1v}aL zvWFQAMq;Iz=g7xJ>BDQ;vP#iH+p=E&#=ESaBlT@aY{s<^SH;EoV!bfKIkEJFk8OJ! z8y)lw);Yy5kJ?5FYkFU>G`=+*@|17XH^Q182F1Iko7rT%YkJ=zu{Z);^TnJa7M_fl z9)f30Jex0f9eEI5Nz~WaaTS~3yuuOgMFWxb?X~y*Njz_T!2de8rh1E^o!{CasMfM= zm0u%b5M=3gm*3mTK!V?S#_tQ9;$-$aYy4)00}0&GS5#J$xg(7CTZ3b!X6UXDMSgh$ zP$GKoeLiS6+56s<o(p%fGq7qfS1|*J=yVHr5D;F9I{=^*Pz~6LGID5)RQ$!S*mwxT zl9n-(q*IWw(mpwu;h*P=;%eCnu$x1K{R$Jk?KC_}cCD;j_yhdBcAt|aV>9??PLO?L zC-XB-kf?D9?Z5j3f<oc5pAyr!UXw$R^-a3^l*e-jM_2jH>sTLVSRs~J+6=Of<Fz)9 zdT<n+V9ff<^CD@(Q=U?wH&>z<kt`O0y!tLVJ8p7^48e~=1k)K$^{0q&e2(UBeOtq8 zfqJ`Mikj|RNyVp*%g0&sT4&h22zvS{>-2i^@%Sww4Jj_x@d!|DDDKYB*-1_oFHZX6 zfUxb+$6!~zUzKtZ9-cVoCmxj$i~4#8d1gXNx7|Cyl-k+>`;Te(wI}YPvJS5u?1mI6 zChtzrr}{B%Z<sK)xE{Ajy0(*d%U^GMZz!<QW-|$z*i%(&hF2;=yy+m2BE+;D@izKC z!?9@!u}?4{W^aKZ^u;USl?Iy0w24WRBGG3N8wHk82t0+^#lK@6dw|}yg_>%;Tj(Ux zr(1~0=|8s60Uz7OHa2Ri^=+YCGYOm2g&$l?mQ=^5*Mh^lRo-EP^llY)oZ<M~<#HtK z5<6l&^ThPTcH*2gqU&8OsG@c}?vM7XFW_P!#B>z3zG`&OnVO#`Sw+0)JCZqB#$U-I zrIS<no!^qxlM_Yr$iB%^b2fyx*kmlKDik@A*}Jycj|r+W5XQr7%d^thL_xZc(;!!a zU%THIW7*DlR6>L+;%$;NB_;OPt!&v^{>QS-J4TA96!EJEki%1c;&=Ban@hU#mHkOw zi8Uq_mPmLgJDvs~)|R)tOK-gDdm<$yed>CASx`T<hbW9RPqjn`zJ-NA)Gf~wDXe?; zqvjxnlL6BP^h{!!;C!TTB7hPPT+!mam$Eck$g?L4ybqHPrs>lc!>%G2BRoqLDDE?> zb9f7uv$Y6umL6JvDTXjF5o(q~CfZ|3hCL=`C-W#<St#j$a>%-Tg+)SbR=u|tC-47k z<BUBvp_hemdD{S6*nhIEnV!-qjcL}K*ky`~h(*8x<bF&tr}yf+a1T>L-0<6Zvah*3 z5ig|)ai+Eq6APIL6c&ftwu!8sp3r_Anqfxdx1;3n^Z|TJKk|5b|ER$*s+G~M4u}&1 z^B$Rv2Z*ioY}7PtO>fZ<VBVr%_Y=*GdCIwnF1tR*4PRgH>`K4bFKByZ0<8w-eLbY_ z0L6pKL>L4d({5uLxjJKE65CKXdQetGg9VPt?ADu8p<5p36?WK_&rIne>^i*X-Teq` z0$tdV_nmv_p^r%I%oILQPOi@^4*Tb2-y$HI6GJmUBKgmD%UJy{j7A9Y#ZGlCJRj@q z<ZgIll+~lAxAcO_!bd+@ir^Y3b1v7s^K6hPd>f7i`24{q9cK}lM!_0V`&<m)_Z+$S z+{mcZC#9iFhhREhjxf@HRv$j_Lo$0-Jiok&teh3iKi5Rwos}TEPtMHRj#u1g%M!!W zpllFQn@`5=Bb&>T_`MmVwyclr=MP}Oa1!LObv|3|I|&rEZfCUqPrQZTNwyQ60=ifF z;%bsGdm>*|O%~6V@<aNP4`&xAc|8>N>y4s~W^=PIcVpW_kB6B__c`7911rh!ISPK2 zo4Dq@%#y&l{rd8dFSfI|G>ZB$QQ!AZ!d~Sa9r1|;o}DbX<0^Lx!UQ&H4S9a9Lg{sa zIu+PlH$q+4L-mh~Cpi6Yj?i%2pAEQ?bIypmo4o64JJ(<0IX!=W$CI+o`Wm@3H!5LD z6$X@2HSskIw+iVsWLG)xvjuRfiiA6Q@Zi)tQdly{5ua)WCl1^}NR)uyfD}MHAOau( z_`OEncH~4bPPd1(YzH_1%U>gp9aBPXuVe*(evke(tt7LYF;OijM2;1#;_#CK7`BpZ zb|&(-SCSLXG?v_SN>dpJdf$R%7oZw&2v7?+184;Nw33+S<wSTpc?5#rDhv&fwu)?+ zm)E=ey|%M587R(-@$AtGil^dW+dPrIp&M`nc>4QmB<A^#_?P#Qubz+T@e%e2dr1sk z8iosy+n9sAU3wGWig><b_xA_vxJB$Jbbb*cLDT2&O1rz9c_&YgIfUv0-3ys%ilpXU zPqgQ!okY7}ApgrwvSfi)@*zALuU6T1lG6)Ze7Bus=nL8qinG?|I=FX`)h`s`*lvDd zNK|Jy9sm6ZI=PAreNls3-_jRn@Z(RByDvuaJ5~_!OGAxem>afs0e!Pd*u?kfS|IN1 z)}pGCYZHpcdcXOqtY{m!@ct=g-bci%WYtR((e2%rEKzarBL2JEX>KxTVFG{SESa`2 zS@{yggP!u}v=vV}xZT#lxTXI~2RD|Jj~8Z@_kh&cnVBf0653fv!)U0GM$kYZji#Pg zz^A6IESZ-?TZA-)QXx&FSA?`TJujqE+9;$-dPYd&X|0fI=pi9B&}yWvQx;G8JPUnC zpk>iFg*1n*6VhR{N=U7=LP+!JLLn`rP9YsfpB2)Hv_wd!(D6cQr=x{*Ce0PnGMX)< z4r&zA`BWvOFVQ|o%h@0fEQT`CL`FWq+!GohpvxH=B%mu8`gj>*SjEua1(e+eC>7B4 z3~dt7O$_~7K({coK|r@N^q7F|V(2~rJyy=}9Rgm<(2W9milM6n^bA8Q1oSLJUjQnM zxsl~&3I&H4I!Qp!Gt?%aKQMHtfL>v!ML@4HR3)GkXgN(6@Y{@>D4;@ECqh757&S;h z?=kc-G}UvUm7%{2=p%+w0cD{!+9aTU4E<U_#SCo#DvVjea)*TiwyWvhigMOq1jDxp z<Y<Pj7tnZyRtYG=mv~bZ&=iI~FQ91*ohhKb89GTor3|$RsFI;W1ysXOi+~y!suEC( zXd>`*0ncLOL;=lVXarDU(8E|RKq#;>^dWYW=RiI~TLiR_p+5`gIEG#j(1{HFYAG4J zr0bB~pcDxomKbohun@!sFGZ~PxA-W_y%ee5-|nN#6DaePdeuyUVxv=*lG964%1vI@ zFui|{kF~d#5~24W=A*=VDbad=tB)e~QsVXg`98{hmoTg(y?>#P0yl~cG)3<}&PVy$ zOVQ~4%Y2mDv0jov@9*%D_IfE6d^qEyZ1PgF^!_jTD6e`cIeP!aKFWN7GH;k(wN#+k z=u{Uu^|D=J+5E&RUwe~iT<LuK%{5b89YlP<G2&QyuIrd3xC19{67Il%`|iMD$oedH z%|<f4B9-rQima-*#TUI-^U|_q?f8<E8oyV667df&lACTkI@QFjsB6c&6Ue2Nd-yk< zq-xdV9^tcn7u+AWTDVJZS-7w*7H%fs5a1M`J?MtFN$1tW2e>-GTlxy`(+$p!^ubEj zdk}VmyTSck^AO<*`Dmoa*$VfXg&$y>nH%H1Ou^j<vQnI}yH@uqv@@^g8tOAwa{LdK z<FCL|WRb;qx|&gwI6CiX>-Fw$Zf-?46}1RL__I(5f)LYve8b!L=-t;yuQlCyt^>(i z(<kKiYfpwp@4ZH<)+7Ymz$$z^V(35)tQitf4vtC<EfE-n7?Suk5<!MUb_IovA>e7r zyH#W^(ea~RCm)b5A|?5PB;qmS7jg%8lBTt3qVptRT_JuateeE2iY6!5_2OTTCU@2~ zf%e5ezQ^y**S`Yq^XsLZ*$V@U#I)O=_Or*Mzf}Htv+&*R@%0w)dDbW3{Vm~*9`Wp$ z@<rnM0<Dxbn?3upP=zX%lSyx+l;41zZr~7R;^-Zq7&5z_O57D1F!idC;+Gw_cpomN zBkgRNOT+BTne6`td)uA0##@)J7n)-Wie~<2*k^^0ZT1s3KXz#NF0I`H5cf$9>HMUO z9W5->le`QR@BMW~K->M*<DV7Y58sD}VdMkJn;WvzUWLK+&K0-U`hQ#La5}54h=wmC z?Kfui9lsYl_UM@q?^|bvjSgc3=#L}WMlHbWTK#QRhKemv6)N3J7H&*T5B0Km9AIzv zZ|r~KLiO+LH};UzU_TAAaL)q!5ic&ZzW2Y_H}4^#n^JgXI8kj<^C8>Gvzz*MOb=%_ z=C((qf)cW4(+GaYbn<x9WOz5vys75TxyXh$Rme0Vv&l}xo3Bc+2W$nHdJ&YI40}H( zUV}~K4y=q1z}IfgQ8e-8Co-ZvUMAJ=v%q8H`$NjTY%WOvZvM@Y^bJ@FpW18%ii_MC z58NVrKf$iKzKs@5D^SLiytIv7@KgUy^s#i3k7r;T552h<f$e{}&(!_p@0L_C36nQ= zM+WX<S~Xz_*}prTzf(be+#Q9;W$W(D&YPg@>`TxjG*Pd(=w2u;ZBO?tB?I@QDz~5v zZg8~y46FSHT6X1L6JlaNlm=55v)za?h?zD{!pQ=ftb)9?XHXZ)iWC<IRE~e-S|sM2 zarP~tc)}XU0-xJSyS*u0S-1BG;%k98L<U$tuG5xgmwVxPxAO`H@PUiu>{augPsrlE zQ4r(ndrR7n#kpLMKJLCu0zNo7(g5LaW0xL8Pq1xT*bvo=+O|z6`u)Nua%KY*4Aj#o zX*fO7R!qkOZAQ#~VhoX2r>0xbGUgTRHH<9o?dK}F#<><=;~X(`BADH|*DA$yz(N)Q z;*TsOZ&fELPHe=S@nGxD##79qU_?lx>H7i=PJb-y3EuqiK`27N2ms@@f!4`y)pCC2 zA<}){<WBcaqFFrVBW{8~p|~`NenK|wGxxahBAbO^{ayvirm`3oAP<j0kgoocqomZB zM`sZJ!|a6Zhdmzer((wuQow^y0nHE)$8b8~MN;x%QkR-KjB*=`{NNj=3zbr>iUseS zol5=a`a1IVhy6qw$+ZvD(k3D1P}Hv8O6{n?0w(&$jxl(?W-r*;zOn+^a~4t7^z3QJ z`axi!uH1VbTKEDRa5~0VK*bZ#iq_fc=)medC??Bl6nt?VIa<@7kF6t~nm$3l&4=fL z!XZTUQ6hA5^hc%T0}z|QmqWgwDc+I9boY3Wuzhk1nx&ABXdndnZx^;H7=iF1z>{xQ zEjBtI`pUxlU0jc^%=_F%?JQ4sqQ57fsIn*_{Raq7KhPbBTvQQ0khn@0{YOE@e3HLE zl^;Bxytuy$zwryQVShK#&*b?2w1k5<u#2;4x0CD}>(RGa^ao$B=do`~>Bbwx?|?jM z9L5LTpO2(6`w?W-nJ#$#$w26H&lB4L1@EH7eIO&z$Lj#E;^NI^5F`x(uS?_a45qi| zk@E*q`7PIp=Rmw@B8fj36HzsfwG_e_*8vqKLk1sA<W<*6>A}k(3!JQ6P@#BdjqT7# zQEZ&!i8pg%E^3@^hB%|y6;DIz4)=^a1jhxD8rq0L-)Fd=%q5<~36gg}DNSadgb$ue zdLGGTN9K_(I1twzNfP}+4jj>lO30lf-FoK;o5*o>Dh!(M2JCxY{MQC1t|!lnF?87+ zVmcbfPoG1^9?eSIQHrj8Z;2ZOyzMP<Cj0abvcp?qbTer<+L!Nii?kjc!e9B3WF1TA zH{K*=$MjhzaRm52ZRBlCc`*~b(k5a#5PM!zB1{d<u<wo}!WReBQpTdPf)VxxZOF}I z3%jrg(Y9)AkNU0bm#r(l)_e?Cnf>z;*T)0e?QXQx)Zrg^mGAn4;|>7M0KNsZ03HLv z?sHrUKnJh^<^YxgHUO#tX8~6M_W=Qaa$FQ34WI#70nY$_eaLZ_0F8hHfMcLF0<HjV z16u#&%DMKq0L263fGj{EzyVkT*a0{W_!jUO(BUuqyEuRx&>t`yFb+@(Z~#^SHUT~a zd<OUya1GD`cmN1MoFf{L22cV9KERDJAIMa|V!#GKHQ+Sh3ZMlLfRQHw(g12ef50ff z6o3P;3a}l(vFjWD)?#Lh09ye6{a2*0a7}{{D9W>NUmioODEviB8_(j;;1Vk>tGh-< zJ^4p~JPLCGhwcC_*Bm+Vc69&TlDTsyO)Kd?YkvOpXG>-|9R-*OH;HoqW^zefHa7?V z%>pEG)4AvHI}9aGV3Xk(m4IF|=6r@|H0yUXsFS#7P_G1h4%A8l*Bs<ndyG~lv^5#{ zT>O`WcIFDLP6OV9OGVAONOi~wIN9_42$FT7V@<~kecQ!{wOBY7!5fvAm6v$#kKK#z z8nP>9{8e;)V^JL$*Ob+Mu^w{5$6%}6tGh;#+NNl}XFR#kl+Z3T(L#<kb!oT0hd2E( z-JAZ>$D2;<E2R9}QnKMvY=FPq!o|qRkxL2fsK#6JjhQ?^NnZ<$k%hI%$M+|?%L$=h z53q1}MD(!v|2V)x%$H+A*JeMZZOOKf6HPIERt{?*uz4_w27BAA7(s4bPH0z<=gnTU zu^xH9$z;ftMA0->7P``DVGRp^W1VQ}QVhT21(FU17h~YRe^p4rb_=7uQX@3gci<6= zQ02+M&iDrSBp(cAdGa^tsL*WB-5*=H92QCN{gp9=Lm*>4w(pa_YS65t?#Ismzi;%h z{|`4h>GRV+!-_=%XU%zblEb$>3u+$y<QGs=cIySvhqu!FdpK5Exc>_vb^L^yy?1Qm z%ELq)=PwPGhD#Hr-KD*x7O7QQES(~qA)PNRmoAmQA$?bRO!`n7Da)5RWUt6RkR6u& zQ?_2-Di2bORcuo1RvcFRq`0H-C{)TJN}F<)@+IXO<p;{s$|fbJ@>lgx8B|58d8!H( zQGK8~tol}UL-knYr|zJRRrge9l&dZ3;p#l~PW2J>O?6&oab|huo0+wlF`6El;hJ*I za?MK3cFhURH=6d^46RA)(jL%0(uV4ibqZa+ZoY1_uD5=O-mago|3kmiu*Yz~@Uh{t zA>TO8ILr8gvD~=YxY4-9c+7a(_=E9=QDl;sB1|c!bd%oXFfB4|H<iC{`owhB^rvaF zdAs?58TN%UK&hotjWkzUC|w{+mXDMd$fwFH6rD4F&ip&mslBPK)QvQ}U|3{)Yz#1U zHg!W|>rAW?$FaznLHd#OdnuK+NdJ}w$s%QOvOY4E%mUf1ko`k;Lslf8ATN>6kk6Js zFJDwHuaK{h6Zr=DR{1V@wfvC0R(@9gFZl)e75Ods@AAj;_KHwNq9R3+u8=AQDsmP1 ziZKd@!lhUx2){;gQt>7Gx?9mvnW$7MP0A_C*Ofc40N*HiRY%pAYA!P|)0DY2^Hk>b z%)6OAG?|)7nmLf{GR;3UyENr{G=FPCwRg0CX#;dwx}my4U9oPX?x601?iXEGy-B}D zKhxkatT5~}JT{~nWk!Q(x~a_cf@y_mn`xivpy`6?N7DmS2XlnEi&<*UH?K8QGiSkh z2}y{dRfDA?r1{ckq|>A`rL(0=q}9>`(&JKpS$kQQY_QB)E*mWyCz~XjC2N#@FS{(8 zCZ7k1tdXymACw=Le<p8~{~*6AZ<gPcKad9~B#H<{tfIT3w?eBJpct&kQ#ci`DykJN ziu;NrWp`z7Wq;)u<znRnWfv&k1l2TEwd#QCtm>bt?^Tyo*HyPwzpMUIiPU0sh&oc8 zpiWnp_f;#^I<-lir5>yvq0U!NRxePOt6x#CP_I?Lq28+Aq28lDrmj;rs2kNS>ig;r znX*hxrX{mFbARUX%r7!qGXKbYkl9gFqAAt5HLEoHHAgjd8oTycZMpVM?LO^6ZBLy+ zH(a+)w+B-F8gjj&`&E~$@2k(!JN0YI^_TP#gUZm)@QR_z@VcS5ak_D_vBe}Z>&-dl zQRa!}>E^lSo#qeC$ISmSUpD_{hN4+HoR{#0prS8J*Fl)cvKg`qvcF`{$zPCH$={M6 zk)MR@euT`TpgXCG4243`Uol;=MzKwCP|;2~O1VM#t8yP?QeL2*t$ta3R9&aJrCFxE zqPwB{0|R>7@QtAms~T-SYrbgaCgLCQqr*|s2~wrZB)cSwmk-B6H7c~q3Ca@XO657_ zMP-XJQ`Jv3Q?*p}w(7L%zDlfCtBceV)LS6IFVr{GF`4}`$7r&(<F!k)uNuBI2APMM z=a-u|uo+=G^O3k@zbbyiT0T%bR`ALIWqW0v@|yCFGF&wY|GZ^uW=&?YW`gE9%|6XB z&1ubdnyZ?}8lBdzeMkF&wn5vXP1X(3rRsa>ml{?ZHW-==w+$)A48amCHLimlm}s7D zUSKXaFEzhvzHfeH<`$Q;|M>yDHQ2os()H5a(yydH2z$3x>gU_H6J^t7PT6kRep#LD zfvlZ8R6a~TT0RM)-YDNL|6G1v-UJ0bh}plb+OIkXHTz2ytRAYKp|)tB(Qee9)Lzxz z*0$57VRyCaUef=l|3zP7C^sxO95J*nHyVuj#<9l9M!RvQvCQ~}@r1F-c+E(Sw~Z~v zd&XAdBO_-TVzQd@O@*d$rjw>GOw@G8bkEdkdSvQi9)$TU#(b8WSD05}^Q|{;GG8~} zHn*7XnOm7;SHa^%VwXNAjgV!^`pa@;g|hLo=VbF_FUgk4%9%~tB-;VIenfUcc1HHK ztVtFvmt&5NitiLn3K6XOPs$oqAGH+*`kd}M=FnarukWwV*H4AneO13nzgJ(Y|5|@d ze_t;)#2Q9oaN%YR2J(^lf|=Wb=U5EjH~CG)3#yM*H&yM`zhoBa#_J~ON_5l9b<gT% z>zukfx<|T5y+S`r|GGZiP>Fpo45p^Ublk*M!`DRvy`=%NZ)Jh<F7jgeLV2uW7_8uL z3Y&6)k|;k?eydDW*;V1{F4(GlGe>LengyE8n(sBYHGbL@?ep5Vw1>3kv?5)GPOF=S z{ub$u>l$?ueYp%aZmNF0ehW6@*M{#5KN^CKy^NELGmH<7$tIg=swvH!Vb+-km~G~D z=B?&xY($Kvmg91eOoJ`^M#{^2$o`N$#NbSFo7|!pq^MVXrbxv$+oGJVTAaBVR^so> zc#Tr4*Ouw#>0Z<=(XG*at3v}3joyZ4%F1xO&c~W8m#uhxcAhA6j0DBI(I3|Wp8|M} z)Gl2v-6cH({S?bmWNBDRyKE^c?83U8leNemVda!^jl57k9|rUgG_zIir$|y*6cZJT W6<hGnR<0;+E5yo!e7@*<;Qs*}Q%$@8 delta 17252 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/w64.exe b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/w64.exe index 63ce483d1e462373fe16015c70ec52bbbd816c11..46139dbf9400b7bc0b64e6756ce17b4eb5fd7436 100644 GIT binary patch delta 25576 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 Ai~s-t delta 25342 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≥?Q>KVWeGOAcjD;Wv1MXJ z4$`nlB_@=tGGtSiD=gpLJ773Zy+FDBQ3k3VEFKd?r6(iVZuel_ckG<|xcndWl+#r4 zmm&j!B;z|Lpi$rciPja*4v$O2DH)w+GhBs4nph!-7qKAHu+c@P6;BB_OQ|l%i6v45 z-LA$OjFeu(MvfKw{5Nfyu?_9i5KJ(<;;G|uTMI{zx=(v_RCbkf`9CX!qbJ?#2m7$E zTX#3Og<*f;ydf;D4`p)eh|KUdR70&$oD!Z+x?+${g_4XfWE#G~+UT4cD(zQTlnuR6 zmu(ta*Bhmkl*E=dw80tPk48W_2=50_kxkf`q{RWO(4(u{Aml$p*^7OpD<Q1HBb@gO zW%V9C122=(?!SNxFac-}i2?_Eq-+{{f%W!`$lP&W*^v%lez^Kg;S^EnHK@G0I%zoV zOw!lwlw9bDv``^WORbcSot7qO@gW-igfh@HoGa#W^<Rdwqn-u%eP6;ni&rha*oS+9 zmcH*u>R@pslcy~)^kATM?_VS^%mPTuu(4yn#v=ZC6yjs?N3aFGpok<U0UF!{(T+OC z%Qe_c9EF4%^Y01P#B1rO&e8@MFMyKfc&W7+VOhkUOtz)-ScmECl2@-0&oFQ$*2Grf zI!<RS)FE4?{*N$3Fd8Y#BW{B%x@Ii8L^C5A;!v7w+EPQ2Mw-!RRBkNXs-}7<sf9Ic zvZ;OYfd~l2JLK{WzX}P@=1&wvqijl1a@I;4D6!Z<hB6w;hf<jx)D*<GD{=oCR&DA! zt{qLB&EN=-_Wz@tkKroIM67LKmGmq6#bQ*ZOsX?;9HO~xEA=-+)lR4hl}Jd2npZ%% zfwJkVvn<2=Wv2n1FfFI0x(@7!ciXUnXdOqk0f$or1Mefb1XE9IWz)*DkgJmR1~CVp z;5G}8i&Ppi0r4r}Nfwh-MRp-3!bLg~#8Q0P@u?APj!$r(^T9gK;w=_bVTg+K%pa@A zQL2lBaIqb%i#PnR6~w>jXbBL+7v06>ikM+Gi8)F2UD!#VnT9hkgtR3!HjpLxzTz<e z`HlOHbkv%S`)j41aje33V(`q)$hK%OTCrFtI+^P)oxwV3&Kbax{8;|#PN)xQW~ogF z9CYX&Cw&RMJs=Y`jtm9SFdITRTWBQipQfHRQcpX^>+_Ldfy$kh{=#^o9z(+p>3e^w zgx0Kdu7woD6Ad2HIY>zdTbQxs?7M1rHrYR^`+R4#Blb9~Dz0Db!@(lX&p!n5DmBep zN=A<6#eBvOt8yN+QR>o*UGeYYzbPIYSymky^n&yo5)YvtwCaEIW9EQFeybmw7|@Sj z7tcNli04E6*v){bpmi88wAKTi62$MQ{db%&pS2CHWTdwb{6g28T?<S#T=!`iuNgk9 zYtV~)Sv*@9^oCAge+SL?{0z6Ne&UHV(Gs4WDt-rj$Y;xfgLx@|Z3-UXK(iuwd$YU2 zxq+v9f_~rBQd~Qb4PB__dIMY9#>`K2WB+M0htKw5Zss=px#O&hIoj}nS4)P@UTn7c zgx^`u7S1@3)+)JvEDgq4HYmhjcaBX93FEhRWn#!+KGKtYAM%pUiFFK()m>(pp;7z? z(aaV)Dn7`grI1fsD}^-pOS55-mr#QoU>2%->3y(hgvN)*(dIR=f^CoJ>-H(unD~z! zE)l1tPy4Z^h*-B*ljvBhRED59g~hkso!u%K%@V|*RbH4_@xHOpifMsimK!U?2h9Z2 zk}E|GB(>LXLrl6Y(3HIDBzY@D?r7v4PI+O=4HAkTTKbb=^uquu6dSz@G{X`rof*Jh zYUj(h8Ng<>dr5blecdkI(+HU~9Hs|()R-z(OUv#vb7UV~FE%mqa=`4qRKjVoN#dz? z^kG7xvXr}|vZ3uweADl2TKjjyH{b@Ad}#1kh}aTWogtelKIko=#Xk00Lsub7|J500 z?$9ki4~r4H7ivwM)EXO1u3icS=KumHl|dcVg*2f-mL)%&N2+KKP4p4g;{kUPwY7-G zlIZtPyb@_!Z)HrJ4?v8Q7XC)IfA!aBQn5ZL5o0C{<@!_PsyiYnxL9KVoz?wqAcUo^ zgESVDo0EEirC74km#6~j?*N4jB{|zb<`>l_wnn0f$0lyZG*RN-dq_NiKMnq3ll5@; zZWM#<3Mn6gSuGv9$7V$Z^VXqEj0$Xf6s?d=VbnfRzY{&A^B@B!3~fu9%B4-3vxA+9 z>cY=<XV0Si@&k5Y5rhh2Vfb<sjE=-nE}Is$mg7pVKaNsSUa(T0ewC48h2bTtd<haO z_0zy~vggVx^_ifcc9fyh6Dl!<t}OcY8l5AXIv>X7ps#`40Ub1fliChd%}_Ta;9!}K zdB;`e5LQLvr;y@uoz*dWhT+9QfP{lomtruSI>c%_9_TRyW-4b1M(%!~BwuBkEp7+Z zmYhMQV2gw7la=dbs(3lo?i}uim7UtRk`AH?j6Ljh-*~=><0@3+Le&2f#~yYL$v+Ci zQ0h2X8Jl+^(RHX#xGmigYFiw%jS`J&VxE@hP=>9NYgib25~f2IN)(E{bb|HUXu*2a zQIJntoG=`NAl&e)GBKuckm+X=>{7+5G@GewTOC$Rxp1^eZ@t+jmA%^~A<>HEQIJ^W zLVeUr|4@CR;X*q!2KVIpIrUHkwbis;+YDv6R0s)I=l2n8`rc2NTXcumOl%{@gR^{% ziUm}G`x=@9TS$;2Y-KR1nzMgz{o8A)r}e12)S1nS_V*n}iMSftOzo9IPtEU+LO*-V zHb!^saLy6+SdT`d5HHA4R)g{2d|xB-*YBZ3+dxWuw4ePM9mWUy@Ad7vUgtgsvdLw3 zijG{A7L8yPF<nP>Q<$)v(Y4dk`&b4TXS%658xQ{O(J%xp2vI~(tRk}LxrjSNS~o;N z#9I+@&_qT^Y+&pQ?yn7}C1@<VicM42e_&wm#g1sR0~e=~SQ$pQIU(`KSRH4y-KA_< zk1#vC!kBBf$gm}74w+K4<^<7{3%g4Yz5am7(h4R^ni!N7#zuGRU>u<Ah*fYXA#aB; zR?^KoY2ZG}n;VRYa!~TQ{w;0!MalIDR#2)n{0Y|(4*7b-1ktsL22wWJAsY(56v}?> z786u}3!Ok0gz@1?0!}yqa~3_Z0ylMo!IgFI9u_P70SWSi6xBgCS!@#j5U*PQmZ2tt z`(sL`gy&!u(!wpV7m~}?q92%7v3sCj`@K}phmO!F+8UCuM?)E<#UHTp?s0st57^`G z-Fp@9p>-)X$)-i1s2D*uO#z9HxfjW~uGS|qcCgb@HV$Dyv{4g;*lOwM4{Sz{?miv9 zz(Vy=7b+<#G~su!*eh>&vh)IbA3?0g=*)%Hkt|+Kr4!{3*|h2l_H&PHzS9FXxTi3! z9j1~NoD-Dpg}<<>>;-GNI~7);+>0Fkl^)id?xmz_%lNAFGiJKE4Ecdph8L`pQ%Jyq zyZwMY>Di98jSJ-;Z(;-ECi6)T*seIUaT!KOu(?(V#juk7cC#PiMh`0c69*MkBuXf{ zX9=*r=BTrn1QGko{?BO$&PXnG<c|o$x~Om$<g>Y#a5)f>Ne~A$(Rt}&P0;1Gl1*=Y z&hq2ix%a0eyOU6WDhyBD=j^Na(Dnh?QaM<<J7K`th6G6|SiI^PcIO%ygHHrI8JGKe ze=uDyFSq^4RJvmL8l|}`tXBt*k9R3^gb{`*aRUcP44c@?<bL-@SmqdVcT_5yX6|Bz zy*j4%CJnN?CRlslz$H@p3zi24+|eeqmgYbnExSSbr)(D!(MEfet&IIRMLCz((BeSH z?B(+foHR3SO@ir#+n<3~tk0wYq`9IUq}VWqqQ!=>DvVQMJU~eo4XMPDBSJr8BNB!u z)x-ay*~tq*HYBClBF;NNLNuHL)UQCjV4YQ2m4F7^<0HOO<DWaQ+X-#?ah1&2JF!Qc z%IpeIT$@<+nX<`aC#?Y~)%uSv*CDpN{wYcvTy!tjIoUSYPFiuDz0vz+x1}dA;pdBS z@fG#CC)mB-VSL&N=8?FxeNZd39R2w(*u0NkMKfI?Ae)YS%E}TW%x!Sa(lFpQFB<yZ zr`=Mv7~oj|-)e}y&;Cga<(D2~A$_{=z3;POefshlkJ-C@dgZ5mf)*G?HR3N;VvkQT zwCZdNHbHl=3Ko_$2Iqsyw8V;rD2T!zjSecZr(tGz!%N<XnUzi6#IwR%S8UhdAa(m5 z-q34w_j-t0w5>*+YV919*w7c;`Kwpiq!*&{FI^>t7$neq>!lNFEJKZzsj+M|_Nf}n zQDYm_Se_bNsl>zrO>y+nQkAip7&iTmZvhEas9-Ai-x$Efj{6S0s>~(HzxDLrsiA35 zNXWF3I$mWxk~+G)-GrmjAGt#wu{lX$`8BoF(iWq+*<&#EG8V%xa9d$aGI3IVp^QoX zb}~q2{Dzrmk}ZNVrmDq}n?RM(+Ol*N4Fe#d3~Xm)04o@dWUMe(I#*0F;AsO}rentB z@IXH$a~1N-rmsInYO($Z4tK!kZQ0P|9_D$M)b+RsT-kK<BT~mYD9%JBe*Po&VRBnO zB9)y<4&`t5V)v8%h2y<Y4yx`g9F^?^TOc+~culS$D~i1yL8il5*>qZoBb~gmN7Tgq zO5%?VeC##p^NVbF-~LWJDv`~WxUG_X-?xjCRgEoCV(zgx4Zp#@gATjMrduB}zZbvY zFYIO2FDCF2yO~o;KYrBDEIp-d{*MD`+~BCl#ja%=Vkeye16zo}n&|v9M;?svNO)bQ z<z*}+`wI^pLU6ZDKI{b}0KT^=I2EvW!sjPl{uv5+l1^*fJCN3?0|_dQ%4x;jBj5{x z?IxR?w}NY15`Md=+%vZWiueO(wEEO!ElOaS{k+1m@53yj=O|Cwqj<Sour~ExIDi;; zz(Aglce5Az1@V!oY(hWpe0LHDcRWf;6)(|Vo+~IFNrsP3<7BBED4I#ahM!#KZl)dS zjMTS3uEZarhy7wt;vl6*67($0EFEY>vHzX9?cYpQ&TTdEwC4t<Elk%xsgnzi)ij*C z(aI4`K0?@qRH|%}w$PBR2v5TDrz5xg44d1(W57YQ4|8GhIY8!>v_oxfkTp@NV_){~ z8IwcViuF1>v>IB}9*<nW>D_99Kh&;)hl>HvZ=#bAU~5;LF40?9@PHUy5_@Str2lJ3 zhvAD0yKIs-qaaLjCu`y=UdPyge17q5<|RxD>T-ixL>5VoazNY{Q|+n!c+PNXGg~9r z`1nCAB()RokqYo+S*d3J2Z0r(ZsGN(So?w9`3ZMe=D@D;QT15Ted+EQ&?vj)dSh`* zzo6{qwXc^xJ4=gP&qGiseha1_67>%xc4}ZKpLUl0HZU~!5=5*Kx1J%*`s7(|M5X>a z&`>QbIAIg(JSaGLXA8r76Rd+v)+bMMy#x_guu6T&Gd6QjJda!Lhl4us|J-Kh2c`H- z-$-g<Ec}%!BzF((pS?D+j%nw4`6-jr+VdNJWgP}r@GqQTzYm_u=XGMEhJ^6_;@PW1 z!t;Nx!-GZH2@YFvCAB#<p&EPLXLw*E6mKF%qipx^%_<PQvFI`2p}yf3t)rrQh#XP& z!?V%>+#gHC7wwDnVNam?FFF?MgB8NHSno%~73lKX?Xp~q23jBMmzspEQ^x%%gIM6u z5pB{ikd3k<wZV`CT5ZGkC#elVU4CJ!hI)J6#zdwjT({6oN7{uX=_)H5+QSs&i{Z=l zIzYRg<b(~hQt#l)?9#{ZQ+{C+(l_uYer8Y8r}6>yEbFBX!o^COBry`1r1b-6ibN`a zjskCMJeeF{{7b^1N{|60z4tG^t&&}SDKvkE$`X+LO#wzjh&m^YRC(!CD5Cw<Xf&13 zOQka?$);cT699*Xzx6;SI8^oOzF>(W2}lMKw!M~dq!krx)4xpO@dFwy9&nRVbDgaY zXs=$nb%HG&=F6Wx!Age(^E*zk{lk*^wZE{(!=m{$H(AHwUHMhF*u>#M{Ndwl+3;9C z_5|BId;q`jEPFcqQ`b8`wHP*w*q#xO4ZqyPwZPV2hx2H)zz&RTZ{7utH7?Xx^cI>T zZAPrvw_%x73Ialc!1z&dFN{)!a$}`5P$|XchW7A1M4oWK4)82DNa_J@C0;XtPP<6$ zl?XZGrLSP2!e_<IRv%U}%F6qF%}k?b^LA^Pb@ZXuGu@y&gM5Xo#)n7WfDPK04b2G9 zwPmw1`gZL39qPB1<K(TixJm8RSSDh*F7OMzJXYB)6?OS%47-}qmA{k0T*riWT7j(} zcUij93bRgT2zIXDHaMUo$LgTm$&O}=PwWNpEFQ=5(#Ul7@|Z||UdG<H#&prKwqc$9 zYN28RZX3SRmg_Ae*99b-6Sgqq6Wqk;)D98Eel_yo+C2N^z76j5%r*9;v;v9DKKxz7 zG}z7B5N{pNJ`Qgm77dOv#AHWGp@<dx))x@%4H}IbJ)Zp;9-nv#782xgyGf@&(I|Jo zD7VK$xi0E3?*+SMm_Je?$}q=*WHTbn>}srm9USXy$b6o5?<zY#wkMxCk~xo?!vFM$ z<%|pE-LA8><2Jc?!05rfG)}6oWr^ecOus$Ev1wfgrG(EnO>Dw*qsnz`*7y!ipTow1 z-11tsY5dGy8G$$~RIhM=WJHqY{|#42NA#?|PLH`AEW}>GQ0t@xsdTy+8cSK<mw)D; zENAT|g!8xFWrHUi4)j^B%%!tz+W4kIO^aW8-7*PVis4-rF)`J*57ueH(hO&C_P+y< zoUy?H<j!~4n-fcTx68~oa}giZpRLYp+u>#*IVS6HSeRtfT}0r!dJmS5^|V}n3JWix zLVURn>+Pkr>}KZi@Wn++g>G>4K$a|lchPoKZ!ENdKrPvfotl&rIzI*1OR`YFy0Zq} z!T6E27VievX5M#e*!amqvIg!$RZpHJ8&j@}6%Au#(_e4U8L7_=kS1QBQF1~Nl0_jg zK3sh=Ha2V1oLqbHM#GnA>#Inr?+7LydHG9&5W}E{KhOHbd1lB;PJDQtOle#z&wx-% ztv`bDVy_jQG%m-H!6hVKfbD9ut_GbZ-cA!Ar5=5zPqQUf{?5d#4nC`p5&5%~{G>w- zqha`-Vbxio-FmbXDh*P^FnUN#$i#3~pjniTyvFBZ8){hSlt{z(HPjkKBd6D}(Np5w z-T|lClOIyUHcs&g+F(Xyr_;o5aZM=sgO=Mv%W)y$$pTktWDPq%rEh%D>lo||w8=KJ z3g*rcFS2wV!Wbqaz>!?wvv_D|vEGYpWIgACcAY6UJif=$rgq^k-(yRs`tZB&v3I8? zbbJfvm{OL2l6aIvrbxDE8V9~$TTXfL9Lnx;u_^T)`)6v3haDwYD;*OqE?M5tN(}n* zE*m~A%6(4(>4&ACko7xlCU@D&X`T7%e0F477(eeW`*~WNpKTd(;z0)O5QC{2L9v&g z<+E<nyYLbDZ0ht_$DIvi4ZNMtHc#(k=s%9?YLau^rGzuAVY+{(*nIS*iC8eEH!a0T z@v-G7$_cvhBD~QJ)i@yO>SQyS8(2*CkeFlD&>%A>Z2)STunI$0bTV&2LgL4FIBvl# zLA;SB{+@dDAIyLE&3D+`!~VKzb|yQdM~{|F(jc`Qb*g)zVVLRwsk>IX;kn@Zr&--$ zUsj$QZLE2W=@W;$)1!bY$&JamIZiKuhsd(=EN@}AFh`g~C9&6%t><LCU}H`Q>Irkf zXv1LQ8P3nJpd1?5xrN@&Vuf-$(ciwqeqY!(cq`gHQ1to<#=t(L$QAWD_^V!%rdP9} zizXW$!AQ__t?(o}vM7uX*vWogG|Ocf+73NwC%tr%jmaDDmwyeXFWm<5JnVK=OD0Pd zJDazK53FYMUk&Hq%wy|b?d~x&PnqRj<bFzmewL19H(u?*XMMta7Dw>wPP0CX1vl^0 zm^IAFVLY+udz!6XoWS4Q&(1IQ53N5%8gN=Ff+>_%9PvG(X~pd-^?JB7$q2ynFZCd_ zXOXYDdrvtID;!4Ac*seyYM%5{Y{+Y7enKA0d99yk8>}U~SORMt-a51mGtYL<2=Z6n zdK0q##;PnE4mPRW7>wqXpPBrcIlUM>Ww3A^l$MY{LWLz5!Z}3KB`#p0GDz5S>vJ*H zwRBTM`nF-TTiif>!qLC=$=09o1lctGXEtw%4?p=hTfU@oz6Tmj`gZ47i@ssGlD<t% z2>R<M=-bQWG!p+5l>H{+H?XX?+X%Ddj8xJ7f$>OMoTK%o&e9X(<d5c*5cgq99GqJ& zU{&G(7MmK}q_<njhwdQZUC4@+4L$+VYNSvLX0%914=Y$wr5DRw>d!y>kS$sI5+7B` z&LQ@*g*7Y<<4>L1>%Qz;ozF1%pI}sl;dI30g_AeRraxTB>hs(4?`JTtg1(*3z+FNz zn-o7m(DdV&HtbQ?asz1N*@wj5iFn$Mr(~z4pP02E-2c`w6a#%IN0ELIFG%1l>6E;U z9WCgjo5_AJ@C!UfLf~a@LDklXeTZV(+Tm%&uZ=AH_0HY{zfqMT1}T!CDiv{zWxt-! zA0Nf)U%v)>g`Idq?0Es39yM?)nMAh4Uuv4~thfb=S5D}^JCAhPG(Lwa3@V~6vN*Br zw`{q!*lpHP2+OBq%ke(fxTCC1VK@HOd2D3iNIqsB+gTVN`Dm`97kKINtn}6<Sxyxn zD9Tp}K0VS!0#xz9TxKZh$Xj=^grcAqXT!DCu#lDve9EPYAY6E|sSsp}SeqJqO*Ylc zc}`Cu5lF{1Ck~p+))z&EKHPyjz@v+4#X%21seWkXDP*-Z;^tL!s)Csp`$n6^#ME<` zlzVu}m~5@aM4pv;Z>9+)*GX<<k!%SkC+T%mDJBM=W6^I;kNkvgJgPv4c>Tv`Ic{Mn z^<*Tq%l01$H`tVfpjBttH*b#VwEZQjUMZ~$j6n->gs3^-?l?D_a%|FaIGttv-pcIs z`~S?b_KZ>oa`gQ#IhLGZ7v6dyf9qjvc(#dl>aKVhx5}kcg{(iZhCe}9;UH~Pl*qO5 zVY08);x3KeL56~CX(d;}p%`v`;<cnJgqM)8=-Q|{^uL-(F~f9~d0*n!E6)H%BaUYP ze{ym~!zy(X<--rLHOnphvf<3JIK_8K85tT@7g-txs`<eFaX*_<e1~s)h^4<hB24HH z$CVu&O(Bx+{$}~#zM^fw7qcV%{1vNwyF2ebgFSnDxc8xKw57OTopQeQ60+$1u6dW( zE-|3vo@tnwDrq9JO8)pG#?`O4r<P-5@<uky;vh9cq>>?cmXZN`nKz^bad4e%DgX<M z@)N1zOLkj~a82rq0+dRQTx7m0CK*rPMicv0QG5NQzF)HCE86krudy#yczKQ<Oh%b( zIVQR&?h|S5?Y*@toOPXtM4%9?<m%>xL}EbHSh$+@B^Q|bRqE3uY5w=jePthh>|U0> z(rmtTOPL;Hp$T#+%jaa&uf&iv7xUFER<g34_p9Mb@y5bGmBQ4zr?4|CJL){y<CXjP zU6a}FRUJ*yQ`A~>yUV7u$;w#${RO+fDuln&hk2Fs<X_s&2A71p_59-bTvhC5`6YAw zB<LyKe(2^S+J9Rx#nJJZXq1k=!1SvNeJ<|B@S%Us2NWCa5~2_FKkQ+fSDW0{e})5A zapX*0Ez5gPuO4pKYt7D<<FXA%0Xv}LVowu~Ld|Mnal$F7K5V%-L2)@B;L+`RekIFz z=R*Gb>(LML&ZLA3$)c1d{*fluOZ(93*lTzx!1Eg<<BhhW%g6(xYU?7}x6X_wF1>JK zEMzz|aR4nwf}$KJakMK5iz$KBWfe)=OoAeD7AD~lG)gvYCc%6Xn5PQ3w+MWs2o#V2 zr4LopYj7T7BS8TxmGsQ!^e#wG!(LFVFG2zhUMT7-R>fsgT(g`5l~b(GfDmqkqJHQR zE=GAfOWz+XJY^d|*%K-)lhYDzSa3w5?ldK{p%bNujk2ltI5xI4)o}D{l00YWCYyd8 z%XXJ~wcD<7JY~~yTzsh&bo0e4Uuc<VcooUAX~$UBP#Vg=@Fp{^>*|*C$#dO!x}6PK zC-DBCuyyMOxt)Qb(Y(UPY-jh^<?#cyvsv$jgl5o29wO?~fyIV_6!Vmf5ZCOi4Ii^z z?{(zwl(OsZ<?%J6*{Ju^0tb>OBdSh-gEWaY%bk@D)zwPQ4I(@8J{%IG*`M!6@GCNy z|N8!XN(P&}zBfPQ1lznmkl*k&JF>nTzh^Xiu)a^XJ)@!Pjc_D4z8?R>56U5z@D@t9 z4Smk&0ET!1dw`=5dq$F8XA?GcWNS8f@R@J1k2b91-(1U*HpcNgN3g{k2LwjJL{J(> z&y?WY`=ZiLYuwW1?1zmV_{+zc)24u4+z8rrEGE3kpP2%`r+86$N9+}_@u=|M4T>p3 z{W$ywL$l9Fjrpj*51(DcHf^%x&n-l4;vjcvs!I4u<5j{e4OfXsX`o6(OUVl1BE_qW zBq>@Y1gV`$q)Wjnks+B>B2#iziEPPECE}#VR;A7y>Ap2zq4Fe2VTlD;Rnm2p#toa3 zYE-&}=wm9qj_5L#-c0mPmEKPDW|fAEnv>S5bQ#ghRl1z$B`RG-bbgK+fkDDaQ&hT^ z=nR#vBRWl`C8Cp5x{>H^D&0hMq)L;?ECs4Gp4M@ayGkqmI(wBS@1E532K8LbH&f)U z8c|$;bt<j6=Ps#q9LZFvbP~~rRhqnf(r%R|@1C?xrE`d0r_y;uuTbd%q6<`dInkCk zl<^l!D3YxvtRs57N@o+DuF~6yPEqOIM8~Og8POe8x}0dUN>>r>rP4J-JF4_%qMyF5 z^uAVytE1GYM(QZx7nPQXu2tzqqN`Q9iRf~b=CEx``&8PI=<O=)PV@$q_9ePRrOiYa zs&pjLd7$$#2hkLnttP|~ovG6F=s+5w(gM+fN~aUuTctCIj#lYRqQg}>n`mE^&LP@W zrSpi!vmToJ0?_%=g90V8oDw9JE+P85O0OfjMx{3seN3gd6J4g#yNTYZ(q%+%CYs(} z!GmLR%uZ8Y2c~ylL?^rsz3~I(HJQbb!V7DI@B*%ZsjO_JkU{R?6sw$3DklS+Z&Xf- z%7I(c@TJO$DPZYa&G{*6%t=i*BfXc(d8DrLNN}Q6&MlP#N2#H$%DJd=;=l=1IY(7a z5;z_z=W~@Kfa9ogHmaO#aJ=(XmZ-9Fz;abNud19paCnt7UEwIZ4VZszR)%Ak%A{=v zOi5)Xs>~9Vc}-<T5>p#q?Rho^na$m1bc@~i{Gj?~0~5DJ@sBs`E!*}5&tE*ach<*Y zI=)9SE7|^HSl8EJN!G5D<$kb7iu-M*>sm*t5)AF+8nKQ&+}=KFV+Ou@DEg2ZfUDSg zI=O77ruT6tN;qMOgp1V@mX=ixKcyvu4g4g8e<_2_`6Slh{=A@#rR=j$7PZ;!s)Lzj zY`_O1r-ZDdcyXgVHLF~(tLkt3s?e#1z4+<hy!-pC&yK<T$@iFTM^FB63_G#o1Yf>x z@5-I$bh=e+!mbeBAhOqYdGcHedv{lo<Jq_A7%zK~{kY55@gpU&?!~>&cIkEe(#}l3 z`(6Ile7147nU~YqH@g$~VRQCA-QA8i*jBdm(|;w4-WzThABY~3<=a|%X(gMqw@p+^ z5{~qg@Hk?^iukOLa^8_wX%uod;O3}#m11|Y9eW4I)Y{ZL_HLl&Ra%2#!!3VdLgFD@ z&lb%6FJ7g6JK$CFW=Z?(`MLnse_u#kYD-ROf?AlM`j*nDad0jLO8vD;f}e}-Si%0Y zucxc`XP6oo6?idj3HxbZr}jrz$Z|-W^gckF(sm%}Mt-yvnO9HJ#Gi4M|L9W|_hnX6 z@~7lJvad^inBw4AU@Y8A3wa+?>`pvG8!w2<%Sj1rdLKx}kMSBPy4IzNu14e93fVNg z54-lIA0OR^J^V77|LPMK`PGqL&wA4ZwvMdQAv)>+K4uc|#*>*!xr+0W-m0PJry2B= zE|Utw=L)i^e{W{q-;*!e&c^JA{hq*<?4Q6NY|E}AR@#=y`y=@;KW6RABKY6pS$dg? zU-U7XUiK#c`$z2jfl%k+y=bD0g<WL!&jEkd{lNRYK}q3XiD!QuILn8`v*QP&V(xBJ zS^%>gpTto!;Cpm+Oo=)no5sW`bM0b>SGrOXp5>P{ILfBLo-FiGcmFYOHcziK7bKoa zl>IH^{em++*eizu`71ryszat;X-KNiLjska4okhAQk(rzWqgw?F3AN;Ie%ke3`C?G zFpw%a%rPfDC}KYz3gCxNW={?!$E-zy)r`|Y5g<o+{c}g<qOJeKQJJ%q9F_bAPxkg< zbB|UnxugKKAXS^3;nGz+m3poCA7B}2e)gG#@Kl=J#^Wl6{rUjsjyBz3ZeI)Lu`NOk zeWBBx6Aal~(15l=7QIKAy@f6Ox=nsSi;%P()<$f(a`#cbT=Nz1X^nZ*=;RT2$0iAC zYG*+m>QyKDVP9Xc9vk=HHx?Bsx^haoy@&RiPAP9fS#1&buyxV}v^%^hQZ<rj>xrbu zHzWt|TUM>m>gW@_w0jSmb0nw-Z!9z@C7qMrRK&Hsul_sl?B{tY>&uiiGAdS+hqvII z)K-(nyMX5;zyB)lyoZ$^>CCTb!y1ny@vd80%r_%@&S*npM{fn-xqsONYTWqn96_8N zo`=y$N*+IP0^Sf54W{|z-4v`Rbwa$M<{ftAn;HBMS*(3|9&hc+ww5RIH3jUa@>Krs zXx8ay1ixo8+jO)Cd;6#dpRJO;X9U`pJ;BX${EQAd{-e2U`OE=f8#AF%Da)ES_A+&2 zj|D^91<IGQKW19^l>=G!tT2AYz`eFvX*$<yFokG`|MMIki`|;tm$&7!_H%;mC!u^c zXwFRg1<+J>V9qiAg=H*%?s9vlCRFS)uRv#i5`G!BDkn7X#T;^)oN%P?r_z&+NB$AA z9^z~%mrY&UvoksIj;$adn;IjT+bcniSLadWbR>&?CB(kqG|I?$<wyHJ@Ff`QHGd25 znz8rC`S0<3Vmf;@H`ws{f|d@rEnwSn!@`yCAT8m(s$*CD9!fbq!7y$$lyV~cyilES ztC@T>nD@_OZN6>WZWcKv#FW2q=M2Q_WDVZZ<@qgoe+ML18g@rGi$mGUZ(ZE>;?!L* zL&(A#yPfuyu#dlu;Ac%{XTOa!A0(%QnDP$}3|BjP?Bp$lJufP5KJ%^!kMvMWl<vIJ zTuH-VG_h-fp$ThvL3<(VJhp|VRcvxasHqA<w9q%V2uqz_VeeIR<yWp^)fGX>LoM)q zS(n7Ra=Cc9B`wzd;ASHY->OiKdsG{6A?&f766<=vnf8z{3>9vb#zCU%uaNa~mrWU= zti!QLb1T#=h~HX&(w_BRAdd%*;xu=>3mM@X%H|)73f_x`!=2<Ho~Zu{3kW(<i~{j4 zE_UtztYn9d4fc&DhV?ZxCImOV=C;faVdmrhy`G^D{qUOJ6iSj!Jwxyi`9-*@UDbFO z#2fIU>{&(Vg%d~;ievGN@K+nN9Ph(_WMlh|o6TN$EJ$7u+(FAN3xq6sT_VQ@{VKMv zvFgXz*n{KK`5$uF%O~PHzdN^ii0e0E0O)yM5ilWf;|h%QQk=T@%2o5Nzq^7RJJF;6 z5i{-Zxp3z13q~ImXFe{wCMh0e;X$28OOfiH8I0$P*fTw)zvnd9CA~QZ9`ux?oj8ig zsgR|-NRKxci^`Y5=L<)}IjIC`DAtTV1fnyMDI%WYoe(e6C#m#mvut|Sh8?S%XmC=B zRa{K(&Sue7fw~$txT=l&KCGA&@t<Vl+Dajz`>q_eq$<*s@&(n1SIfxdL$885NkK!{ zfvT83-64*LgUtq;-h?<*A(aL(MLPE(jj3J$Qxdn)EWi4ybZ{#XmK;exo3%gLJ<)l$ zBD4dmlXBq=O6;=TcPi0`xn}j#iCdp5Lhouqn^d8<=CSoBWB74f*twI@e8@beJJnuy zfkmC_7qELSx!fH|Jzu2?Q1WXH^HFf=Tqd4+iTB;jemoVF6alf6c<hvxT>2_y&j+%6 zghwV=i>>g<?b%((ijE`qNJ?LW^uhFn<2k|R)k=CYmL;4H9lF(DnOir^oK!J`rmF)L zf$1n3M5-y{!)Ij9Lu7DqXR)Gw3nusZD`4~qs99Q;jb{ra_7dB9x}$D8yL#F-ZSG(g zelvxl3%L%`+XF$57p#x#7QKkw-1u7ar}0JC1Y=6A@-0{zeX01eA62eQ)x3DUC*;&e z9mP;FbR<f!KB-&yHSN8Nz>y|rv+C-AsD7v)S|yvRe4(FJ(!J@>OS^{4Qpe_m&((xW z)0xMa?*6xsuD(%#{U|Zj_&I#>_-bG3bcjtl(}6!z%xq`+^0#W)`7>Sv&()%EI!zM= z@dqIaqSuTok7AJU;+hX8>Ki)uZKL5Z!v~~zo6H4O(PLU@TUW`sr6x(9#=4yCJMNpS zbR5fA;p^1GmIX9ila5aVH%_1HBCQ8i$r)%8@L&qB5#sR!Q)){@ZE50h)I%T6O+>6= z<f|{k%PWYNA#~>ot3K=7(G~nhwL*X_Jh~ys=LA?5xe-!KOR3TTkjh|v>doBG`S7+Y zto^xQzI7o>J$J_6dn#40tgWq6WVwu}24_+KM;?o=84<i4yk_TKH_%w-Qv`8j68_6Y z9c-U1HL)JnH!(58kfy4VG++w5T@&qU0>?Hn6x+qtEEabDmGo*8X`aQ?x-^nA7RACW zBoEpLn756x$pL1UwP~@jC_v#q#CuCnMT4R!%CjR_W74QBGzNRR@^#*1_RIO+US)9G z3)a7%<+@6#SPRg#kEXG17uxZ2Ozh<gT|CNGqs_yWH-f%>1CIL=7zY;u`T3LC;S0$f ztz&4ao8Jk_Rb#k3tM3GT@&oB$E++c4l==f}e=&ydex1F1F}%|i*aQE&cY=&?wEwqv zf;L}dyDoO*zq-b*U+gVx!_80mtc+fNhTcn_FVf^Fi?*|18>LgesIHP8yrfjE7x0AA zSG^WIUxU)O6Ite^=-IWMls7gHVnC8ouz_O3yyt;2DAspIJ77);Fr}<_u|pYx6b4?} zcBR3>Lm!i8YegioLXKDtQjU0A`MVZ>@uqim(n#bq)4xv;2d7J&$FS9xJ>9Ke7oaZA z;-c<z{!Dkp%K-wJQey_|bJ;iHy9^wCbo+j}LM<U0B^+=-9_jQXH7U9|Ni7_Ma9(tj z>er(JKYq<5st4zTVdh9$Z^zu(smp=<C}Mj#&>E2vCb8GA_&K-|9iWKw(hL^&T`GSl zQ;||qHfORAu9)o8rP6y;B0Ke+v&-^jq#s_Vr1hiOjqgJE-kFTQ67APvi8_~f!ht8p z<?0g-XUXm!8+65wubrqAs+bO6Pej$h{KknW+ef#S9k?=J|893(k}kj23|j!dUo~vf zuvLi4H*45g!z2wyXgE{DH#OX%VVQ<!HN2xChtF>4=cQsk7p^h7Y1m)GQ5w$Gus}nP zc4`5<h7a)4HvPVDMosQF4WDV~jIV*{=dEF+f^1i<bAFn}%G7X)hVN^*OT%w9yslxR zhR-zg#)sqd>#X4@4X0_iOv9BLZcs6w`&47>)9{#v-)s1*hJR@2h<D2A=dEG5hS3`K z(y+gV85(A5XwmRZ1+gQn)fgXXSgzss8a8U!N*iRehS3`K*DzDVYz-G`_=bjSG~A}) zKElrENtMP3*Jf4e9{%jnW^aRrM?!V%CLa-$-jhqBF(^z`QOHm+d<k%Mh^Ha%hRTSJ z10qWsQ}h3UBD-TSLb?b3m&V>P*M>UfM?Y1C$&R64%@Z|FH*@;sXmMIg^fPO5oTkdJ z{IM#J9Z30QYH@67%FkVkdus9Bf2;C1e(9IbC20(p6w0r$Nfm&_qx=fAcz_mn*W%<` zpkMhTRUS64^2^iWZM69AhibZ6izjLE5G9V+Nzxyv0(qK1v=)C=i@R&_#ag`aPgVY@ z7MHZRti`ML{(URoxVQYTWL?<YNt0(!HCyJHv*u5oWSMHtnLjUU>VgI4+yyh{PB*uU zn7yDK8}Vp7YkcIl_vj-}JNF;W-2&t1|Ji@z+aD#K%{VfS{qi`okFFKZwTj`>TYEZk zo>N>o&u%W9=P+Z9q1+`$=#H1RQFBZX$BjhTeM4==SkQBoI9vS0zqiiWo^$TjigS)> zmD4)VnG2j^<N~|7ae?!F8@=niYCOu_m7++o?93e38pCr+D~erzV&?NEvS&|X9F(RE z<5`!de)&{2$>+cpEk^iFlh@hnIQz*+bLOeO=+;Ji&e+X?GsdXRr9Ag=3O+(`tV0C9 z)?TeRuPKh47v#KRp0}lS7pNRUi=3Y`=XcD7^Rqa!gr^3j4b=UJXpTFK5L!p2q3xh= z{44&yYeQ5F$8|?&F5AhV=M3F^ID^iMqicP0|2$)12O}ibsi<@1Iagh4PG@#y^Zx1Q z(JVKrH{SI~<hXHl?8HC8G-AL0)4yeu*7xPOs|X8G3jLgDln`&uJ?2G@dl`X7hp@Ge zGv_nKjq~Yd;CzO8Hny&NKH(&DKLx9&ANH?0MDT0<uNkH?X;e=1=LT^#{jrzSkqF1# z0_}?TXfM<$QLeS8J+#Sz^NcaJXwqzf<K9DP&O={x{Dg3!jy-%9+@ra@cT%Bj12L0Y zQUAR^?b0}IEQ0$@LN-ti4$PYfn+NUEd10byvPWRDp_DY?EJyYgNFYbw+!qH$Tbt|q zX&8L8SgtWBkA8k_969%H?wtF4*Ba+?#~g>uR_T;K4rwg<sc%YiMqxC^JwRyA*jimp z(aq_5@%)`$DHyC3tn;wvJTT}UYh2RbN!LZZ5a7%OSlqb)ESUf-nSeFQa!J?uI&;2Q zjlLsXINxrdhpEd*XKck8r$F7&GgA3?EV}3x9oc}};8}$1o9}$3>oKgk4I3A5+&P47 ztqrY7%`L8+-xR1i%Jv&(YV@pWT~6{eu`#(&B!t&B`M=?KT!r`-H%lk$bR9xlw{FF? zM!wcDv`08+HrF#0SG5HQvwkW)q0<fUQK~VZ8dQaDC{@ijm6y8my0n%yPk_7f0>Zeu z(wV$2I9Sy*XU=(ktCl_E@0A=ExC&P2&C)%*t}T?m^m`3?J6#Wo_p;NqDgA=id6gF1 z=>j^_Tveejtxb-c2^*Rzrdh+EH<!K!{u&|sX6XexUFbl{V-EO#&T|HqwT#d_lzt(O zoW}?wrqqq|nD18Zn&Xm**7UL0wd?8Yh#5qH9{OUod}F+F{GwgBHr+nr+UPcL?u~AB z&y|bgsQMavjw{Wx*G0B0>^)~W?jnNeCsIo^P8n1;3@Qe;8wPg1sqWu%cm5p5H6cW6 z@_C^B&f^?v&i{XyyN@B$fG|sy({ZIMbUNQsvtH*{dQ+$KE}f{?jdpZ_-Z^u|`K3qn zy5L^a;%Ky3)m7-|2q*LuJ&y6Jqb=Vr!h!R#bi*bS%lYV{IhS;`mpQu94y|;3dQkon z+ys;@y)Vc4;@{Xb|5lP+(ugh5{G4|dyv={C4)OlK#`XU-uJiwYHm+e_{J$`+OXoZ3 zYWI(K)@{?XM*iSe?z+tmgG-od>-~R%FvTbBAL6U~$-Xo_Nas6n1dm%N+L*3knudag zNgBp!7_FgMLw61B`O-Z>x*_c^>D2OSG_2OJO2cvucbA3)>wG5tqD9wgh}}eK4*vU> zf_WO|Xqc&Cx`u*=DH_IUXx7lZ^mSBIx;<DIsjDkJ8LVsLx1CdqF3~Vg!|YP0HoA$e zn`Cvg8#SyeeWi`gXU=vl8mURI)8flD%+oMa!*mVfG&F1IrJ<{aP0!ToYBVe(EH%&6 z1wsLamS&iBwXGZN)D{;ws>qclhv<Ct5A=v)J}XMip}HjJW~o2)`)7vYKjAuMyQ<<D zrSFC5=H(0c$GX+-csACW<DUBHxNg8)Pi(E==K&|dj}`}d3h*34B<LF81B6SU34eu; z&jMNkKEUm1Jn?}!xCre8O}H3=<V%2`Bb4Kww>uD*EE{eD)rgb;e@1Y`zwfihjVTd< z=p^7Mjm`n?)o6N>a2vrLG7>PP4UT!x^w0b*YV;*wRtOpm{s!Q;2vp`Vpe~f-?t12< zG7$X`C_w<$YxG?pACA-74>G_F2-E|@VG-(R<p9UE<G2ju9S{5%p#b!5;01&gpf3Sk za0gin+7-ALVISyy!1MX|^9u<9dqq);@PCehPY|fGr@%efEqbF7`+%;UF~n35@CZV! zw~i|Z_UeKY5Fd&620lWdscZs1j)q+e{!`%eu4*T<fj=S8XyyL`VjylB1rSOD-iqZo z<=<ZcA0sG@0QQG@R}C35*ZTDYA2hD}9B%T;$Ptc4Ao&d7A&q|+cu%9p$HPwUjguL9 zdjnY_=HJzXA;s0?b{~%G23i98y`UBp2ow<_(fbv^PZ4Oe9ss?PR2jl<8cnzufu^zq zxDO!%WtIbL5i&v70dFEq0o|CCkJ}0&*@!#<<|T97Y|w-<0u8TkUygf*PyjxM+fNDt z4ISZhgq`4L1B(!-_hrC4xcyXvZ;wk&PXuaE3UCGj$;<|Z48SzyLns`?b_6Pvuo{6f z5X!jSM57TLt~9SB5Fg$Zu2Q3`fENa$H;}mmY(St2?gGOHX)6LaUZV-uXtWtup!`Yr zvlf|4fcJ)A$Urv&V~45*bpyVw(JO#$)73&Ff%_0>gb3-woV%b2Ck%(8LIE>@jR@NV zP$qEdD0Bw=Y+(NkJd5zbD}nG4aXARo>dj*?_qgwn_67nMAW)Ajz<Puw;NJxv9gpP* z`WW!jmoZ|XcLE<wz{VAbsRVjVRCUD*xCnvDA)E0X1gdKt@UMya*gz18&g8gd2-{Im z0njiRH%QQCpmP?^YS6C0wo}x~B7wP6Q33dQz*E!IMppxWpM&1}qQ^j&d6)*!uD}=s zs<<2Q5CV1ba6X8Y^Eqw=gi3&I7pMu5KnDv(27E{0>j;#g5Lkmiy&*h|o7D!$Q~?_o za@=*$goTT=5d}`oLmK$mz>RPn(Fkn@Ml8ns)BHt(_yvI!knrQzILrf-5qJZEDysvA zEKv)EJCEzF(S)wcR6QUpLZEWUIbMd*rKL;w*6Zpfwj8+Z4J=FW3*Nx`w^-FJmattR zmKhSFfx8e^fZh#^EmG-jzylh67)WocY=aEpZwQA$Hv-qKM2A2V&Rm6&13eqK34!*H zYM^Tgbq4#t8N>+2ab|y=f;P}JPrHE`YtaMn2{Yg2xQ?I+Zz0gANWlH2DqRL_LZG~a z-@XqI3gnLg$F9dzf*ub%xB;C6eHhp)e<PF*k>0=#A7IEpcLc6OptFE*%NCWt4XEF$ zR%Qm)Ae2MC4*2mlC@JW2VD5)V1Dyvvf<O%|2e$qQN{yxH1^fhoMlOFRh}XVAtC3*| zu=O5w{=9&X5SqYm0%jb9CL=Rp&qL@L=s2K=KozV2HXu;%?-KnrYy!yGAK|!Hzk$+$ zE(D%Lp#7j4=vj{Wr-)ZM#|=WDg3^E+5vZk`fxV8ZE$t0_x0>UQfxiye?~JN+0`Lz6 z3H%4Z?6Ybk2o2}Z0r2C1N#`+@(0oFl3y=ftdm$e~ga|E(a^P#<p>?2_03RWcwc~mP zs{nzPUmb8-tx9JDx$iLrkS9Ega2<3FP)4AU;I5&;*P(Ra6V?)qP7-$g0UK6661st? z_z{JY5HS9Rx+(PrE<!M)AUMvs_YoAu1d;>v7_25ja&8h$=vapX2^A2AA`qW2QR5Si z)A)q>3$+O0T8$>$qtS$CH2MPYo<<Ye-Bc@Z2gYbLA-SulVnXtD5KTxfA)*OCQE35w zA#ABy0wMV-s0W1PhoB6EgEX3a5#(neK4GCs@BhGEH(2+vW3+CVN9~rnEz*|8Esk5= Yx8`jv*t%|KsqY)Q4*OHy&>gn>U(tnFn*aa+ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/wheel.py b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/wheel.py index 0c8efad..1e2c7a0 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/distlib/wheel.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/distlib/wheel.py @@ -26,7 +26,8 @@ import zipfile from . import __version__, DistlibException from .compat import sysconfig, ZipFile, fsdecode, text_type, filter from .database import InstalledDistribution -from .metadata import Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME +from .metadata import (Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME, + LEGACY_METADATA_FILENAME) from .util import (FileOperator, convert_path, CSVReader, CSVWriter, Cache, cached_property, get_cache_base, read_exports, tempdir) from .version import NormalizedVersion, UnsupportedVersionError @@ -221,10 +222,12 @@ class Wheel(object): wheel_metadata = self.get_wheel_metadata(zf) wv = wheel_metadata['Wheel-Version'].split('.', 1) file_version = tuple([int(i) for i in wv]) - if file_version < (1, 1): - fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME, 'METADATA'] - else: - fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME] + # if file_version < (1, 1): + # fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME, + # LEGACY_METADATA_FILENAME] + # else: + # fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME] + fns = [WHEEL_METADATA_FILENAME, LEGACY_METADATA_FILENAME] result = None for fn in fns: try: @@ -299,10 +302,9 @@ class Wheel(object): return hash_kind, result def write_record(self, records, record_path, base): - records = list(records) # make a copy for sorting + records = list(records) # make a copy, as mutated p = to_posix(os.path.relpath(record_path, base)) records.append((p, '', '')) - records.sort() with CSVWriter(record_path) as writer: for row in records: writer.writerow(row) @@ -425,6 +427,18 @@ class Wheel(object): ap = to_posix(os.path.join(info_dir, 'WHEEL')) archive_paths.append((ap, p)) + # sort the entries by archive path. Not needed by any spec, but it + # keeps the archive listing and RECORD tidier than they would otherwise + # be. Use the number of path segments to keep directory entries together, + # and keep the dist-info stuff at the end. + def sorter(t): + ap = t[0] + n = ap.count('/') + if '.dist-info' in ap: + n += 10000 + return (n, ap) + archive_paths = sorted(archive_paths, key=sorter) + # Now, at last, RECORD. # Paths in here are archive paths - nothing else makes sense. self.write_records((distinfo, info_dir), libdir, archive_paths) @@ -476,7 +490,7 @@ class Wheel(object): data_dir = '%s.data' % name_ver info_dir = '%s.dist-info' % name_ver - metadata_name = posixpath.join(info_dir, METADATA_FILENAME) + metadata_name = posixpath.join(info_dir, LEGACY_METADATA_FILENAME) wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') record_name = posixpath.join(info_dir, 'RECORD') @@ -619,7 +633,7 @@ class Wheel(object): for v in epdata[k].values(): s = '%s:%s' % (v.prefix, v.suffix) if v.flags: - s += ' %s' % v.flags + s += ' [%s]' % ','.join(v.flags) d[v.name] = s except Exception: logger.warning('Unable to read legacy script ' @@ -684,7 +698,7 @@ class Wheel(object): if cache is None: # Use native string to avoid issues on 2.x: see Python #20140. base = os.path.join(get_cache_base(), str('dylib-cache'), - sys.version[:3]) + '%s.%s' % sys.version_info[:2]) cache = Cache(base) return cache @@ -773,7 +787,7 @@ class Wheel(object): data_dir = '%s.data' % name_ver info_dir = '%s.dist-info' % name_ver - metadata_name = posixpath.join(info_dir, METADATA_FILENAME) + metadata_name = posixpath.join(info_dir, LEGACY_METADATA_FILENAME) wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') record_name = posixpath.join(info_dir, 'RECORD') @@ -842,7 +856,7 @@ class Wheel(object): def get_version(path_map, info_dir): version = path = None - key = '%s/%s' % (info_dir, METADATA_FILENAME) + key = '%s/%s' % (info_dir, LEGACY_METADATA_FILENAME) if key not in path_map: key = '%s/PKG-INFO' % info_dir if key in path_map: @@ -868,7 +882,7 @@ class Wheel(object): if updated: md = Metadata(path=path) md.version = updated - legacy = not path.endswith(METADATA_FILENAME) + legacy = path.endswith(LEGACY_METADATA_FILENAME) md.write(path=path, legacy=legacy) logger.debug('Version updated from %r to %r', version, updated) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/distro.py b/venv/lib/python3.8/site-packages/pip/_vendor/distro.py index 3306163..0611b62 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/distro.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/distro.py @@ -49,7 +49,7 @@ _OS_RELEASE_BASENAME = 'os-release' #: #: * Value: Normalized value. NORMALIZED_OS_ID = { - 'ol': 'oracle', # Oracle Enterprise Linux + 'ol': 'oracle', # Oracle Linux } #: Translation table for normalizing the "Distributor ID" attribute returned by @@ -60,9 +60,11 @@ NORMALIZED_OS_ID = { #: #: * Value: Normalized value. NORMALIZED_LSB_ID = { - 'enterpriseenterprise': 'oracle', # Oracle Enterprise Linux + 'enterpriseenterpriseas': 'oracle', # Oracle Enterprise Linux 4 + 'enterpriseenterpriseserver': 'oracle', # Oracle Linux 5 'redhatenterpriseworkstation': 'rhel', # RHEL 6, 7 Workstation 'redhatenterpriseserver': 'rhel', # RHEL 6, 7 Server + 'redhatenterprisecomputenode': 'rhel', # RHEL 6 ComputeNode } #: Translation table for normalizing the distro ID derived from the file name @@ -90,7 +92,8 @@ _DISTRO_RELEASE_IGNORE_BASENAMES = ( 'lsb-release', 'oem-release', _OS_RELEASE_BASENAME, - 'system-release' + 'system-release', + 'plesk-release', ) @@ -163,6 +166,7 @@ def id(): "openbsd" OpenBSD "netbsd" NetBSD "freebsd" FreeBSD + "midnightbsd" MidnightBSD ============== ========================================= If you have a need to get distros for reliable IDs added into this set, @@ -609,7 +613,7 @@ class LinuxDistribution(object): distro release file can be found, the data source for the distro release file will be empty. - * ``include_name`` (bool): Controls whether uname command output is + * ``include_uname`` (bool): Controls whether uname command output is included as a data source. If the uname command is not available in the program execution path the data source for the uname command will be empty. @@ -757,7 +761,7 @@ class LinuxDistribution(object): version = v break if pretty and version and self.codename(): - version = u'{0} ({1})'.format(version, self.codename()) + version = '{0} ({1})'.format(version, self.codename()) return version def version_parts(self, best=False): @@ -967,8 +971,6 @@ class LinuxDistribution(object): # * commands or their arguments (not allowed in os-release) if '=' in token: k, v = token.split('=', 1) - if isinstance(v, bytes): - v = v.decode('utf-8') props[k.lower()] = v else: # Ignore any tokens that are not variable assignments @@ -1012,7 +1014,7 @@ class LinuxDistribution(object): stdout = subprocess.check_output(cmd, stderr=devnull) except OSError: # Command not found return {} - content = stdout.decode(sys.getfilesystemencoding()).splitlines() + content = self._to_str(stdout).splitlines() return self._parse_lsb_release_content(content) @staticmethod @@ -1047,7 +1049,7 @@ class LinuxDistribution(object): stdout = subprocess.check_output(cmd, stderr=devnull) except OSError: return {} - content = stdout.decode(sys.getfilesystemencoding()).splitlines() + content = self._to_str(stdout).splitlines() return self._parse_uname_content(content) @staticmethod @@ -1067,6 +1069,20 @@ class LinuxDistribution(object): props['release'] = version return props + @staticmethod + def _to_str(text): + encoding = sys.getfilesystemencoding() + encoding = 'utf-8' if encoding == 'ascii' else encoding + + if sys.version_info[0] >= 3: + if isinstance(text, bytes): + return text.decode(encoding) + else: + if isinstance(text, unicode): # noqa + return text.encode(encoding) + + return text + @cached_property def _distro_release_info(self): """ @@ -1169,8 +1185,6 @@ class LinuxDistribution(object): Returns: A dictionary containing all information items. """ - if isinstance(line, bytes): - line = line.decode('utf-8') matches = _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN.match( line.strip()[::-1]) distro_info = {} diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__init__.py index 0491234..d1d82f1 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__init__.py @@ -32,4 +32,4 @@ __all__ = ["HTMLParser", "parse", "parseFragment", "getTreeBuilder", # this has to be at the top level, see how setup.py parses this #: Distribution version number. -__version__ = "1.0.1" +__version__ = "1.1" diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-38.pyc index 630827efe1c5358b7bb4291e3b3135abdfbb8503..16192b6fb65fdd9dfce56b784f988a758fc9f4b6 100644 GIT binary patch delta 101 zcmey%xqyo|l$V!_0SGkz?TYW%$oqnsiP>=SPv&{f$@&@jxvBa^m8GRwnfk>=$@(dY zd6}s>$@xVksl|E~l~wv>sd;7kIhjfN1(hWk`FX~A7W&1RC8@dviOJcC>8Zt&x3YKu E0OtuLJ^%m! delta 66 zcmZ3$^_P=3l$V!_0SKO#ZHVjI$oqnsh1F2cVDfk7d2)98CAkIq1(^l9nR&$}i8(pC SMj0lh6~_6AAi>EuSUdo=x)v$` diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-38.pyc index 48015d2759a6f392ed8f10e971f277ab8fdf462f..064c9924f30f7edd3c0612d49dceaf9172e12c44 100644 GIT binary patch delta 1352 zcmZ{k&2Jk;6u>>}4>s#KaawA-u@fa#+In5v8z&|Tl?tkoevvOF4Pb##wO&u`P3&DW zI}T1rRm7PCVs0Q+<$~0zLPAzAt;Ao@1LA@-QYFNphaNb<0fbcGJ;x0p0$cj+n>X)k z-@MreTTizlZ$=`T4}SWe4{wydiQJFPRg9Y3pa$D%wKi?TW0p}d9h=rImvQRl+dI3) zHg&d*x?MJ!JG|yP)A?D$vpLN*O>4`nQm^wvY=Ok2X4Oo#W;&pe3fpFbkVlHy1SJ!l z+X;=3@y^|o=Slbs=-D{ptRSg`2qg!SpTg3M0(>Mu`pGa!kTi+HlVydGd>q>M0rPb7 zi^HZW7$uY#8Td<8SV7FE45AC3(#coicItB?#j7Lfcpg0Np_dAP1d2+IDJ<V<k1T|T zuYihOMO;I?fmlE+iYMt5`L^>%`UD|YL^N~yIGV{m?v@($WwSwbKU)@8Gez>fxS1)x zd>M9i!mi^(Vapg}UHqCECr`wQb3dQyhF?YP8X|<a2#_juD&7Y+uc4RFvuDYVVl{hz zrUaY%OWk5*kYQhC&~jT2Xa5leYr%-`i0Pb8o^{^Kog&eH+sU}NQ;27}N!cQ14s6&? zMGy8oQKMB%ZmzU=v&GrG_%5F%zli7g74nH#GA6>WapjJ`;@=}NpJ*GoNam(`Nb|KZ zQYh^O_d;>sb)OzsW&{fg0(MW%xs+M9Qyp_$Cs$fp9CM(5=f_Ta;&<cJkvf?rGLxgX z%IJ*^(zRYQL6&{!c-dwimnw>D6eQA+g9rNk>gB+T-QK#N(PrJW=o}2G$L2Bk1|oa_ z9KY`AJqN){rhq=8!Zd0ylTp&I1e5?708Lc<G-+Pw9=F1lz)EV=v&?2U_TAn={BH&e z90tWlg^yqFMhG$+BMkM*Yfy);(JE~>*+Bzjf6MtN!Hbh#7Z;}{NK9-@d81eaV~8WK z^FHX3;<qU}qk{wkW}wm3zKjDSRlK#9TcJl?IqZ&!&!*|DhdwKaw-9e5-bLI%R1rAz z4Bw2k5SW&6VH6X=OCUZHi^UwdBzBAAp<Ucs6<-#QC!|_7y>8QF*sf5w%FJfXwxoDm z9KHqDqRruEP{t;~MTY8>b6BjS{}$pyL<|u}Odv)P_<HOdB8w;>jv??vz%~&zgb9!# jx4cO$&aloyEf5!qeZqNVW@t$Bt6}&D)ILqo{F?u73%fz~ delta 1288 zcmZ{kO>7%Q6o5VJpRU*WaTAibiIX-~nq(b2n;$ozNGM8M+Cor5(o{qX#M!JT$u{=d zyd8%KwW?Hc=kN}QN(iXLq0mDss~03rxgsR43lcXF7bFhcip0FN6CeUx`sU4>_qT7} z?$7(r_S<i@w`(E!`{m%t=Hk=#$Gt-fhN#qxnp4X=t|zQ=IX|;ks2|Q&EmAg~_b#zs zQ?vIhShL(+?)eHFK&K30;yWqMGL55@#@L0%cjx9=VnpiU0^uTd4~!0cC`B(R5n>V6 z#`;-`jkBa&A&ct+-^QBuIGP@34{#-Yjv45r4K{`!r*-xP9;F{J6E_FP`*JeGBMPQA zgDEQOQXtp(WN<0*;#H}GR|wY#*9kWWuM!d`phA4LSae)R6pP<9&g(slUBye;i{0ey z$3=CcQeL(yTo1z%R<Z^5JwD8Czi>sK>I~kXMS&%`z$&IDhS`reKk?gWkad}~D})$f zLBdzLTk_s>#2$I!a&C<Mga^6DbGPK7ekQ2Vj{>#TkJ{C`E8st(P%RYkP29-q?AONq ze1^rEcKGFFMyE`{llqYz$1Um6mbp}$TFDaDN?p|I0v7R)$sGF~GsX)00KphJGcT0S z!lf{NZsg;mch%PJ2V*d`ekXb-))%@N(j&{jC_z->{T@tC^`JhLNuH{63*VX=x>qDa zDo58^O_H)7cV$DbIp7IXC2@^=!e<q;^F-e)(Cj!qZSC8D*UFa7ugKZ+V3C4v6aIan z!L2-(dT$^t8Dgp&G%XmnHYK7&SO;mad)j(AxJCtDlUBaQJ=>}Uu^+V>{J$Btq(cWj zoxZ;iM2G^X2xnX6Rk$nG_%1)J!AS%Bwz~Uwg5w)pMVJ|3J^0a#H$+9iZNjO?aip#v z$7lK6n3Uw;<jH8NDbpaBD!q($wZu=mmgVVrJeuV%?UT>zgqwtQ!Uo}Of=!@dhAl#c zKxv_jTZL5gvJ}6@yM;Wvj9(Ror{AR`x^O>kSLqw!3NILPQ{A?_poM0_De>wqShYRJ zHu29w|2<RXheFOj2bd(^SeXkUH>(tFmjHxbLLVVR7$VTaf=<X13_=%yz5=jAC=oU# l{8)ASHn#;()&FP+x`jA?dTH)#QVXjI`H!e^P0_+y_%A0SCh`CP diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-38.pyc index 36570fc36360ea3ea72a18fec68441f76b1ceeb8..fbfcfb78c5b3cbfcd21b3cfbdcb73b08c5025e14 100644 GIT binary patch delta 5659 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 N{JIME16*IQ?0+s-!O#Ez delta 5615 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-38.pyc index 748619ef6affbd824b32a6474a3e57daf9918c0b..221325e42488a8ada7ea7f1ba3258918560a8392 100644 GIT binary patch delta 11161 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 Q719I!&9UbQm)()||9+s5F8}}l delta 10825 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-38.pyc index 99f227b2cc6cbc3d476c67731e8953b8a52e7fc5..24a22f3118d16209c9572420f2862fd8fb90532c 100644 GIT binary patch literal 4815 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 XU|rxc12?D(*O~L@p2k@=<(>N<{kv22 delta 1147 zcmZ8fJ8u&~5Z>K8-@~u7oy2(&VG)S9Je-6_!y^h2A)-J+gjcS>I(avVl{?$oyF8m9 zl7bR+5`Ta+G=P+fl9G!4{y;!9)D(!BON0Zq?wg%&W_D(0=IezY{rN|^T$;e|XyfCv z57z7a8TOOB9zVCs30FML*Bzaboib>uXZR)~l=x{UL&+1;98rnLuBGKF1(uS;CwJnL zN1r9qWKRiCagFQT;3iM6XpXfrE($!eN1dW5iK5W=Sa1ML_8(^PAnbZUAxYun@|@ER z*J*HF-sxT-+~V3k;hN~#Q=Bp{aDAURy}ZZ`kbS(wO_2S(i+6(@;OZi=d!m<gK5d3# zE3AdvZ4n*O_oL_F>4G?v6Nho?C{U)t)qU!yST@9_xDK(VG!DP8x9nmL{3XJ#8<U~m zo@_VT6OCpNx}G<2Y4ytb*5#IqWb`RjvC7~#4PQ_KAZqk2<;>*aWGk`<M69fcQ1&Ci z<Um5KiS6X}W2hjPsnx)(5emOnn~k1pwrSJEY-`bdy*iCa<S@eD+B(tF0K<9s0u8{R zYBp^}Mm8Gh1vOS$lG`*^xf{BtqAOsNCcr}UIV)#vI5mh0+$b8x0HA_#6iiNlh>iNH zD{C9B_x~lhS@#Zu+%laSLPyn=D?zNSZK8yxT0qJa0@fI-I2Kt%eK0buYGw+L*g-iI z%~@CblNVM%k8^&DuY2N-TMt`udntNlITz3hC0$4Vn+S>fH9S=iG60VwtMKM_G6Z&# z30N3NCl#*5I~J$vZhck6>hgNC-f3v8Z%Vh_7JMW6UKpD>NjVE4@)kmpat2QofLQm1 z-)iiL0F-0|gsLpB$vM#N!RSHJ_F!46wGGkaEm;j3TM`Eqm$!Vc3d<oxwLb3&Uo^vq zpv0+!i?gRmsbfUuuHSCSa9+xmjC(rar=v5GRXV$yG`$aEWEKH8F<Fyj<Pt}gbSkOw z)IgJ$Rlph>H;$V>LqQ9$aosEne@4qRPx};&GQuePt!5ZCXqp+cL^Y7AQW!Qg)i8~r EKia172mk;8 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-38.pyc index aa9cdfb60f806be5905f0af18662234c864d110b..77cd32c480c9e4a98d0d8f498b80a9d7e580f5e9 100644 GIT binary patch delta 658 zcmX|;&u<bz6vt<Fm)&(0RBWLXp|uqYMc5|B*hFnitnp&J7%wZ8!p@W~wm^WAqPsB$ z?7<jC=hQ=!_D?W-(!_Z2;?aYNY1ETOq5j}6s6JNOO=jQceP`bHz1?}VCakXs?wfA6 zg5ZhmzDmo_+#%e35q~H7T9{mfHPb}&$mY>4G>aNo^D>VdOdq2%X^|hKLw3l|oD1{; zDpMgp2;_6f4>aUZ0BG2uAW+bu<3J(sp6&Y!dB5WxhWv^)!XC@<@loipLE1SE&Yl4N zPQH>q<URRBK9esw3DhxrTMl7q9E#G~Nw#|+h$Hr}@@)*CdY*WSCs->HxgUjw(UwHC z0CM83eoO^Wjt7$%?9KJZkoG@w64cvtl03YCt|H(xtode-=4rgaYo{GG19{d_vorx} zl5jUrRF@EHJO7j4K5S1XFP$A3h15VMnj1=S7EbXNXYrO`3MRk6nV7M4{oG}uE*6)m zTCT6G<PEh_)>V=z7<5T5maDXqT&>?#YqU^PmyE1hs#h0_g)_-%wPI9hqLk6^WOB5^ ze(MoGG4!flTrSNh96}WlI*aHK5?Pd}q43@uJ_}coi5t#)6K}!QGFBt!mH+2CsIgy? z>&-#mUWKPOxy6~zyy5ngXZ7H|y@)ubwLf5!O?B>hAM`e$H<EGr8pN1tzwTgczuozW g@q)ea>ka2pu=rPGneGHPz}ru{HLvKy3h#6M1Duw-MgRZ+ delta 690 zcmYk3-)qxQ6vyvP(j?RtXLVcKt^3hh*V=U*>hM9W2vrfpm*Gq8wzfH0ZRuRGaVRDX zY#pMA9eMI$(ER~IB?#h+_~_f5Y@(<jD6^g79(@q%N$AADH|LWtH|Kk}=kXGEe~EKm zb~^0@pRI+)bbQ(Aqko=8UJG7%UyZ^kRJ=;$uDWZLBuIr;XmY=97yA|u$RgC>JG5XM ze&lTEcgv#86?%|*Epj7yEb=1tS=5izZ;=maz{*H;GPr`flQ4+R+2jx=G~fmDId}&j zU=5zZTX+Ru;0Zj}>*C(PFrHX}W{$yLe&j9q3cuhDe1uQ%IVYeSFxEvM4IIQKGs&PV zVojqms4PlCfi?Ug!)5>Grz86B(ML3---`wp!#HQSCP30dta_zWQy!9IvG-w|UVtfV zVcwAN-wj33pOzzV_ar$_kY`Zos!3^iw8AE%mYc!vtmS6qF?3_VOp=f!5YjZ)VT8sK z6T^O_98t-XH^pc)#cGVkYMjcc>@1_wS!P*(ARQk#9aH8?u~NPi&0i}knPM?|<m#~- zH;>L|OjEZ(u)CNqE7JU2DQ;&7DRbDCCl37##0H0UBitHQh>9yV-*vi*>ox-(!U@qj zPnou{4wtIE?%hAS%%L<!?Tj+f9CzH>^RGRxmzx_@(=W7cyY84aCKHifzlb$FZfv$F swQ-P_6k~JyJ*5Ss@$)5Pb5Oo5>dMXt@1R^;<cyV_1sCt7cDBd%7s_(V761SM diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-38.pyc index fe600567b46c453f9812c685d1f00b6ca21d1a37..2782f90a47a8bea5f64af3be2f5a124610509016 100644 GIT binary patch literal 91273 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 g`+GO^-c;-Z<9Vv%0D6OAI9dP4imTveb)&cVe+mwjP5=M^ literal 95136 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-38.pyc index 52789805c7b646475f3f6e9932dab50f03f2dfc7..bf5d56fe308a52525c9770d8712f4cd1eaba3d0f 100644 GIT binary patch delta 124 zcmZ1&ay*1Ll$V!_0SGkz?TYW;$XmneoT{IZpPQ;*R9RY@m8oA`l&qhUn3tKFlbl~v zl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2(-keHmEn4Vg^c{%GW2?3|z%HopL bT!qY()Vz|+w9L%`a#382QJYt5lraJTtWhj? delta 86 zcmX>evM_`<l$V!_0SKO#ZHVjJ$XmlI=b&GbTcBT%S)iMlS6q^qlcQ^tVNzOQoSz61 n+<b<0mIS|JaAk2xYOX?NN@`w7X4>X5xhO8iTbnOxlraJT>6IR1 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_ihatexml.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_ihatexml.py index 4c77717..3ff803c 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_ihatexml.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_ihatexml.py @@ -136,6 +136,7 @@ def normaliseCharList(charList): i += j return rv + # We don't really support characters above the BMP :( max_unicode = int("FFFF", 16) @@ -254,7 +255,7 @@ class InfosetFilter(object): nameRest = name[1:] m = nonXmlNameFirstBMPRegexp.match(nameFirst) if m: - warnings.warn("Coercing non-XML name", DataLossWarning) + warnings.warn("Coercing non-XML name: %s" % name, DataLossWarning) nameFirstOutput = self.getReplacementCharacter(nameFirst) else: nameFirstOutput = nameFirst @@ -262,7 +263,7 @@ class InfosetFilter(object): nameRestOutput = nameRest replaceChars = set(nonXmlNameBMPRegexp.findall(nameRest)) for char in replaceChars: - warnings.warn("Coercing non-XML name", DataLossWarning) + warnings.warn("Coercing non-XML name: %s" % name, DataLossWarning) replacement = self.getReplacementCharacter(char) nameRestOutput = nameRestOutput.replace(char, replacement) return nameFirstOutput + nameRestOutput diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_inputstream.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_inputstream.py index a65e55f..e0bb376 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_inputstream.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_inputstream.py @@ -1,10 +1,11 @@ from __future__ import absolute_import, division, unicode_literals -from pip._vendor.six import text_type, binary_type +from pip._vendor.six import text_type from pip._vendor.six.moves import http_client, urllib import codecs import re +from io import BytesIO, StringIO from pip._vendor import webencodings @@ -12,13 +13,6 @@ from .constants import EOF, spaceCharacters, asciiLetters, asciiUppercase from .constants import _ReparseException from . import _utils -from io import StringIO - -try: - from io import BytesIO -except ImportError: - BytesIO = StringIO - # Non-unicode versions of constants for use in the pre-parser spaceCharactersBytes = frozenset([item.encode("ascii") for item in spaceCharacters]) asciiLettersBytes = frozenset([item.encode("ascii") for item in asciiLetters]) @@ -40,13 +34,13 @@ if _utils.supports_lone_surrogates: else: invalid_unicode_re = re.compile(invalid_unicode_no_surrogate) -non_bmp_invalid_codepoints = set([0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, - 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, - 0x6FFFE, 0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, - 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF, - 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, - 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, - 0x10FFFE, 0x10FFFF]) +non_bmp_invalid_codepoints = {0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, + 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, + 0x6FFFE, 0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, + 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF, + 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, + 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, + 0x10FFFE, 0x10FFFF} ascii_punctuation_re = re.compile("[\u0009-\u000D\u0020-\u002F\u003A-\u0040\u005C\u005B-\u0060\u007B-\u007E]") @@ -367,7 +361,7 @@ class HTMLUnicodeInputStream(object): def unget(self, char): # Only one character is allowed to be ungotten at once - it must # be consumed again before any further call to unget - if char is not None: + if char is not EOF: if self.chunkOffset == 0: # unget is called quite rarely, so it's a good idea to do # more work here if it saves a bit of work in the frequently @@ -449,7 +443,7 @@ class HTMLBinaryInputStream(HTMLUnicodeInputStream): try: stream.seek(stream.tell()) - except: # pylint:disable=bare-except + except Exception: stream = BufferedStream(stream) return stream @@ -461,7 +455,7 @@ class HTMLBinaryInputStream(HTMLUnicodeInputStream): if charEncoding[0] is not None: return charEncoding - # If we've been overriden, we've been overriden + # If we've been overridden, we've been overridden charEncoding = lookupEncoding(self.override_encoding), "certain" if charEncoding[0] is not None: return charEncoding @@ -664,9 +658,7 @@ class EncodingBytes(bytes): """Look for a sequence of bytes at the start of a string. If the bytes are found return True and advance the position to the byte after the match. Otherwise return False and leave the position alone""" - p = self.position - data = self[p:p + len(bytes)] - rv = data.startswith(bytes) + rv = self.startswith(bytes, self.position) if rv: self.position += len(bytes) return rv @@ -674,15 +666,11 @@ class EncodingBytes(bytes): def jumpTo(self, bytes): """Look for the next sequence of bytes matching a given sequence. If a match is found advance the position to the last byte of the match""" - newPosition = self[self.position:].find(bytes) - if newPosition > -1: - # XXX: This is ugly, but I can't see a nicer way to fix this. - if self._position == -1: - self._position = 0 - self._position += (newPosition + len(bytes) - 1) - return True - else: + try: + self._position = self.index(bytes, self.position) + len(bytes) - 1 + except ValueError: raise StopIteration + return True class EncodingParser(object): @@ -694,6 +682,9 @@ class EncodingParser(object): self.encoding = None def getEncoding(self): + if b"<meta" not in self.data: + return None + methodDispatch = ( (b"<!--", self.handleComment), (b"<meta", self.handleMeta), @@ -703,6 +694,10 @@ class EncodingParser(object): (b"<", self.handlePossibleStartTag)) for _ in self.data: keepParsing = True + try: + self.data.jumpTo(b"<") + except StopIteration: + break for key, method in methodDispatch: if self.data.matchBytes(key): try: @@ -908,7 +903,7 @@ class ContentAttrParser(object): def lookupEncoding(encoding): """Return the python codec name corresponding to an encoding or None if the string doesn't correspond to a valid encoding.""" - if isinstance(encoding, binary_type): + if isinstance(encoding, bytes): try: encoding = encoding.decode("ascii") except UnicodeDecodeError: diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_tokenizer.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_tokenizer.py index 178f6e7..5f00253 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_tokenizer.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_tokenizer.py @@ -2,7 +2,8 @@ from __future__ import absolute_import, division, unicode_literals from pip._vendor.six import unichr as chr -from collections import deque +from collections import deque, OrderedDict +from sys import version_info from .constants import spaceCharacters from .constants import entities @@ -17,6 +18,11 @@ from ._trie import Trie entitiesTrie = Trie(entities) +if version_info >= (3, 7): + attributeMap = dict +else: + attributeMap = OrderedDict + class HTMLTokenizer(object): """ This class takes care of tokenizing HTML. @@ -228,6 +234,14 @@ class HTMLTokenizer(object): # Add token to the queue to be yielded if (token["type"] in tagTokenTypes): token["name"] = token["name"].translate(asciiUpper2Lower) + if token["type"] == tokenTypes["StartTag"]: + raw = token["data"] + data = attributeMap(raw) + if len(raw) > len(data): + # we had some duplicated attribute, fix so first wins + data.update(raw[::-1]) + token["data"] = data + if token["type"] == tokenTypes["EndTag"]: if token["data"]: self.tokenQueue.append({"type": tokenTypes["ParseError"], diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__init__.py index a5ba4bf..07bad5d 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__init__.py @@ -1,14 +1,5 @@ from __future__ import absolute_import, division, unicode_literals -from .py import Trie as PyTrie +from .py import Trie -Trie = PyTrie - -# pylint:disable=wrong-import-position -try: - from .datrie import Trie as DATrie -except ImportError: - pass -else: - Trie = DATrie -# pylint:enable=wrong-import-position +__all__ = ["Trie"] diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-38.pyc index 4efa34fddbd315a0a3dde6d7d28378efe18700fc..0ab091fc177289ca638f8e2373735d2c06d15536 100644 GIT binary patch delta 184 zcmZo-zQ?2;%FD~e00f%<cE#rc>Bk@rGGGF79Dul3YofLSKPw|c3QIa;6k7^wFoP!B z#3o0MA~v9`pC<dnW2zDC@$rc{Iq~r;8Hzxrf{9<5`WgATsrp5grKMS!`o%@b`YDNd znW;I+`9&qE#d;N$Rr+PAd1d-JnMwKul_eSZdB%Dc`o)<gsk#M;$=QkNsl}767|l3X LfF_DC@h|}ZG~F$j delta 220 zcmcb|)WobE%FD~e00hs=HpD41GB7*_agYHAkmCTv#X%Fb70lTf8B*DzSgQn5m{OQ? z*mGH<I2aki8S+F}7*aX2xr#g(89*?SA&)JBA(bPFHH9UZL6dc2lq0jBCfCHps{U*N zl_5o$sZnexi6vm##Sz56#qF6}kY7~dT2z!@w34BS8)zk%_~oKsl3So(kXfLcnO9tr on3JPxlwnd@VVs``5}d5SXePu5R4l^8!^FbO#3;bX$H>M60LP{;m;e9( diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-38.pyc index 487202b24b432b2ccd6b84356b8cc5ae389b6c79..e66060d4db627686df8af9065b4d7ae43c85e195 100644 GIT binary patch delta 94 zcmbQsbBKp0l$V!_0SGkz?TX*X^PbT;O+O<)H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*kVBohk@0OO<}VgLXD delta 57 zcmX@aGna=al$V!_0SKO#ZHU{*^PW-8QNJX&K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J*^Y^Y1pxUo5$*s0 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-38.pyc deleted file mode 100644 index 058d54cd543acd09bbc7dbf6f2943aa38652a462..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1998 zcmbVNOK%%D5GI$qtCcLvitQA3pK6+-QHxkWAGe^0lN3dPLWer-L1;s)McP_tA2La~ zwz0m%{uMphN8kE;c<rIcU+Aebl;p^c&;q8w;p_}K-@Hiuytr5+F#bOH^Ti)NA%Ee= z>;M^g3{(FIL=Zt!lF=T`yq=e_9-}DpQa=lNq2pOv$)a8aybtm!$ZM2*PedTXGa^D+ zJ7v8<RJKSvdJPsyo7ts!TNmlbNS<WFLKz#0<RH;Wk=y1dPx^(BJWY&LajM(Y`p;D& zVXYc@Xt+5V%GVSO_0ihwVDRx6rv3$pBt0rf&l6O5XQamj6F#i|*e~=*MDQJos;I$Q z5v!su7SCue5)H8glB#HmJFwQovRHw2K`cNFcU1t!`yP<#2!TQ2Q<!=Wh#{xs#4G7J zy&%uXZ=atq<CV;?Q%~PFzM!Y{6)hQP8Yh0~od>0VK`GgPu-`DD@XjlxcL94!!XvOz zbvBlN^-kDHPzEL0i%Ry0?EfSPxWl@~Yny4>dMS@|D;sIk+LkSCRFdy%OWHNdv^3U7 zwXH#hb8X_hFBST1tIr{o-ziln%VHsH_-qq1ZT-C>$!)+zY+@Tg9Wvbxt*>ReWBswP zKZupK4D4DTc^e$W=}2A@wFZ{|dD1c2uro}C4;^BfKKyd<_2}@cB1WN`{6OZSP@RFv z(r?mayTie2*#YygYz&WV#Ceh@hI4FJy$poVkk)C9M(}HRP1>Z#i|Fvibmz6QV2N<L zvY?F;Qo2W8hFj#4b}y-Fg6z^$Xj$Dwg07FrI&ikmdB4a_3?Xp-4oI}CIz7HK0ez$G zV?Ry@^4EY30br=;7E$kkuI*Wt%6yDZ$M`p(E1bg)&e4x4YJGz06mJ0{=vAcHfUltY zr-0P1bPMxCHcVwEb0dW-x@y6hn?YmN;o@=r{tWb0mYwE*vJ5#c>G~8~p&j+X9Ha%# zccsDZ;{2l-u;wJrD`odBK)mQK*g7y+)N@+Wi#Pdosa06>NqucNRB|Udyb-P2a&HE^ z>ag*)+z!*O4r0ymJpVm013p3h6d-Owe+Dv?Ps_XRpywUGr7MlJ$akeS|K-F3Z~*7j zi52I>^@F#BU%74tyDC%j643_yFJ^pLo8yB!-KO1k9iN3f&Lroy#(7qVQHng=)%{VN zjy39CFsD95@-dQ6klaUtEuk>;3ZqsCJyREV3GvFgH@*stdv@TtsYh)5tGU(byX^&Z zVP|AU3S3Zl<rQ|O!hcZsV{tE;+o~EMu}kpuZA_lM4Gqoc9^rs*$6DIT=98xw_&j%P V^k^LDw|L8S1Z35#)4Eq@{{jt4s&@bY diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-38.pyc index c326a44f10dd4c00091523683e9c31d9ae903330..1af14f57ce5f7c2d8a1d234183600ff9f5446db3 100644 GIT binary patch delta 99 zcmZ1{cv+Aql$V!_0SGkz?TTN>!{nT-pOK%Ns$W!DTAG!qUtE-|pOToDnVOTFUsRG> ztXEN4rC*ksSEiqnnWSG(S(1^TXRK$TUz}Nzs#}nloSm4STD)0{NtTT<YO)7M8USZp BAzc6f delta 62 zcmcaCxK5BKl$V!_0SKO#ZHQaQ!z5>?Uy@s(Uyxa#o0(T!l9-dDYm{M9T49`@2ol`v O&m_yncx!SlM;ZV}z!Q!D diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/datrie.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/datrie.py deleted file mode 100644 index e2e5f86..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_trie/datrie.py +++ /dev/null @@ -1,44 +0,0 @@ -from __future__ import absolute_import, division, unicode_literals - -from datrie import Trie as DATrie -from pip._vendor.six import text_type - -from ._base import Trie as ABCTrie - - -class Trie(ABCTrie): - def __init__(self, data): - chars = set() - for key in data.keys(): - if not isinstance(key, text_type): - raise TypeError("All keys must be strings") - for char in key: - chars.add(char) - - self._data = DATrie("".join(chars)) - for key, value in data.items(): - self._data[key] = value - - def __contains__(self, key): - return key in self._data - - def __len__(self): - return len(self._data) - - def __iter__(self): - raise NotImplementedError() - - def __getitem__(self, key): - return self._data[key] - - def keys(self, prefix=None): - return self._data.keys(prefix) - - def has_keys_with_prefix(self, prefix): - return self._data.has_keys_with_prefix(prefix) - - def longest_prefix(self, prefix): - return self._data.longest_prefix(prefix) - - def longest_prefix_item(self, prefix): - return self._data.longest_prefix_item(prefix) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_utils.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_utils.py index 0703afb..d7c4926 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_utils.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/_utils.py @@ -2,12 +2,20 @@ from __future__ import absolute_import, division, unicode_literals from types import ModuleType -from pip._vendor.six import text_type - try: - import xml.etree.cElementTree as default_etree + from collections.abc import Mapping except ImportError: + from collections import Mapping + +from pip._vendor.six import text_type, PY3 + +if PY3: import xml.etree.ElementTree as default_etree +else: + try: + import xml.etree.cElementTree as default_etree + except ImportError: + import xml.etree.ElementTree as default_etree __all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair", @@ -27,7 +35,7 @@ try: # We need this with u"" because of http://bugs.jython.org/issue2039 _x = eval('u"\\uD800"') # pylint:disable=eval-used assert isinstance(_x, text_type) -except: # pylint:disable=bare-except +except Exception: supports_lone_surrogates = False else: supports_lone_surrogates = True @@ -47,9 +55,6 @@ class MethodDispatcher(dict): """ def __init__(self, items=()): - # Using _dictEntries instead of directly assigning to self is about - # twice as fast. Please do careful performance testing before changing - # anything here. _dictEntries = [] for name, value in items: if isinstance(name, (list, tuple, frozenset, set)): @@ -64,6 +69,36 @@ class MethodDispatcher(dict): def __getitem__(self, key): return dict.get(self, key, self.default) + def __get__(self, instance, owner=None): + return BoundMethodDispatcher(instance, self) + + +class BoundMethodDispatcher(Mapping): + """Wraps a MethodDispatcher, binding its return values to `instance`""" + def __init__(self, instance, dispatcher): + self.instance = instance + self.dispatcher = dispatcher + + def __getitem__(self, key): + # see https://docs.python.org/3/reference/datamodel.html#object.__get__ + # on a function, __get__ is used to bind a function to an instance as a bound method + return self.dispatcher[key].__get__(self.instance) + + def get(self, key, default): + if key in self.dispatcher: + return self[key] + else: + return default + + def __iter__(self): + return iter(self.dispatcher) + + def __len__(self): + return len(self.dispatcher) + + def __contains__(self, key): + return key in self.dispatcher + # Some utility functions to deal with weirdness around UCS2 vs UCS4 # python builds diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/constants.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/constants.py index 1ff8041..fe3e237 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/constants.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/constants.py @@ -519,8 +519,8 @@ adjustForeignAttributes = { "xmlns:xlink": ("xmlns", "xlink", namespaces["xmlns"]) } -unadjustForeignAttributes = dict([((ns, local), qname) for qname, (prefix, local, ns) in - adjustForeignAttributes.items()]) +unadjustForeignAttributes = {(ns, local): qname for qname, (prefix, local, ns) in + adjustForeignAttributes.items()} spaceCharacters = frozenset([ "\t", @@ -544,8 +544,7 @@ asciiLetters = frozenset(string.ascii_letters) digits = frozenset(string.digits) hexDigits = frozenset(string.hexdigits) -asciiUpper2Lower = dict([(ord(c), ord(c.lower())) - for c in string.ascii_uppercase]) +asciiUpper2Lower = {ord(c): ord(c.lower()) for c in string.ascii_uppercase} # Heading elements need to be ordered headingElements = ( @@ -2934,7 +2933,7 @@ tagTokenTypes = frozenset([tokenTypes["StartTag"], tokenTypes["EndTag"], tokenTypes["EmptyTag"]]) -prefixes = dict([(v, k) for k, v in namespaces.items()]) +prefixes = {v: k for k, v in namespaces.items()} prefixes["http://www.w3.org/1998/Math/MathML"] = "math" diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-38.pyc index af84a4dfaa643e8e1fa4b6ed2b3c97332c738bb4..ed38dfa677925e9b02f243cfd60f4e5518200ecb 100644 GIT binary patch delta 91 zcmZ3;c#M%Jl$V!_0SGkz?TVksW9^)+pOK%Ns$W!DTAG!qUtE-|pOToDnVOTFUsRG> ttXEN4rC*ksSEiqnnWSG(S(1^TXRK$TUz}Nzs#}nloSm4ST0Ak;1^`{hAK(B0 delta 54 zcmX@cxR8-2l$V!_0SKO#ZHSx5V=d>VUy@s(Uyxa#o0(T!l9-dDYm{M9T49`@2ojvw GWdi`PDG_V{ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-38.pyc index ed1a3d203d1fb8b62fa684308cdd4408bc6ae737..7f322c5ab23b03aba52e288da07b2a1b15341078 100644 GIT binary patch delta 94 zcmZqXTEWE=%FD~e00f%<cExYx5o2<$)X&JzP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7c;z;u`i0GD?lNdN!< delta 57 zcmZ3%)y%~c%FD~e00hs=HpFe@5o3}I(J#p@&@ad=(9O&%E=kPE(KX62DXlQhPXq~W JPGvgG1OU;O5!C<y diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-38.pyc index edc979c641c6aabe4b0b85e95f5bdc83255ee1e6..c2829b49ca1fc864ae8d8752d0d8ffcf85ec4b2c 100644 GIT binary patch delta 94 zcmdnb_JoZml$V!_0SGkz?TX*XBgW{QuAh;go2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5)wf$={h0J}*b-~a#s delta 57 zcmaFDwx5kBl$V!_0SKO#ZHU{*BgQD_q+gO-pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JoXYs05di1-5^Mkf diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-38.pyc index deb626f0c94bd80eb228fbb485671dd8d46d8522..d09bd02ee6e998e85e30c92a2d6808f45964b823 100644 GIT binary patch delta 94 zcmZ3>cZrWDl$V!_0SGkz?TX*X!^h-Yrk|0Yo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5)wg6S&@0JZTT#sB~S delta 57 zcmcb_x0a75l$V!_0SKO#ZHU{*!^b2Ss9%y>pkI(#pqrUjT#}fRqid95Qd(i0p9m7% J9Lw~T1pwq+5>fyF diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-38.pyc index b0f0e20b6528f77ea068f9eac803b4ca2dc3119b..9bd34266e2591a8ae49fa233a493927d93d5715b 100644 GIT binary patch delta 100 zcmZ21azcbBl$V!_0SGkz?TX*X^NGnhT|Xl~H&wr=va~cSQ@^+<SwAH)FEceKIlrhR zwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*kV40AslW7Om|oaF$$ Cf+H>f delta 63 zcmX>hvRH&Cl$V!_0SKO#ZHU{*^NC5$NxvkwK))cfKsPh5xFj(rN7pFBq_n~~KM^Fj P*^#-Qjq%pxi=5>EdV>{T diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-38.pyc index 898672aa92c673f368d0fba56347cc7a83039b42..7ecefd2cb77f7dd9b0504f4c8065e68893d13da4 100644 GIT binary patch delta 94 zcmZ1?dQy}pl$V!_0SGkz?TX*XbAZt~Uq2&1H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lAE5=<M0O+P6<^TWy delta 57 zcmX>px<r&Gl$V!_0SKO#ZHU{*bAVCKOTQ$yK))cfKsPh5xFj(rN7pFBq_n~~KM^Fj JnV)GF2LSsP5_13m diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-38.pyc index 2723dcdccbdec7db0221976a7469e699e544f766..3a8ae9d136bf0e4c6eafed80301c6375c162b027 100644 GIT binary patch delta 4238 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 delta 3675 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 KY(CL(TK*cQZkp== diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-38.pyc index 812ecc7dc751bd18f649e675f8a3f23d38dfb248..db459a194542ad58de5d975aa1540b273ff98b37 100644 GIT binary patch delta 94 zcmdnUb&ZQBl$V!_0SGkz?TX*XBgO2TtDljdo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5)wh50Qb0JmQt%m4rY delta 57 zcmcb{wULV_l$V!_0SKO#ZHU{*BgHJ|p<j|)pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JoXPx_5dh^j5?BBL diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/sanitizer.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/sanitizer.py index af8e77b..aa7431d 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/sanitizer.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/filters/sanitizer.py @@ -1,6 +1,15 @@ +"""Deprecated from html5lib 1.1. + +See `here <https://github.com/html5lib/html5lib-python/issues/443>`_ for +information about its deprecation; `Bleach <https://github.com/mozilla/bleach>`_ +is recommended as a replacement. Please let us know in the aforementioned issue +if Bleach is unsuitable for your needs. + +""" from __future__ import absolute_import, division, unicode_literals import re +import warnings from xml.sax.saxutils import escape, unescape from pip._vendor.six.moves import urllib_parse as urlparse @@ -11,6 +20,14 @@ from ..constants import namespaces, prefixes __all__ = ["Filter"] +_deprecation_msg = ( + "html5lib's sanitizer is deprecated; see " + + "https://github.com/html5lib/html5lib-python/issues/443 and please let " + + "us know if Bleach is unsuitable for your needs" +) + +warnings.warn(_deprecation_msg, DeprecationWarning) + allowed_elements = frozenset(( (namespaces['html'], 'a'), (namespaces['html'], 'abbr'), @@ -750,6 +767,9 @@ class Filter(base.Filter): """ super(Filter, self).__init__(source) + + warnings.warn(_deprecation_msg, DeprecationWarning) + self.allowed_elements = allowed_elements self.allowed_attributes = allowed_attributes self.allowed_css_properties = allowed_css_properties diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/html5parser.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/html5parser.py index ae41a13..d06784f 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/html5parser.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/html5parser.py @@ -2,7 +2,6 @@ from __future__ import absolute_import, division, unicode_literals from pip._vendor.six import with_metaclass, viewkeys import types -from collections import OrderedDict from . import _inputstream from . import _tokenizer @@ -119,8 +118,8 @@ class HTMLParser(object): self.tree = tree(namespaceHTMLElements) self.errors = [] - self.phases = dict([(name, cls(self, self.tree)) for name, cls in - getPhases(debug).items()]) + 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): @@ -202,7 +201,7 @@ class HTMLParser(object): DoctypeToken = tokenTypes["Doctype"] ParseErrorToken = tokenTypes["ParseError"] - for token in self.normalizedTokens(): + for token in self.tokenizer: prev_token = None new_token = token while new_token is not None: @@ -260,10 +259,6 @@ class HTMLParser(object): if reprocess: assert self.phase not in phases - def normalizedTokens(self): - for token in self.tokenizer: - yield self.normalizeToken(token) - def parse(self, stream, *args, **kwargs): """Parse a HTML document into a well-formed tree @@ -325,17 +320,6 @@ class HTMLParser(object): if self.strict: raise ParseError(E[errorcode] % datavars) - def normalizeToken(self, token): - # HTML5 specific normalizations to the token stream - if token["type"] == tokenTypes["StartTag"]: - raw = token["data"] - token["data"] = OrderedDict(raw) - if len(raw) > len(token["data"]): - # we had some duplicated attribute, fix so first wins - token["data"].update(raw[::-1]) - - return token - def adjustMathMLAttributes(self, token): adjust_attributes(token, adjustMathMLAttributes) @@ -413,16 +397,12 @@ class HTMLParser(object): def getPhases(debug): def log(function): """Logger that records which phase processes each token""" - type_names = dict((value, key) for key, value in - tokenTypes.items()) + 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] - try: - info = {"type": type_names[token['type']]} - except: - raise + info = {"type": type_names[token['type']]} if token['type'] in tagTokenTypes: info["name"] = token['name'] @@ -446,10 +426,13 @@ def getPhases(debug): 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 @@ -469,7 +452,21 @@ def getPhases(debug): self.tree.insertText(token["data"]) def processStartTag(self, token): - return self.startTagHandler[token["name"]](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": @@ -482,9 +479,25 @@ def getPhases(debug): self.parser.firstStartTag = False def processEndTag(self, token): - return self.endTagHandler[token["name"]](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 @@ -613,6 +626,8 @@ def getPhases(debug): return True class BeforeHtmlPhase(Phase): + __slots__ = tuple() + # helper methods def insertHtmlElement(self): self.tree.insertRoot(impliedTagToken("html", "StartTag")) @@ -648,19 +663,7 @@ def getPhases(debug): return token class BeforeHeadPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("head", self.startTagHead) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - (("head", "body", "html", "br"), self.endTagImplyHead) - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() def processEOF(self): self.startTagHead(impliedTagToken("head", "StartTag")) @@ -693,28 +696,19 @@ def getPhases(debug): 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): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("title", self.startTagTitle), - (("noframes", "style"), self.startTagNoFramesStyle), - ("noscript", self.startTagNoscript), - ("script", self.startTagScript), - (("base", "basefont", "bgsound", "command", "link"), - self.startTagBaseLinkCommand), - ("meta", self.startTagMeta), - ("head", self.startTagHead) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("head", self.endTagHead), - (("br", "html", "body"), self.endTagHtmlBodyBr) - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() # the real thing def processEOF(self): @@ -796,22 +790,27 @@ def getPhases(debug): 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): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - (("basefont", "bgsound", "link", "meta", "noframes", "style"), self.startTagBaseLinkCommand), - (("head", "noscript"), self.startTagHeadNoscript), - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("noscript", self.endTagNoscript), - ("br", self.endTagBr), - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() def processEOF(self): self.parser.parseError("eof-in-head-noscript") @@ -860,23 +859,21 @@ def getPhases(debug): # Caller must raise parse error first! self.endTagNoscript(impliedTagToken("noscript")) - class AfterHeadPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) + startTagHandler = _utils.MethodDispatcher([ + ("html", startTagHtml), + (("basefont", "bgsound", "link", "meta", "noframes", "style"), startTagBaseLinkCommand), + (("head", "noscript"), startTagHeadNoscript), + ]) + startTagHandler.default = startTagOther - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("body", self.startTagBody), - ("frameset", self.startTagFrameset), - (("base", "basefont", "bgsound", "link", "meta", "noframes", "script", - "style", "title"), - self.startTagFromHead), - ("head", self.startTagHead) - ]) - self.startTagHandler.default = self.startTagOther - self.endTagHandler = _utils.MethodDispatcher([(("body", "html", "br"), - self.endTagHtmlBodyBr)]) - self.endTagHandler.default = self.endTagOther + endTagHandler = _utils.MethodDispatcher([ + ("noscript", endTagNoscript), + ("br", endTagBr), + ]) + endTagHandler.default = endTagOther + + class AfterHeadPhase(Phase): + __slots__ = tuple() def processEOF(self): self.anythingElse() @@ -927,80 +924,30 @@ def getPhases(debug): 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 - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) + __slots__ = ("processSpaceCharacters",) + def __init__(self, *args, **kwargs): + super(InBodyPhase, self).__init__(*args, **kwargs) # Set this to the default handler self.processSpaceCharacters = self.processSpaceCharactersNonPre - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - (("base", "basefont", "bgsound", "command", "link", "meta", - "script", "style", "title"), - self.startTagProcessInHead), - ("body", self.startTagBody), - ("frameset", self.startTagFrameset), - (("address", "article", "aside", "blockquote", "center", "details", - "dir", "div", "dl", "fieldset", "figcaption", "figure", - "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", - "section", "summary", "ul"), - self.startTagCloseP), - (headingElements, self.startTagHeading), - (("pre", "listing"), self.startTagPreListing), - ("form", self.startTagForm), - (("li", "dd", "dt"), self.startTagListItem), - ("plaintext", self.startTagPlaintext), - ("a", self.startTagA), - (("b", "big", "code", "em", "font", "i", "s", "small", "strike", - "strong", "tt", "u"), self.startTagFormatting), - ("nobr", self.startTagNobr), - ("button", self.startTagButton), - (("applet", "marquee", "object"), self.startTagAppletMarqueeObject), - ("xmp", self.startTagXmp), - ("table", self.startTagTable), - (("area", "br", "embed", "img", "keygen", "wbr"), - self.startTagVoidFormatting), - (("param", "source", "track"), self.startTagParamSource), - ("input", self.startTagInput), - ("hr", self.startTagHr), - ("image", self.startTagImage), - ("isindex", self.startTagIsIndex), - ("textarea", self.startTagTextarea), - ("iframe", self.startTagIFrame), - ("noscript", self.startTagNoscript), - (("noembed", "noframes"), self.startTagRawtext), - ("select", self.startTagSelect), - (("rp", "rt"), self.startTagRpRt), - (("option", "optgroup"), self.startTagOpt), - (("math"), self.startTagMath), - (("svg"), self.startTagSvg), - (("caption", "col", "colgroup", "frame", "head", - "tbody", "td", "tfoot", "th", "thead", - "tr"), self.startTagMisplaced) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("body", self.endTagBody), - ("html", self.endTagHtml), - (("address", "article", "aside", "blockquote", "button", "center", - "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", - "footer", "header", "hgroup", "listing", "main", "menu", "nav", "ol", "pre", - "section", "summary", "ul"), self.endTagBlock), - ("form", self.endTagForm), - ("p", self.endTagP), - (("dd", "dt", "li"), self.endTagListItem), - (headingElements, self.endTagHeading), - (("a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", - "strike", "strong", "tt", "u"), self.endTagFormatting), - (("applet", "marquee", "object"), self.endTagAppletMarqueeObject), - ("br", self.endTagBr), - ]) - self.endTagHandler.default = self.endTagOther - def isMatchingFormattingElement(self, node1, node2): return (node1.name == node2.name and node1.namespace == node2.namespace and @@ -1650,14 +1597,73 @@ def getPhases(debug): self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) break + startTagHandler = _utils.MethodDispatcher([ + ("html", Phase.startTagHtml), + (("base", "basefont", "bgsound", "command", "link", "meta", + "script", "style", "title"), + startTagProcessInHead), + ("body", startTagBody), + ("frameset", startTagFrameset), + (("address", "article", "aside", "blockquote", "center", "details", + "dir", "div", "dl", "fieldset", "figcaption", "figure", + "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", + "section", "summary", "ul"), + startTagCloseP), + (headingElements, startTagHeading), + (("pre", "listing"), startTagPreListing), + ("form", startTagForm), + (("li", "dd", "dt"), startTagListItem), + ("plaintext", startTagPlaintext), + ("a", startTagA), + (("b", "big", "code", "em", "font", "i", "s", "small", "strike", + "strong", "tt", "u"), startTagFormatting), + ("nobr", startTagNobr), + ("button", startTagButton), + (("applet", "marquee", "object"), startTagAppletMarqueeObject), + ("xmp", startTagXmp), + ("table", startTagTable), + (("area", "br", "embed", "img", "keygen", "wbr"), + startTagVoidFormatting), + (("param", "source", "track"), startTagParamSource), + ("input", startTagInput), + ("hr", startTagHr), + ("image", startTagImage), + ("isindex", startTagIsIndex), + ("textarea", startTagTextarea), + ("iframe", startTagIFrame), + ("noscript", startTagNoscript), + (("noembed", "noframes"), startTagRawtext), + ("select", startTagSelect), + (("rp", "rt"), startTagRpRt), + (("option", "optgroup"), startTagOpt), + (("math"), startTagMath), + (("svg"), startTagSvg), + (("caption", "col", "colgroup", "frame", "head", + "tbody", "td", "tfoot", "th", "thead", + "tr"), startTagMisplaced) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + ("body", endTagBody), + ("html", endTagHtml), + (("address", "article", "aside", "blockquote", "button", "center", + "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", + "footer", "header", "hgroup", "listing", "main", "menu", "nav", "ol", "pre", + "section", "summary", "ul"), endTagBlock), + ("form", endTagForm), + ("p", endTagP), + (("dd", "dt", "li"), endTagListItem), + (headingElements, endTagHeading), + (("a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", + "strike", "strong", "tt", "u"), endTagFormatting), + (("applet", "marquee", "object"), endTagAppletMarqueeObject), + ("br", endTagBr), + ]) + endTagHandler.default = endTagOther + class TextPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - self.startTagHandler = _utils.MethodDispatcher([]) - self.startTagHandler.default = self.startTagOther - self.endTagHandler = _utils.MethodDispatcher([ - ("script", self.endTagScript)]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() def processCharacters(self, token): self.tree.insertText(token["data"]) @@ -1683,30 +1689,15 @@ def getPhases(debug): self.tree.openElements.pop() self.parser.phase = self.parser.originalPhase + startTagHandler = _utils.MethodDispatcher([]) + startTagHandler.default = startTagOther + endTagHandler = _utils.MethodDispatcher([ + ("script", endTagScript)]) + endTagHandler.default = endTagOther + class InTablePhase(Phase): # http://www.whatwg.org/specs/web-apps/current-work/#in-table - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("caption", self.startTagCaption), - ("colgroup", self.startTagColgroup), - ("col", self.startTagCol), - (("tbody", "tfoot", "thead"), self.startTagRowGroup), - (("td", "th", "tr"), self.startTagImplyTbody), - ("table", self.startTagTable), - (("style", "script"), self.startTagStyleScript), - ("input", self.startTagInput), - ("form", self.startTagForm) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("table", self.endTagTable), - (("body", "caption", "col", "colgroup", "html", "tbody", "td", - "tfoot", "th", "thead", "tr"), self.endTagIgnore) - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() # helper methods def clearStackToTableContext(self): @@ -1828,9 +1819,32 @@ def getPhases(debug): self.parser.phases["inBody"].processEndTag(token) self.tree.insertFromTable = False + startTagHandler = _utils.MethodDispatcher([ + ("html", Phase.startTagHtml), + ("caption", startTagCaption), + ("colgroup", startTagColgroup), + ("col", startTagCol), + (("tbody", "tfoot", "thead"), startTagRowGroup), + (("td", "th", "tr"), startTagImplyTbody), + ("table", startTagTable), + (("style", "script"), startTagStyleScript), + ("input", startTagInput), + ("form", startTagForm) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + ("table", endTagTable), + (("body", "caption", "col", "colgroup", "html", "tbody", "td", + "tfoot", "th", "thead", "tr"), endTagIgnore) + ]) + endTagHandler.default = endTagOther + class InTableTextPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) + __slots__ = ("originalPhase", "characterTokens") + + def __init__(self, *args, **kwargs): + super(InTableTextPhase, self).__init__(*args, **kwargs) self.originalPhase = None self.characterTokens = [] @@ -1875,23 +1889,7 @@ def getPhases(debug): class InCaptionPhase(Phase): # http://www.whatwg.org/specs/web-apps/current-work/#in-caption - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", - "thead", "tr"), self.startTagTableElement) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("caption", self.endTagCaption), - ("table", self.endTagTable), - (("body", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", - "thead", "tr"), self.endTagIgnore) - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() def ignoreEndTagCaption(self): return not self.tree.elementInScope("caption", variant="table") @@ -1944,23 +1942,24 @@ def getPhases(debug): def endTagOther(self, token): return self.parser.phases["inBody"].processEndTag(token) + startTagHandler = _utils.MethodDispatcher([ + ("html", Phase.startTagHtml), + (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", + "thead", "tr"), startTagTableElement) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + ("caption", endTagCaption), + ("table", endTagTable), + (("body", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", + "thead", "tr"), endTagIgnore) + ]) + endTagHandler.default = endTagOther + class InColumnGroupPhase(Phase): # http://www.whatwg.org/specs/web-apps/current-work/#in-column - - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("col", self.startTagCol) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("colgroup", self.endTagColgroup), - ("col", self.endTagCol) - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() def ignoreEndTagColgroup(self): return self.tree.openElements[-1].name == "html" @@ -2010,26 +2009,21 @@ def getPhases(debug): if not ignoreEndTag: return token + startTagHandler = _utils.MethodDispatcher([ + ("html", Phase.startTagHtml), + ("col", startTagCol) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + ("colgroup", endTagColgroup), + ("col", endTagCol) + ]) + endTagHandler.default = endTagOther + class InTableBodyPhase(Phase): # http://www.whatwg.org/specs/web-apps/current-work/#in-table0 - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("tr", self.startTagTr), - (("td", "th"), self.startTagTableCell), - (("caption", "col", "colgroup", "tbody", "tfoot", "thead"), - self.startTagTableOther) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - (("tbody", "tfoot", "thead"), self.endTagTableRowGroup), - ("table", self.endTagTable), - (("body", "caption", "col", "colgroup", "html", "td", "th", - "tr"), self.endTagIgnore) - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() # helper methods def clearStackToTableBodyContext(self): @@ -2108,26 +2102,26 @@ def getPhases(debug): def endTagOther(self, token): return self.parser.phases["inTable"].processEndTag(token) + startTagHandler = _utils.MethodDispatcher([ + ("html", Phase.startTagHtml), + ("tr", startTagTr), + (("td", "th"), startTagTableCell), + (("caption", "col", "colgroup", "tbody", "tfoot", "thead"), + startTagTableOther) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + (("tbody", "tfoot", "thead"), endTagTableRowGroup), + ("table", endTagTable), + (("body", "caption", "col", "colgroup", "html", "td", "th", + "tr"), endTagIgnore) + ]) + endTagHandler.default = endTagOther + class InRowPhase(Phase): # http://www.whatwg.org/specs/web-apps/current-work/#in-row - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - (("td", "th"), self.startTagTableCell), - (("caption", "col", "colgroup", "tbody", "tfoot", "thead", - "tr"), self.startTagTableOther) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("tr", self.endTagTr), - ("table", self.endTagTable), - (("tbody", "tfoot", "thead"), self.endTagTableRowGroup), - (("body", "caption", "col", "colgroup", "html", "td", "th"), - self.endTagIgnore) - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() # helper methods (XXX unify this with other table helper methods) def clearStackToTableRowContext(self): @@ -2197,23 +2191,26 @@ def getPhases(debug): def endTagOther(self, token): return self.parser.phases["inTable"].processEndTag(token) + startTagHandler = _utils.MethodDispatcher([ + ("html", Phase.startTagHtml), + (("td", "th"), startTagTableCell), + (("caption", "col", "colgroup", "tbody", "tfoot", "thead", + "tr"), startTagTableOther) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + ("tr", endTagTr), + ("table", endTagTable), + (("tbody", "tfoot", "thead"), endTagTableRowGroup), + (("body", "caption", "col", "colgroup", "html", "td", "th"), + endTagIgnore) + ]) + endTagHandler.default = endTagOther + class InCellPhase(Phase): # http://www.whatwg.org/specs/web-apps/current-work/#in-cell - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", - "thead", "tr"), self.startTagTableOther) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - (("td", "th"), self.endTagTableCell), - (("body", "caption", "col", "colgroup", "html"), self.endTagIgnore), - (("table", "tbody", "tfoot", "thead", "tr"), self.endTagImply) - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() # helper def closeCell(self): @@ -2273,26 +2270,22 @@ def getPhases(debug): def endTagOther(self, token): return self.parser.phases["inBody"].processEndTag(token) + startTagHandler = _utils.MethodDispatcher([ + ("html", Phase.startTagHtml), + (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", + "thead", "tr"), startTagTableOther) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + (("td", "th"), endTagTableCell), + (("body", "caption", "col", "colgroup", "html"), endTagIgnore), + (("table", "tbody", "tfoot", "thead", "tr"), endTagImply) + ]) + endTagHandler.default = endTagOther + class InSelectPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("option", self.startTagOption), - ("optgroup", self.startTagOptgroup), - ("select", self.startTagSelect), - (("input", "keygen", "textarea"), self.startTagInput), - ("script", self.startTagScript) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("option", self.endTagOption), - ("optgroup", self.endTagOptgroup), - ("select", self.endTagSelect) - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() # http://www.whatwg.org/specs/web-apps/current-work/#in-select def processEOF(self): @@ -2373,21 +2366,25 @@ def getPhases(debug): self.parser.parseError("unexpected-end-tag-in-select", {"name": token["name"]}) + startTagHandler = _utils.MethodDispatcher([ + ("html", Phase.startTagHtml), + ("option", startTagOption), + ("optgroup", startTagOptgroup), + ("select", startTagSelect), + (("input", "keygen", "textarea"), startTagInput), + ("script", startTagScript) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + ("option", endTagOption), + ("optgroup", endTagOptgroup), + ("select", endTagSelect) + ]) + endTagHandler.default = endTagOther + class InSelectInTablePhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), - self.startTagTable) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), - self.endTagTable) - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() def processEOF(self): self.parser.phases["inSelect"].processEOF() @@ -2412,7 +2409,21 @@ def getPhases(debug): def endTagOther(self, token): return self.parser.phases["inSelect"].processEndTag(token) + startTagHandler = _utils.MethodDispatcher([ + (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), + startTagTable) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), + endTagTable) + ]) + endTagHandler.default = endTagOther + class InForeignContentPhase(Phase): + __slots__ = tuple() + breakoutElements = frozenset(["b", "big", "blockquote", "body", "br", "center", "code", "dd", "div", "dl", "dt", "em", "embed", "h1", "h2", "h3", @@ -2422,9 +2433,6 @@ def getPhases(debug): "span", "strong", "strike", "sub", "sup", "table", "tt", "u", "ul", "var"]) - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - def adjustSVGTagNames(self, token): replacements = {"altglyph": "altGlyph", "altglyphdef": "altGlyphDef", @@ -2478,7 +2486,7 @@ def getPhases(debug): currentNode = self.tree.openElements[-1] if (token["name"] in self.breakoutElements or (token["name"] == "font" and - set(token["data"].keys()) & set(["color", "face", "size"]))): + set(token["data"].keys()) & {"color", "face", "size"})): self.parser.parseError("unexpected-html-element-in-foreign-content", {"name": token["name"]}) while (self.tree.openElements[-1].namespace != @@ -2528,16 +2536,7 @@ def getPhases(debug): return new_token class AfterBodyPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([("html", self.endTagHtml)]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() def processEOF(self): # Stop parsing @@ -2574,23 +2573,17 @@ def getPhases(debug): self.parser.phase = self.parser.phases["inBody"] return token + startTagHandler = _utils.MethodDispatcher([ + ("html", startTagHtml) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([("html", endTagHtml)]) + endTagHandler.default = endTagOther + class InFramesetPhase(Phase): # http://www.whatwg.org/specs/web-apps/current-work/#in-frameset - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("frameset", self.startTagFrameset), - ("frame", self.startTagFrame), - ("noframes", self.startTagNoframes) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("frameset", self.endTagFrameset) - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() def processEOF(self): if self.tree.openElements[-1].name != "html": @@ -2631,21 +2624,22 @@ def getPhases(debug): self.parser.parseError("unexpected-end-tag-in-frameset", {"name": token["name"]}) + startTagHandler = _utils.MethodDispatcher([ + ("html", Phase.startTagHtml), + ("frameset", startTagFrameset), + ("frame", startTagFrame), + ("noframes", startTagNoframes) + ]) + startTagHandler.default = startTagOther + + endTagHandler = _utils.MethodDispatcher([ + ("frameset", endTagFrameset) + ]) + endTagHandler.default = endTagOther + class AfterFramesetPhase(Phase): # http://www.whatwg.org/specs/web-apps/current-work/#after3 - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) - - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("noframes", self.startTagNoframes) - ]) - self.startTagHandler.default = self.startTagOther - - self.endTagHandler = _utils.MethodDispatcher([ - ("html", self.endTagHtml) - ]) - self.endTagHandler.default = self.endTagOther + __slots__ = tuple() def processEOF(self): # Stop parsing @@ -2668,14 +2662,19 @@ def getPhases(debug): self.parser.parseError("unexpected-end-tag-after-frameset", {"name": token["name"]}) - class AfterAfterBodyPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) + startTagHandler = _utils.MethodDispatcher([ + ("html", Phase.startTagHtml), + ("noframes", startTagNoframes) + ]) + startTagHandler.default = startTagOther - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml) - ]) - self.startTagHandler.default = self.startTagOther + endTagHandler = _utils.MethodDispatcher([ + ("html", endTagHtml) + ]) + endTagHandler.default = endTagOther + + class AfterAfterBodyPhase(Phase): + __slots__ = tuple() def processEOF(self): pass @@ -2706,15 +2705,13 @@ def getPhases(debug): self.parser.phase = self.parser.phases["inBody"] return token - class AfterAfterFramesetPhase(Phase): - def __init__(self, parser, tree): - Phase.__init__(self, parser, tree) + startTagHandler = _utils.MethodDispatcher([ + ("html", startTagHtml) + ]) + startTagHandler.default = startTagOther - self.startTagHandler = _utils.MethodDispatcher([ - ("html", self.startTagHtml), - ("noframes", self.startTagNoFrames) - ]) - self.startTagHandler.default = self.startTagOther + class AfterAfterFramesetPhase(Phase): + __slots__ = tuple() def processEOF(self): pass @@ -2741,6 +2738,13 @@ def getPhases(debug): def processEndTag(self, token): self.parser.parseError("expected-eof-but-got-end-tag", {"name": token["name"]}) + + startTagHandler = _utils.MethodDispatcher([ + ("html", startTagHtml), + ("noframes", startTagNoFrames) + ]) + startTagHandler.default = startTagOther + # pylint:enable=unused-argument return { @@ -2774,8 +2778,8 @@ def getPhases(debug): def adjust_attributes(token, replacements): needs_adjustment = viewkeys(token['data']) & viewkeys(replacements) if needs_adjustment: - token['data'] = OrderedDict((replacements.get(k, k), v) - for k, v in token['data'].items()) + token['data'] = type(token['data'])((replacements.get(k, k), v) + for k, v in token['data'].items()) def impliedTagToken(name, type="EndTag", attributes=None, diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/serializer.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/serializer.py index 53f4d44..d5669d8 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/serializer.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/serializer.py @@ -274,7 +274,7 @@ class HTMLSerializer(object): if token["systemId"]: if token["systemId"].find('"') >= 0: if token["systemId"].find("'") >= 0: - self.serializeError("System identifer contains both single and double quote characters") + self.serializeError("System identifier contains both single and double quote characters") quote_char = "'" else: quote_char = '"' diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-38.pyc index e0424d5cefbbdae5a3101292a38e6aeb21858dd4..112b8d6613e07895899e8ce33aaabcc0ce7d9ac7 100644 GIT binary patch delta 93 zcmZo+U&+oB%FD~e00f%<cExYx;be9$(9g)vP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS vE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc5Eo%p3>+ZnYnf delta 56 zcmZ3<-onlk%FD~e00hs=HpFe@;bfNc)-TB|&@ad=(9O&%E=kPE(KX62DXlQhPXq~0 Ij$jT10J`Q88~^|S diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-38.pyc index 72b06b4c79e50f0eacf565a77ab76d3c196c6fdc..5aa2992d8ea6d16d6a63005698ff38a23080c3d5 100644 GIT binary patch delta 94 zcmaFF-Oj@k%FD~e00f%<cExYxxy0<8r=O9Zo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5*55A!od0Ot-O8vp<R delta 57 zcmZqYdBn{V%FD~e00hs=HpFe@xx_5zsb7*?pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JtjO|=5dirV5~u(G diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-38.pyc index 6979244ccc4005a2d6523d32bcf385aa7270bdfe..0cffd9cd6a919b77eee1d0787e9692763f7ad142 100644 GIT binary patch delta 94 zcmZ3;eT<tYl$V!_0SGkz?TX*X6T;%0t)G#fo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5)QjzyUf0KA4ESO5S3 delta 57 zcmX@cy^xzHl$V!_0SKO#ZHU{*6T%|rreBg<pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JyqHCq5dh|P5##^> diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-38.pyc index 8d5aaab2fdd63f666657f6048ec5475d44ab0838..81d474857cb074d94b5d7e9517214bcf7e27d9aa 100644 GIT binary patch delta 93 zcmcaA`Ad=~l$V!_0SGkz?TX*XbB5cwKtCftH&wr=va~cSQ@^+<SwAH)FEceKIlrhR vwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*l9H}3lY^F|_i delta 56 zcmew*c~z1pl$V!_0SKO#ZHU{*bB0^aTfZc?K))cfKsPh5xFj(rN7pFBq_n~~KM^E2 IS(@iQ00NT}2LJ#7 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-38.pyc index 0bbf798a9d7c3a8a567cf0d707c1475e22e9d7f2..f235e7c8c5985ca7f5ee2dbbaef0592c8dfd127b 100644 GIT binary patch delta 231 zcmZ1<aXf-Il$V!_0SGkz?TUXokyn=S(?o4AUCtDCNrn`TG^PwjCx&Lm6t*;`RPI#v zRERhykOyIL0aY+fT;*xV<Ia#GkRsT^kRq7M+squr2jmN-2m|@Tsr*2`0FW<|A`0Y- zg5?D_t1u=pIp^qS<maa97gd&)W@YLZ7bWYbB<5wN<|OAAm82HyRa92#m!;;F>E~o7 z=@(R%WaQ@=>sja*XO^Vu79=KTC#I(sZ(hQ@L!D7*a;&yAW7OnIZOh5qwS(9t82K2v L{<BRM(2)lKz5GFg delta 208 zcmX>eu|9$~l$V!_0SKO#ZHW6kkyn=S*F<eEQ=U}L6n0656pl2ebjD^zCx&Lm6t*;` zRPI#vRG1tmkPlJC1yse<%s6q8ry;L9LyAC(U<*TvU@BiTa}+<2FO(t-<O`<?0QrJI zzDSBFkS_|B7uqbtn8YOKu3wT{pkI(#pqrUjT#}fRqid95Qd(i0p9m7%e2{sEI-~I9 kDs5@TTa%}0Te99_E>10(d|o?<U4~JBk?TLlWDOm80J(WMB>(^b diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-38.pyc index 6e587cddb7ebbda16f93bad394bc7c04822b01ec..2a10a3f538e1f11fd91f96b50470ae7420fb7b8d 100644 GIT binary patch delta 94 zcmX@*`QDQ!l$V!_0SGkz?TX*Xvx&($TR$T|H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lA9j14R03{6~$p8QV delta 57 zcmaFwdCHR~l$V!_0SKO#ZHU{*vx!O0O}`|!K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj JnUVROA^;!m6IK8K diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-38.pyc index 75159473f83b06be8af966fa181651b0f3a437ed..abdc5b1c43fabc2a9e4362ba84d1a2d2ef3e26e1 100644 GIT binary patch delta 4129 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 delta 4089 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 Ee=I_2tN;K2 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-38.pyc index f229e3dd3eb78e96d3d49a71e4a1e823151f1c6b..75a839273a156df07db7395e950548330d3b60c5 100644 GIT binary patch delta 5319 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 YmTHXEzA#E^Iy2RnmW(7*#$!hM|9Sm&?f?J) delta 4430 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 QMP)kBcqksz&S;7M1DuhdL;wH) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/base.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/base.py index 73973db..965fce2 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/base.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/base.py @@ -10,9 +10,9 @@ Marker = None listElementsMap = { None: (frozenset(scopingElements), False), - "button": (frozenset(scopingElements | set([(namespaces["html"], "button")])), False), - "list": (frozenset(scopingElements | set([(namespaces["html"], "ol"), - (namespaces["html"], "ul")])), False), + "button": (frozenset(scopingElements | {(namespaces["html"], "button")}), False), + "list": (frozenset(scopingElements | {(namespaces["html"], "ol"), + (namespaces["html"], "ul")}), False), "table": (frozenset([(namespaces["html"], "html"), (namespaces["html"], "table")]), False), "select": (frozenset([(namespaces["html"], "optgroup"), @@ -28,7 +28,7 @@ class Node(object): :arg name: The tag name associated with the node """ - # The tag name assocaited with the node + # The tag name associated with the node self.name = name # The parent of the current node (or None for the document node) self.parent = None diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/etree.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/etree.py index 0dedf44..ea92dc3 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/etree.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/etree.py @@ -5,6 +5,8 @@ from pip._vendor.six import text_type import re +from copy import copy + from . import base from .. import _ihatexml from .. import constants @@ -61,16 +63,17 @@ def getETreeBuilder(ElementTreeImplementation, fullTree=False): return self._element.attrib def _setAttributes(self, attributes): - # Delete existing attributes first - # XXX - there may be a better way to do this... - for key in list(self._element.attrib.keys()): - del self._element.attrib[key] - for key, value in attributes.items(): - if isinstance(key, tuple): - name = "{%s}%s" % (key[2], key[1]) - else: - name = key - self._element.set(name, value) + el_attrib = self._element.attrib + el_attrib.clear() + if attributes: + # calling .items _always_ allocates, and the above truthy check is cheaper than the + # allocation on average + for key, value in attributes.items(): + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], key[1]) + else: + name = key + el_attrib[name] = value attributes = property(_getAttributes, _setAttributes) @@ -129,8 +132,8 @@ def getETreeBuilder(ElementTreeImplementation, fullTree=False): def cloneNode(self): element = type(self)(self.name, self.namespace) - for name, value in self.attributes.items(): - element.attributes[name] = value + if self._element.attrib: + element._element.attrib = copy(self._element.attrib) return element def reparentChildren(self, newParent): diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py index ca12a99..f037759 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py @@ -16,6 +16,11 @@ import warnings import re import sys +try: + from collections.abc import MutableMapping +except ImportError: + from collections import MutableMapping + from . import base from ..constants import DataLossWarning from .. import constants @@ -23,6 +28,7 @@ from . import etree as etree_builders from .. import _ihatexml import lxml.etree as etree +from pip._vendor.six import PY3, binary_type fullTree = True @@ -44,7 +50,11 @@ class Document(object): self._childNodes = [] def appendChild(self, element): - self._elementTree.getroot().addnext(element._element) + last = self._elementTree.getroot() + for last in self._elementTree.getroot().itersiblings(): + pass + + last.addnext(element._element) def _getChildNodes(self): return self._childNodes @@ -185,26 +195,37 @@ class TreeBuilder(base.TreeBuilder): infosetFilter = self.infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) self.namespaceHTMLElements = namespaceHTMLElements - class Attributes(dict): - def __init__(self, element, value=None): - if value is None: - value = {} + class Attributes(MutableMapping): + def __init__(self, element): self._element = element - dict.__init__(self, value) # pylint:disable=non-parent-init-called - for key, value in self.items(): - if isinstance(key, tuple): - name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) - else: - name = infosetFilter.coerceAttribute(key) - self._element._element.attrib[name] = value - def __setitem__(self, key, value): - dict.__setitem__(self, key, value) + def _coerceKey(self, key): if isinstance(key, tuple): name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) else: name = infosetFilter.coerceAttribute(key) - self._element._element.attrib[name] = value + return name + + def __getitem__(self, key): + value = self._element._element.attrib[self._coerceKey(key)] + if not PY3 and isinstance(value, binary_type): + value = value.decode("ascii") + return value + + def __setitem__(self, key, value): + self._element._element.attrib[self._coerceKey(key)] = value + + def __delitem__(self, key): + del self._element._element.attrib[self._coerceKey(key)] + + def __iter__(self): + return iter(self._element._element.attrib) + + def __len__(self): + return len(self._element._element.attrib) + + def clear(self): + return self._element._element.attrib.clear() class Element(builder.Element): def __init__(self, name, namespace): @@ -225,8 +246,10 @@ class TreeBuilder(base.TreeBuilder): def _getAttributes(self): return self._attributes - def _setAttributes(self, attributes): - self._attributes = Attributes(self, attributes) + def _setAttributes(self, value): + attributes = self.attributes + attributes.clear() + attributes.update(value) attributes = property(_getAttributes, _setAttributes) @@ -234,8 +257,11 @@ class TreeBuilder(base.TreeBuilder): data = infosetFilter.coerceCharacters(data) builder.Element.insertText(self, data, insertBefore) - def appendChild(self, child): - builder.Element.appendChild(self, child) + def cloneNode(self): + element = type(self)(self.name, self.namespace) + if self._element.attrib: + element._element.attrib.update(self._element.attrib) + return element class Comment(builder.Comment): def __init__(self, data): diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py index 9bec207..b2d3aac 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py @@ -2,10 +2,10 @@ tree, generating tokens identical to those produced by the tokenizer module. -To create a tree walker for a new type of tree, you need to do +To create a tree walker for a new type of tree, you need to implement a tree walker object (called TreeWalker by convention) that -implements a 'serialize' method taking a tree as sole argument and -returning an iterator generating tokens. +implements a 'serialize' method which takes a tree as sole argument and +returns an iterator which generates tokens. """ from __future__ import absolute_import, division, unicode_literals diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-38.pyc index 4449dd915d5ceb50f9cd6463cb0fe1a5b992b796..8d27bb5d173ddaaaf4e7e630921ba8694b6b9d0d 100644 GIT binary patch delta 154 zcmew-w?dvbl$V!_0SGkz?TQbd$XmzQI<e>M<QT?u?(&Sx<P3$9#O&1K$tM|=Ws4OO z^As{mQi~Ex@{1H8vgxULAbx7`W;Uj1R_A>EjQreG{i4d!(yUDV;-X~zl*GKu)STq} wBA^<*ipnbevedjX{hZ7s{esGpjQl)fJq!I}prN`2iOJcC=|F?(+5fWx09XGv*#H0l delta 112 zcmZ1>|4)uLl$V!_0SKO#ZHNn+$XmzQFtO(>lS0bm2*wPylEm!Hy!6SZ8I`4gv_fK@ zLS{*7QDRAckwSWE9*6}L-ptJu%_`@mUy@s(Uyxa#o0(T!l9-dDYm{M9T49`@2ol`9 IlKnqB084l$6951J diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-38.pyc index 82327ddbadb47d95a55d0c2944d449e76afb3212..b200fe5b547a8f53709c0bc955dc27c9f4d7d9ac 100644 GIT binary patch delta 94 zcmdmHcH4|6l$V!_0SGkz?TX*XW5?{At)G#fo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5&)gZZ2|0ObWCYXATM delta 57 zcmca@w#|$ul$V!_0SKO#ZHU{*W5+D#reBg<pkI(#pqrUjT#}fRqid95Qd(i0p9m7% J+{=7U9032w688WA diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-38.pyc index 8434bef13066dcebde4de81628f9edeb2c5106b2..fba16ba5fa9b60bc3c07b4db7c9bd102c36b3b2e 100644 GIT binary patch delta 94 zcmbQwdxV!Kl$V!_0SGkz?TX*X)6DFgrJs?Xo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5(lE%PTP0L%>`g8%>k delta 57 zcmX@YJD-;)l$V!_0SKO#ZHU{*)66XAs$Y^@pkI(#pqrUjT#}fRqid95Qd(i0p9m7% Je2MuJ69Dgg6Au6Y diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-38.pyc index 379d041e10be5dad6e8bd958a09c58c4b46b1882..b584c361fc82f4764fbe0a3f596b9cd04aacb7fe 100644 GIT binary patch delta 646 zcmY+BKX21O7{+@Fwo~w>sniY-fhv(!xQMuEXelfVNrnz-BIFLuQeEv+YVbe3wxfil z1I$S17B=RNkO2vanU8>U0}>+=p8>enf)H-_>G3`HJnt*{P3=>S9#eXCNgeCw$J5X6 z=!odD#8S_Fy}CAgMc$XHl6Ly-<6ig3IepUaJ5mg^$@LYL7?%GULqjR&WY7gFzG>p_ zE#=DPh=n{&n9BiQOO0h2r1A=0OKr@8oL>?t-s(5nfqfo_+=gkMKlSYtT-#%j&jUAx zjHivs^tnCe(bx|BGdr1P=W*0(9N4L!@q4QO85{9*_C@cJJyQ(=iXaM>25YF-=eKpG zq|TCrN8Y6ln`mr_lX9(Uq1>6HIeS^Ilg_*fD$4r)OC2zj`mY&Fp@qOla38VQ^kca~ zE{djyXcc+m-)6Fu#0hLDOKNVMM;X)#?MEJ;SjL|vF}a7>M?65_%2H1laFtmYh}U$) zvq9k;#U2lr#Pr&W`Yxsp5RVX#5k;;sS52{D-d^pfZ%dO#I}SrEUlESEt^U=8d8dlr uLaHe~m|Nsfd^PvUP^{C|_Dy_ns30q9iLL{j_hK&(_`;6G)TRKsN%G(MzMs?p delta 609 zcmY+BPcH*O7{*O%cZ;2-6$dmV{zkEi;=o0sjZ?LeI@kl5bSE_F?oOs#sS5{piOhi$ z7nk19v#Sp=ad8sgLBhNns^;*^v+py{GjFob$(tnJ!??Fgo%fT6gO^8qgmgPXYEJno zG0?h1Pm#EdvxTj_d~T<7xLYWcY*Ex2Lot=GqrZl2C{@}o=C~=|G%=S{uI%xMOKXgj zDTmuqBSFAxvKz)yJ0aCNZ6aIT>BFPj>A+=aR$*4fs|BQ5wU&=p>Wz#~VA%T9^JukC zb#N1a6jB;bfbMTk$CQ#fVT^iCQ|IGgOo+2+GCmD*z74C@j839#yNY9FeSE3I4W<4y zLn%)K;1XX1bT%b=W9U3=S_Lc28-JV02=f^qQI^!oe%%ZBV5lpeLmMgMXGusd0hR$7 z0IV!^MmSZOjt60kk7!T~ogLqyZkM?2yO>;n)Cyn?umK2jb8TgboH>!$RNpC08e6{W zLU~M_nzQOR+?z9T@H$eKcr~X{Rz&a`l42caW{2TIRzb$p61ftmH19k0D(%=YeAN=y HcnSsIpmUBc diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-38.pyc index b0f9fd50c515e9654994c5db63d551704526aea9..b9d40733c86e3926ecdc585c62807ace9b6c0d0b 100644 GIT binary patch delta 2763 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 VB!#FSz8(!oa{PEa7MJ4#{{w6VGoSzf delta 2671 zcmZ`*S#KLv6!v%)&v<w2q>0j`ZPEod&DN$ZbV*CI(IrkHuGG4;gX5Vblg@bDJCn$f z+(xK8unAh-C*A@Q52*yI$O{q@LgE1={=o=%1i>#ryudkkk~pzkM|0-hIp^H7e&^<s zk<C-FTd`O;0KY$1UflokS*(lu`dQ!5nxKiMY$*kW3uuxSGQ(D+5P`Lz$*_(VqOex9 z@OyzmY$~8dwCH;QEvm<#@P!2IV_F>cakfvwKA|OHpVSk;Pr*K=wZOiG@mpY@)-tfq z=#ix~NMy8DVK$I$d-nG@y~w@jO@Vj+-WYVP%3#H)^c!WzEt+Qk$;FZ7>M6U3AL;4f zc`iyH2Gd-cK2CORei3|!gC#FG9jHziX@Qj|tEy2pTvctOp9<zkD}2jxqzzshL2>{k z_y_u`uTa;DsOp058m?}s>M$J?FC9TeCbhvawFV8cANV7bilfJrZAo%;XH`Erq^hP~ zR@JlgAMx^~9+WtO1og=)dlh!HNCp__fg=NvIk{8jWu9a(c3O~of~1{(D_twH=p;`e zw(Y8AThl$ET(or30a~8otU4Hwp^+}wlWrhc(GTVXe&|PnqGSLGvtD-rUA;g{p*N2o zgH<+2m<}egS)44M3Hp2Jz~wB897ocJgoVtatsAIYX$O(>@Hhex2vmW{{2-rmDJm+5 zJL^eh^$lMz4aY6nR%P@$9aqi`GLPy3`bB01_akEZsLDLKM!!-fdv}Wa(ok}=E!=Zr z5Y?KwJp_!a@NBy+kRj&wyWzXsF#RpOdav%0#4_jc_S}*eS}Zz6*Ciy4C)Z_oR+d6+ zo)i}>z3i%3QF3~(`JEtU>1O2KMOOTv7lOuRN1`;8347cxZQXH}IlsqIR8>_v9j#5V z!V2}mdZJO*^s2{0$7Z)&k{x5tG|CH(#~WI8S2CD4Sl2n4jO7_#0BFqR-X?xy(=UP5 zL-cuUaA?bSVa~QqU#DK?o#sF+qkyVfREbYzQE69A8^Ti{50xT;<W=ZuJU4*S8$pkE zAluBVW)=XQzz0JANOaS5VxW&1xrCOQ$wLm8%SH*1rm8CtO*j28aq>9oK<3Y(*2_#W ztgnKZV{6R-@+#^wl(6Y=5x1jAUPp2T$xDaDFmT_3$H9^ShN3VmWE>d&A3=Tzo~<AK zIQhLl7o#K&-#h^k1&PvKFS*@-V~d8VK{5$;IvYnMOdqHAUtw^Lz{f)DYI)uUrAfnd zb>d0$?7h{2p5PK)Z)_J-eoTK&O>j>)ds=udY6KohZfA{K+P~gKPo?`)`I=mlYW#Y) zCVbA}n?6i;yw>9KO9yH~EwFTO{ZLH=j^y^#xF?(zdLTUID(}Myt@Gk+KnuXlBIh=O zTiBvMrib?7fd1=0_>m9>!vV?mk~j@#I@j=SEC~6D+j$?7XHf#DZ$TcP8M`$-k;@aD zQH2m}^LK7eG)_%SE;)mQRsII9Bp_aB%(f89u$Y-<=OElYX`&4G%xXb`ldtCY-61&P zJ<%$<rA1F#Aog;_A>;IiOz+woz$rxLiEZ7s%pA^j?69ojL;Mh|$zde3Ks*Hpzf&oe zbb>y3A_CoE-g@Fn(OhmUh8G9G<e-zsVSX5<^8si%*m40b%*kAaqjRkXIe|WD{b_~` zDwa2qwG7FD7@0xBnjZPvqlfv`fXx_~nly;xvbOq$e%AJ4?HX!dN3wIee?>`6O)zZW z6}I6ICQ^^T!5E86ue!7T;Q9`97&5lw0#tBvkp8^yqv^dqz~zW|*cIF)ZW#>k;i|z9 zMs<@-98BXcbiMt|-DcRni@I+kxsOEMdlWmA4bw4TJc7r;rUV}&a#mL4B*E{wY%3k^ z=<N0q@bA!ox}ujgn+!Ncm59Iv2v;qWNVL|`US$mxAb1Etpt8pHB)ER`lIuemJK9I~ tFs`PMpp{(_?zrX27c5&_HuX_#00*zz3>OVX@d-wGSxFvE#*<32?|*o}41E9q diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-38.pyc index b9c6943c65d02a4f48a55779abf678e5d1055182..f60fce93be4c323dbe7df504b6674cd6c7895a45 100644 GIT binary patch delta 94 zcmdnX_lS=tl$V!_0SGkz?TX*XQ_bX@tDljdo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5(lDboxV0N?T<S^xk5 delta 57 zcmaFFx0jD6l$V!_0SKO#ZHU{*Q_Upjp<j|)pkI(#pqrUjT#}fRqid95Qd(i0p9m7% Je2QrX3jq5`66OE^ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/etree.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/etree.py index 95fc0c1..837b27e 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/etree.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/etree.py @@ -127,4 +127,5 @@ def getETreeBuilder(ElementTreeImplementation): return locals() + getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py index e81ddf3..c56af39 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py @@ -1,6 +1,8 @@ from __future__ import absolute_import, division, unicode_literals from pip._vendor.six import text_type +from collections import OrderedDict + from lxml import etree from ..treebuilders.etree import tag_regexp @@ -163,7 +165,7 @@ class TreeWalker(base.NonRecursiveTreeWalker): else: namespace = None tag = ensure_str(node.tag) - attrs = {} + attrs = OrderedDict() for name, value in list(node.attrib.items()): name = ensure_str(name) value = ensure_str(value) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-38.pyc index ec919484d1d495f5c7fd1a1e9d44651bf9334eef..603344f4a19ec05e9337b208d8593f6d453229f0 100644 GIT binary patch delta 91 zcmcb`_@9v{l$V!_0SGkz?TVksQ|BD7pOK%Ns$W!DTAG!qUtE-|pOToDnVOTFUsRG> ttXEN4rC*ksSEiqnnWSG(S(1^TXRK$TUz}Nzs#}nloSm4ST0C)u5df9vAi@9u delta 54 zcmey*c#DxIl$V!_0SKO#ZHSx5QzvJoUy@s(Uyxa#o0(T!l9-dDYm{M9T49`@2ojul G)(8O4+!9Uz diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-38.pyc index 39ceb26ad3a9a5da4ab2a64a6018e288708b13f8..d1656247bde24299cb427ba4a0b15630cc9be3a7 100644 GIT binary patch delta 94 zcmdlXc2|ril$V!_0SGkz?TX*XBgEt!qo0wVo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5)whUpIn0KKgs<p2Nx delta 57 zcmcaBwnL03l$V!_0SKO#ZHU{*Bg7<Uu3wT{pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JoXGTt0|4pB5^(?k diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-38.pyc index cf382dbc2dc89ac07adf9ea0356322bb367320c7..eab2a2872d93064f012dd8272f02257db8f06077 100644 GIT binary patch delta 92 zcmX@d@|lGvl$V!_0SGkz?TVksGtW6zKO;XkRllgRv@|PIzqlw_KP53QGc_kUzo;a& uSg)e8O1~^MuS`EDGfBUovLquv&sfhwzc{lbRkt89IXf{uwRq!+HbwxtSRrEo delta 55 zcmey&a*l;3l$V!_0SKO#ZHSx5Gf&P!za+OnzaX<fH#4ueBrzvP*C@lJw8A()5hS?r HZ5ty1<Q)?4 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/core.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/core.cpython-38.pyc index f875e74645ccfcaca49673b45d7b47f1efa0d598..737c6c4b25c54fc15f509056464d96680c9369a3 100644 GIT binary patch delta 405 zcmYLFJ4*vW5Z+l6ji&~&k;F$<5kW|Dg$NdDM9{(~iXvFZ<#zSXTz13WUgAkaFbXyn zlFrJMBKW$_|6*$s@F$2H6r5q;W4;H>JT0}ClRE<g2GTY2{eJMAzfA@Zf4ywO;=bvK zGBafu1jnxFOWULtcbR7kshFQX2~W)`<5kmhi)JNMj^MNTdDC|l%T+A9WF0X-y1^U6 z@Y4K9ZJl4&k?K{622gZ`Q|JuUk?$#k;s#tm9o_d)XaVg?AsQ=Td8e6phv7piUPlc8 zt^d_*|Dx^|oS}bi8_o2r%Zk3^bZ*V^4uvc;N)~dSRb*b4@LfSR10LFfGQvFf$Srz| z*n%s@6*&|Er*c)B<w_@E^3O-gfv*S`iZD(|%~cMuh!a*E#^reDW&O=CU4WkEYkE2} zr56Y%0Yg%E0t~DN1|g>L5E#){`W-_ddKfEU*o!_hkI-EMg#2u?of(PVCTb8*8KXw# E2TT%kivR!s delta 209 zcmaFuzRry=l$V!_0SKO#ZHT+7JCU!Hk!fSgYeqRU{gT`Q{esK_-ORk=lEj=GU84+> z(hB4JM3CU-O-%mcj9rtNq=LMXY8Xm5OE{VtQy5yABpGTM@`OrQYZ#gt85wFA7I397 zE@TXbu$UGy)-oXEf*CZK{fY{JmKVtZ2~F<Fn$k9tv!s>8Wk4=s;$viD<O4zuMlL2G oW)#}IT6z}~qs8VlIU6R%kj;w~Rx>gdZ}wN3&d4gtCBr2T0M#}#6951J diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-38.pyc index 5f6d491a1d98aff8df906e22c3fb13dda298ade7..440391d1ae94c161ef42bded95e2a108edd4f7de 100644 GIT binary patch delta 1485 zcmYk6Uu;uV9LLW&cel6yJ2%Bi2<u?5O}AbqMrQ?9%{rTvM$KlT#mL&-N-vIexh=#Y zvGc`XoC)#x1k)FhECdp|gMUCQ?bz6W#P~#bP#z>CYVbj0!kp9i`}N+Nc~A1`_j7)~ z-v8&`K1G+$(9V~AJ~x4_<KK&W$37?I4$A*Gr$k5uCh}oNsq+AnT^bDjDSL^(Dz6j2 zv-j9DPEFCAFlwb*#$?VQv1-mJka1wui|Hfj{brBmJ0?vlNv8R=fL5<PFfAn|tznRK zG#++zZx=zwCzLkwvNG(iB;ZV5q~u;5{Qko`om>5X<QS>+dd#WYe9#&5)~fMF2lO=Y z<IX&lx!={cp*B6(Es;pnM@DfE)PReN1xSaB_qnp3T0<5Zjz#%tSDY!5xbG@CLS-i* z`ej4~QANxlt{~<S3y7<TMRBtJ6-V)0fD*lgm_-Q0dBhipFA-lMzD8U?Tts|>xP<r? zQAS)wR1j6f9O4RM9<hM9idaM}A+7~n!0Q-qh~;%Ds_5}wC~5yt>}m3PsfTA<zoSdy zsV!5C4vG1;U#aZ#!TsRnjx?>~Ess{aKk&oN3y;G6AtxbjGvg_UADdA?oHk<_;`d_s zu@y<Kt|w%b52>%yzlBhj+|<jDgf~(@KM~&Ku5=SJ*-wcP5R2g%xp=7!p5#W^d=_Pp zKW(XitlBaU;%&Ctu7Lz?xdGB{%QDC<TiV+x`Pr5(kaIz62L%w)f+Bb%MCpDp_iR-P zp7t|B!cOyC&Vrn=Wfr6o=0~ET#)SaHT~^b5kjY;DSu{;!+|l1hdqljyKxvv+o`08K z;LpX9MdcAjR!6KqxItPqOCAK-X3N7ML$*8#GHlD!AV1jB2XfDrBuFG<?QI5R@(oLF zfy~roCp^8Mz_R<S(p``#TYA^SC1<Tl3}l0D$#IZ~E^fvir;buHT=P4e4qR`D!%`zV zJmx(*3bKR$IIwBpE~F_~fd($A+PYd+@S|Zh-t>Y5y=KMb19`%dW>{(@;v)vWdqzFH zf5G^ja90Xu>jGx~E|7{X16Yx*$_pSpwydO~;^C|DmYutGi5zXUnvx)qEtagj4g1Ok zh#}+Q@ateG2w1hma3S10w)=cyGe*S9UNxILkWr0^g9rEPYTg)8wbYoN86C+Pg-ky5 z*2H1;P-g6qI;yAD@rgn<H?}?0qvrKOrfWPk@@8sZCeK?FoejfqusX)JvWJ+5DQwoU jM~o**GA|}xi%ycY@t3nm)<!*B%XVsF5?kxH({KL)`5Zs+ delta 796 zcmYk4T}V_>5XaA)yL-KR-F4M1P$^a=b<H(*%_p_mzFf65D<fI^vM%Aq`q8>cS)hRr zN)giZ5N7H_h>%5cEcyUNB<Lx6sa~QCAC%aKs27uh=6YJ_49xugGjrx}?>Vbe@Oc8f z#~cow(OT|)a%y3Wu_aUdzrJ$D0+i^ATc^Ek+?r&N;V3^W6lH)brbtx=H#>&-$YO{a zDTdQXHPS|ukYc1CWreOD)$bSW>V1GTv}<Qlp4HK?24Hau#qZdo<-<pOtW~38i-HBa zZ3WJVS%Rp-ShbTCYWTv|ire%WzR1NDeOeVK(i&A!nQ;=h=b{+TwA;akkMiEathknc zlS7lR6@G(Mi-V?=MQ93h5N^QLt!F{Q=A!xD!4$?em9Lj>5PBruA}o`5m#{(NIH4i& z0b#$y3Bo%PCkaO+P7zK@6ofMpUlP8PI7=8W7xms>3Lfz_!J2sJd!uKYH?aQE_k48N z9*|;;M2ti<8L=W)f8}SauZpBy%vDTUU8@DaKDn*3*W&@U;ui0B?*ce4HtwBQ@K03% z?hH0V5Ql^NARxX3V*sbIvF18F#}73jm1T1F`y9Tm&2jZ-aTW+`a@H`3j0+-OTMAfo za3Otv2R(txWLfMb5x8BKoAV=y{%qi1_NPuF+b&z&ezW4hNZk?+)n^qQ2rF!0i&GXu zBm#L(7B%lUYBil|x+K$SxLiNuahqtmwepf!TW3jUxU)Fi-W6+!M2bsW%Pw8s-qB(v wapjOVU8mg^&hxp8Cv%lQRgVi_!<=<TA4}M{*2@ys$`h1`SGmFyoryU37hTo40{{R3 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-38.pyc index b93de18a61ca4ca4d811cc346db1dcb271acb413..d3df767b8f2b982e8a9fc12beb7e73fbb93b1430 100644 GIT binary patch delta 94 zcmaFG+t0@n%FD~e00f%<cExYx+0N{opr4VSo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5*5Au}g40N_y}5C8xG delta 57 zcmeC@d&SEW%FD~e00hs=HpFe@+0HCytzVK`pkI(#pqrUjT#}fRqid95Qd(i0p9m7% J%*MjW3;^|D5uE@4 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-38.pyc index 8aa86b0ddcf68ff53ea363508c23d0a210e3de8c..d2017f91e3f0652b85395aad2b3d011b11fac43d 100644 GIT binary patch delta 101 zcmZ3(c!`lWl$V!_0SGkz?TQzh$g9K3Vx(tiFws`lIaxm=KQ~pssIs&)D^tI?C|N%x zF)uSUCpo{UB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+H_-Vuc9+ D8A>6z delta 63 zcmcb_xQ3B8l$V!_0SKO#ZHN<{$g9J`Y@}x~(N0#*PQN6#K))cfKsPh5xFj(rN7pFB Pq_n~~KM^E2ah?eP9$pg~ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-38.pyc index 3a06faaae3dac03dbb62c88638c3982a6826761b..e1f03a309112c22fa6c4c09b592ce2170b009653 100644 GIT binary patch delta 11866 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 delta 9250 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/idna/core.py b/venv/lib/python3.8/site-packages/pip/_vendor/idna/core.py index 104624a..41ec5c7 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/idna/core.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/idna/core.py @@ -9,7 +9,7 @@ _virama_combining_class = 9 _alabel_prefix = b'xn--' _unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') -if sys.version_info[0] == 3: +if sys.version_info[0] >= 3: unicode = str unichr = chr @@ -300,6 +300,10 @@ def ulabel(label): label = label.lower() if label.startswith(_alabel_prefix): label = label[len(_alabel_prefix):] + if not label: + raise IDNAError('Malformed A-label, no Punycode eligible content found') + if label.decode('ascii')[-1] == '-': + raise IDNAError('A-label must not end with a hyphen') else: check_label(label) return label.decode('ascii') diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/idna/idnadata.py b/venv/lib/python3.8/site-packages/pip/_vendor/idna/idnadata.py index a80c959..a284e4c 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/idna/idnadata.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/idna/idnadata.py @@ -1,6 +1,6 @@ # This file is automatically generated by tools/idna-data -__version__ = "11.0.0" +__version__ = "13.0.0" scripts = { 'Greek': ( 0x37000000374, @@ -48,16 +48,18 @@ scripts = { 0x300700003008, 0x30210000302a, 0x30380000303c, - 0x340000004db6, - 0x4e0000009ff0, + 0x340000004dc0, + 0x4e0000009ffd, 0xf9000000fa6e, 0xfa700000fada, - 0x200000002a6d7, + 0x16ff000016ff2, + 0x200000002a6de, 0x2a7000002b735, 0x2b7400002b81e, 0x2b8200002cea2, 0x2ceb00002ebe1, 0x2f8000002fa1e, + 0x300000003134b, ), 'Hebrew': ( 0x591000005c8, @@ -74,6 +76,7 @@ scripts = { 0x304100003097, 0x309d000030a0, 0x1b0010001b11f, + 0x1b1500001b153, 0x1f2000001f201, ), 'Katakana': ( @@ -85,6 +88,7 @@ scripts = { 0xff660000ff70, 0xff710000ff9e, 0x1b0000001b001, + 0x1b1640001b168, ), } joining_types = { @@ -387,9 +391,9 @@ joining_types = { 0x853: 68, 0x854: 82, 0x855: 68, - 0x856: 85, - 0x857: 85, - 0x858: 85, + 0x856: 82, + 0x857: 82, + 0x858: 82, 0x860: 68, 0x861: 85, 0x862: 68, @@ -430,6 +434,16 @@ joining_types = { 0x8bb: 68, 0x8bc: 68, 0x8bd: 68, + 0x8be: 68, + 0x8bf: 68, + 0x8c0: 68, + 0x8c1: 68, + 0x8c2: 68, + 0x8c3: 68, + 0x8c4: 68, + 0x8c5: 68, + 0x8c6: 68, + 0x8c7: 68, 0x8e2: 85, 0x1806: 85, 0x1807: 68, @@ -754,6 +768,34 @@ joining_types = { 0x10f52: 68, 0x10f53: 68, 0x10f54: 82, + 0x10fb0: 68, + 0x10fb1: 85, + 0x10fb2: 68, + 0x10fb3: 68, + 0x10fb4: 82, + 0x10fb5: 82, + 0x10fb6: 82, + 0x10fb7: 85, + 0x10fb8: 68, + 0x10fb9: 82, + 0x10fba: 82, + 0x10fbb: 68, + 0x10fbc: 68, + 0x10fbd: 82, + 0x10fbe: 68, + 0x10fbf: 68, + 0x10fc0: 85, + 0x10fc1: 68, + 0x10fc2: 82, + 0x10fc3: 82, + 0x10fc4: 68, + 0x10fc5: 85, + 0x10fc6: 85, + 0x10fc7: 85, + 0x10fc8: 85, + 0x10fc9: 82, + 0x10fca: 68, + 0x10fcb: 76, 0x110bd: 85, 0x110cd: 85, 0x1e900: 68, @@ -824,6 +866,7 @@ joining_types = { 0x1e941: 68, 0x1e942: 68, 0x1e943: 68, + 0x1e94b: 84, } codepoint_classes = { 'PVALID': ( @@ -1126,7 +1169,7 @@ codepoint_classes = { 0x8400000085c, 0x8600000086b, 0x8a0000008b5, - 0x8b6000008be, + 0x8b6000008c8, 0x8d3000008e2, 0x8e300000958, 0x96000000964, @@ -1185,7 +1228,7 @@ codepoint_classes = { 0xb3c00000b45, 0xb4700000b49, 0xb4b00000b4e, - 0xb5600000b58, + 0xb5500000b58, 0xb5f00000b64, 0xb6600000b70, 0xb7100000b72, @@ -1230,8 +1273,7 @@ codepoint_classes = { 0xce000000ce4, 0xce600000cf0, 0xcf100000cf3, - 0xd0000000d04, - 0xd0500000d0d, + 0xd0000000d0d, 0xd0e00000d11, 0xd1200000d45, 0xd4600000d49, @@ -1240,7 +1282,7 @@ codepoint_classes = { 0xd5f00000d64, 0xd6600000d70, 0xd7a00000d80, - 0xd8200000d84, + 0xd8100000d84, 0xd8500000d97, 0xd9a00000db2, 0xdb300000dbc, @@ -1258,18 +1300,11 @@ codepoint_classes = { 0xe5000000e5a, 0xe8100000e83, 0xe8400000e85, - 0xe8700000e89, - 0xe8a00000e8b, - 0xe8d00000e8e, - 0xe9400000e98, - 0xe9900000ea0, - 0xea100000ea4, + 0xe8600000e8b, + 0xe8c00000ea4, 0xea500000ea6, - 0xea700000ea8, - 0xeaa00000eac, - 0xead00000eb3, - 0xeb400000eba, - 0xebb00000ebe, + 0xea700000eb3, + 0xeb400000ebe, 0xec000000ec5, 0xec600000ec7, 0xec800000ece, @@ -1362,6 +1397,7 @@ codepoint_classes = { 0x1a9000001a9a, 0x1aa700001aa8, 0x1ab000001abe, + 0x1abf00001ac1, 0x1b0000001b4c, 0x1b5000001b5a, 0x1b6b00001b74, @@ -1370,7 +1406,7 @@ codepoint_classes = { 0x1c4000001c4a, 0x1c4d00001c7e, 0x1cd000001cd3, - 0x1cd400001cfa, + 0x1cd400001cfb, 0x1d0000001d2c, 0x1d2f00001d30, 0x1d3b00001d3c, @@ -1613,10 +1649,10 @@ codepoint_classes = { 0x30a1000030fb, 0x30fc000030ff, 0x310500003130, - 0x31a0000031bb, + 0x31a0000031c0, 0x31f000003200, - 0x340000004db6, - 0x4e0000009ff0, + 0x340000004dc0, + 0x4e0000009ffd, 0xa0000000a48d, 0xa4d00000a4fe, 0xa5000000a60d, @@ -1727,8 +1763,15 @@ codepoint_classes = { 0xa7b50000a7b6, 0xa7b70000a7b8, 0xa7b90000a7ba, - 0xa7f70000a7f8, + 0xa7bb0000a7bc, + 0xa7bd0000a7be, + 0xa7bf0000a7c0, + 0xa7c30000a7c4, + 0xa7c80000a7c9, + 0xa7ca0000a7cb, + 0xa7f60000a7f8, 0xa7fa0000a828, + 0xa82c0000a82d, 0xa8400000a874, 0xa8800000a8c6, 0xa8d00000a8da, @@ -1753,7 +1796,7 @@ codepoint_classes = { 0xab200000ab27, 0xab280000ab2f, 0xab300000ab5b, - 0xab600000ab66, + 0xab600000ab6a, 0xabc00000abeb, 0xabec0000abee, 0xabf00000abfa, @@ -1827,9 +1870,14 @@ codepoint_classes = { 0x10cc000010cf3, 0x10d0000010d28, 0x10d3000010d3a, + 0x10e8000010eaa, + 0x10eab00010ead, + 0x10eb000010eb2, 0x10f0000010f1d, 0x10f2700010f28, 0x10f3000010f51, + 0x10fb000010fc5, + 0x10fe000010ff7, 0x1100000011047, 0x1106600011070, 0x1107f000110bb, @@ -1837,12 +1885,12 @@ codepoint_classes = { 0x110f0000110fa, 0x1110000011135, 0x1113600011140, - 0x1114400011147, + 0x1114400011148, 0x1115000011174, 0x1117600011177, 0x11180000111c5, 0x111c9000111cd, - 0x111d0000111db, + 0x111ce000111db, 0x111dc000111dd, 0x1120000011212, 0x1121300011238, @@ -1871,7 +1919,7 @@ codepoint_classes = { 0x1137000011375, 0x114000001144b, 0x114500001145a, - 0x1145e0001145f, + 0x1145e00011462, 0x11480000114c6, 0x114c7000114c8, 0x114d0000114da, @@ -1881,18 +1929,28 @@ codepoint_classes = { 0x1160000011641, 0x1164400011645, 0x116500001165a, - 0x11680000116b8, + 0x11680000116b9, 0x116c0000116ca, 0x117000001171b, 0x1171d0001172c, 0x117300001173a, 0x118000001183b, 0x118c0000118ea, - 0x118ff00011900, + 0x118ff00011907, + 0x119090001190a, + 0x1190c00011914, + 0x1191500011917, + 0x1191800011936, + 0x1193700011939, + 0x1193b00011944, + 0x119500001195a, + 0x119a0000119a8, + 0x119aa000119d8, + 0x119da000119e2, + 0x119e3000119e5, 0x11a0000011a3f, 0x11a4700011a48, - 0x11a5000011a84, - 0x11a8600011a9a, + 0x11a5000011a9a, 0x11a9d00011a9e, 0x11ac000011af9, 0x11c0000011c09, @@ -1916,6 +1974,7 @@ codepoint_classes = { 0x11d9300011d99, 0x11da000011daa, 0x11ee000011ef7, + 0x11fb000011fb1, 0x120000001239a, 0x1248000012544, 0x130000001342f, @@ -1931,13 +1990,18 @@ codepoint_classes = { 0x16b6300016b78, 0x16b7d00016b90, 0x16e6000016e80, - 0x16f0000016f45, - 0x16f5000016f7f, + 0x16f0000016f4b, + 0x16f4f00016f88, 0x16f8f00016fa0, 0x16fe000016fe2, - 0x17000000187f2, - 0x1880000018af3, + 0x16fe300016fe5, + 0x16ff000016ff2, + 0x17000000187f8, + 0x1880000018cd6, + 0x18d0000018d09, 0x1b0000001b11f, + 0x1b1500001b153, + 0x1b1640001b168, 0x1b1700001b2fc, 0x1bc000001bc6b, 0x1bc700001bc7d, @@ -1955,15 +2019,22 @@ codepoint_classes = { 0x1e01b0001e022, 0x1e0230001e025, 0x1e0260001e02b, + 0x1e1000001e12d, + 0x1e1300001e13e, + 0x1e1400001e14a, + 0x1e14e0001e14f, + 0x1e2c00001e2fa, 0x1e8000001e8c5, 0x1e8d00001e8d7, - 0x1e9220001e94b, + 0x1e9220001e94c, 0x1e9500001e95a, - 0x200000002a6d7, + 0x1fbf00001fbfa, + 0x200000002a6de, 0x2a7000002b735, 0x2b7400002b81e, 0x2b8200002cea2, 0x2ceb00002ebe1, + 0x300000003134b, ), 'CONTEXTJ': ( 0x200c0000200e, diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/idna/package_data.py b/venv/lib/python3.8/site-packages/pip/_vendor/idna/package_data.py index 257e898..ce1c521 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/idna/package_data.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/idna/package_data.py @@ -1,2 +1,2 @@ -__version__ = '2.8' +__version__ = '2.10' diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/idna/uts46data.py b/venv/lib/python3.8/site-packages/pip/_vendor/idna/uts46data.py index a68ed4c..3766dd4 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/idna/uts46data.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/idna/uts46data.py @@ -4,7 +4,7 @@ """IDNA Mapping Table from UTS46.""" -__version__ = "11.0.0" +__version__ = "13.0.0" def _seg_0(): return [ (0x0, '3'), @@ -1074,7 +1074,7 @@ def _seg_10(): (0x8A0, 'V'), (0x8B5, 'X'), (0x8B6, 'V'), - (0x8BE, 'X'), + (0x8C8, 'X'), (0x8D3, 'V'), (0x8E2, 'X'), (0x8E3, 'V'), @@ -1205,7 +1205,7 @@ def _seg_11(): (0xB49, 'X'), (0xB4B, 'V'), (0xB4E, 'X'), - (0xB56, 'V'), + (0xB55, 'V'), (0xB58, 'X'), (0xB5C, 'M', u'ଡ଼'), (0xB5D, 'M', u'ଢ଼'), @@ -1272,7 +1272,7 @@ def _seg_12(): (0xC64, 'X'), (0xC66, 'V'), (0xC70, 'X'), - (0xC78, 'V'), + (0xC77, 'V'), (0xC8D, 'X'), (0xC8E, 'V'), (0xC91, 'X'), @@ -1299,8 +1299,6 @@ def _seg_12(): (0xCF1, 'V'), (0xCF3, 'X'), (0xD00, 'V'), - (0xD04, 'X'), - (0xD05, 'V'), (0xD0D, 'X'), (0xD0E, 'V'), (0xD11, 'X'), @@ -1314,7 +1312,7 @@ def _seg_12(): (0xD64, 'X'), (0xD66, 'V'), (0xD80, 'X'), - (0xD82, 'V'), + (0xD81, 'V'), (0xD84, 'X'), (0xD85, 'V'), (0xD97, 'X'), @@ -1348,33 +1346,19 @@ def _seg_12(): (0xE83, 'X'), (0xE84, 'V'), (0xE85, 'X'), - (0xE87, 'V'), - (0xE89, 'X'), - (0xE8A, 'V'), + (0xE86, 'V'), (0xE8B, 'X'), - (0xE8D, 'V'), - (0xE8E, 'X'), - (0xE94, 'V'), - ] - -def _seg_13(): - return [ - (0xE98, 'X'), - (0xE99, 'V'), - (0xEA0, 'X'), - (0xEA1, 'V'), + (0xE8C, 'V'), (0xEA4, 'X'), (0xEA5, 'V'), (0xEA6, 'X'), (0xEA7, 'V'), - (0xEA8, 'X'), - (0xEAA, 'V'), - (0xEAC, 'X'), - (0xEAD, 'V'), (0xEB3, 'M', u'ໍາ'), (0xEB4, 'V'), - (0xEBA, 'X'), - (0xEBB, 'V'), + ] + +def _seg_13(): + return [ (0xEBE, 'X'), (0xEC0, 'V'), (0xEC5, 'X'), @@ -1459,10 +1443,6 @@ def _seg_13(): (0x1260, 'V'), (0x1289, 'X'), (0x128A, 'V'), - ] - -def _seg_14(): - return [ (0x128E, 'X'), (0x1290, 'V'), (0x12B1, 'X'), @@ -1479,6 +1459,10 @@ def _seg_14(): (0x12D8, 'V'), (0x1311, 'X'), (0x1312, 'V'), + ] + +def _seg_14(): + return [ (0x1316, 'X'), (0x1318, 'V'), (0x135B, 'X'), @@ -1563,15 +1547,11 @@ def _seg_14(): (0x1A7F, 'V'), (0x1A8A, 'X'), (0x1A90, 'V'), - ] - -def _seg_15(): - return [ (0x1A9A, 'X'), (0x1AA0, 'V'), (0x1AAE, 'X'), (0x1AB0, 'V'), - (0x1ABF, 'X'), + (0x1AC1, 'X'), (0x1B00, 'V'), (0x1B4C, 'X'), (0x1B50, 'V'), @@ -1583,6 +1563,10 @@ def _seg_15(): (0x1C3B, 'V'), (0x1C4A, 'X'), (0x1C4D, 'V'), + ] + +def _seg_15(): + return [ (0x1C80, 'M', u'в'), (0x1C81, 'M', u'д'), (0x1C82, 'M', u'о'), @@ -1592,10 +1576,57 @@ def _seg_15(): (0x1C87, 'M', u'ѣ'), (0x1C88, 'M', u'ꙋ'), (0x1C89, 'X'), + (0x1C90, 'M', u'ა'), + (0x1C91, 'M', u'ბ'), + (0x1C92, 'M', u'გ'), + (0x1C93, 'M', u'დ'), + (0x1C94, 'M', u'ე'), + (0x1C95, 'M', u'ვ'), + (0x1C96, 'M', u'ზ'), + (0x1C97, 'M', u'თ'), + (0x1C98, 'M', u'ი'), + (0x1C99, 'M', u'კ'), + (0x1C9A, 'M', u'ლ'), + (0x1C9B, 'M', u'მ'), + (0x1C9C, 'M', u'ნ'), + (0x1C9D, 'M', u'ო'), + (0x1C9E, 'M', u'პ'), + (0x1C9F, 'M', u'ჟ'), + (0x1CA0, 'M', u'რ'), + (0x1CA1, 'M', u'ს'), + (0x1CA2, 'M', u'ტ'), + (0x1CA3, 'M', u'უ'), + (0x1CA4, 'M', u'ფ'), + (0x1CA5, 'M', u'ქ'), + (0x1CA6, 'M', u'ღ'), + (0x1CA7, 'M', u'ყ'), + (0x1CA8, 'M', u'შ'), + (0x1CA9, 'M', u'ჩ'), + (0x1CAA, 'M', u'ც'), + (0x1CAB, 'M', u'ძ'), + (0x1CAC, 'M', u'წ'), + (0x1CAD, 'M', u'ჭ'), + (0x1CAE, 'M', u'ხ'), + (0x1CAF, 'M', u'ჯ'), + (0x1CB0, 'M', u'ჰ'), + (0x1CB1, 'M', u'ჱ'), + (0x1CB2, 'M', u'ჲ'), + (0x1CB3, 'M', u'ჳ'), + (0x1CB4, 'M', u'ჴ'), + (0x1CB5, 'M', u'ჵ'), + (0x1CB6, 'M', u'ჶ'), + (0x1CB7, 'M', u'ჷ'), + (0x1CB8, 'M', u'ჸ'), + (0x1CB9, 'M', u'ჹ'), + (0x1CBA, 'M', u'ჺ'), + (0x1CBB, 'X'), + (0x1CBD, 'M', u'ჽ'), + (0x1CBE, 'M', u'ჾ'), + (0x1CBF, 'M', u'ჿ'), (0x1CC0, 'V'), (0x1CC8, 'X'), (0x1CD0, 'V'), - (0x1CFA, 'X'), + (0x1CFB, 'X'), (0x1D00, 'V'), (0x1D2C, 'M', u'a'), (0x1D2D, 'M', u'æ'), @@ -1636,6 +1667,10 @@ def _seg_15(): (0x1D50, 'M', u'm'), (0x1D51, 'M', u'ŋ'), (0x1D52, 'M', u'o'), + ] + +def _seg_16(): + return [ (0x1D53, 'M', u'ɔ'), (0x1D54, 'M', u'ᴖ'), (0x1D55, 'M', u'ᴗ'), @@ -1667,10 +1702,6 @@ def _seg_15(): (0x1D9C, 'M', u'c'), (0x1D9D, 'M', u'ɕ'), (0x1D9E, 'M', u'ð'), - ] - -def _seg_16(): - return [ (0x1D9F, 'M', u'ɜ'), (0x1DA0, 'M', u'f'), (0x1DA1, 'M', u'ɟ'), @@ -1740,6 +1771,10 @@ def _seg_16(): (0x1E1E, 'M', u'ḟ'), (0x1E1F, 'V'), (0x1E20, 'M', u'ḡ'), + ] + +def _seg_17(): + return [ (0x1E21, 'V'), (0x1E22, 'M', u'ḣ'), (0x1E23, 'V'), @@ -1771,10 +1806,6 @@ def _seg_16(): (0x1E3D, 'V'), (0x1E3E, 'M', u'ḿ'), (0x1E3F, 'V'), - ] - -def _seg_17(): - return [ (0x1E40, 'M', u'ṁ'), (0x1E41, 'V'), (0x1E42, 'M', u'ṃ'), @@ -1844,6 +1875,10 @@ def _seg_17(): (0x1E82, 'M', u'ẃ'), (0x1E83, 'V'), (0x1E84, 'M', u'ẅ'), + ] + +def _seg_18(): + return [ (0x1E85, 'V'), (0x1E86, 'M', u'ẇ'), (0x1E87, 'V'), @@ -1875,10 +1910,6 @@ def _seg_17(): (0x1EA6, 'M', u'ầ'), (0x1EA7, 'V'), (0x1EA8, 'M', u'ẩ'), - ] - -def _seg_18(): - return [ (0x1EA9, 'V'), (0x1EAA, 'M', u'ẫ'), (0x1EAB, 'V'), @@ -1948,6 +1979,10 @@ def _seg_18(): (0x1EEB, 'V'), (0x1EEC, 'M', u'ử'), (0x1EED, 'V'), + ] + +def _seg_19(): + return [ (0x1EEE, 'M', u'ữ'), (0x1EEF, 'V'), (0x1EF0, 'M', u'ự'), @@ -1979,10 +2014,6 @@ def _seg_18(): (0x1F18, 'M', u'ἐ'), (0x1F19, 'M', u'ἑ'), (0x1F1A, 'M', u'ἒ'), - ] - -def _seg_19(): - return [ (0x1F1B, 'M', u'ἓ'), (0x1F1C, 'M', u'ἔ'), (0x1F1D, 'M', u'ἕ'), @@ -2052,6 +2083,10 @@ def _seg_19(): (0x1F82, 'M', u'ἂι'), (0x1F83, 'M', u'ἃι'), (0x1F84, 'M', u'ἄι'), + ] + +def _seg_20(): + return [ (0x1F85, 'M', u'ἅι'), (0x1F86, 'M', u'ἆι'), (0x1F87, 'M', u'ἇι'), @@ -2083,10 +2118,6 @@ def _seg_19(): (0x1FA1, 'M', u'ὡι'), (0x1FA2, 'M', u'ὢι'), (0x1FA3, 'M', u'ὣι'), - ] - -def _seg_20(): - return [ (0x1FA4, 'M', u'ὤι'), (0x1FA5, 'M', u'ὥι'), (0x1FA6, 'M', u'ὦι'), @@ -2156,6 +2187,10 @@ def _seg_20(): (0x1FF0, 'X'), (0x1FF2, 'M', u'ὼι'), (0x1FF3, 'M', u'ωι'), + ] + +def _seg_21(): + return [ (0x1FF4, 'M', u'ώι'), (0x1FF5, 'X'), (0x1FF6, 'V'), @@ -2187,10 +2222,6 @@ def _seg_20(): (0x2035, 'V'), (0x2036, 'M', u'‵‵'), (0x2037, 'M', u'‵‵‵'), - ] - -def _seg_21(): - return [ (0x2038, 'V'), (0x203C, '3', u'!!'), (0x203D, 'V'), @@ -2260,6 +2291,10 @@ def _seg_21(): (0x20F1, 'X'), (0x2100, '3', u'a/c'), (0x2101, '3', u'a/s'), + ] + +def _seg_22(): + return [ (0x2102, 'M', u'c'), (0x2103, 'M', u'°c'), (0x2104, 'V'), @@ -2291,10 +2326,6 @@ def _seg_21(): (0x2127, 'V'), (0x2128, 'M', u'z'), (0x2129, 'V'), - ] - -def _seg_22(): - return [ (0x212A, 'M', u'k'), (0x212B, 'M', u'å'), (0x212C, 'M', u'b'), @@ -2364,6 +2395,10 @@ def _seg_22(): (0x2177, 'M', u'viii'), (0x2178, 'M', u'ix'), (0x2179, 'M', u'x'), + ] + +def _seg_23(): + return [ (0x217A, 'M', u'xi'), (0x217B, 'M', u'xii'), (0x217C, 'M', u'l'), @@ -2395,10 +2430,6 @@ def _seg_22(): (0x244B, 'X'), (0x2460, 'M', u'1'), (0x2461, 'M', u'2'), - ] - -def _seg_23(): - return [ (0x2462, 'M', u'3'), (0x2463, 'M', u'4'), (0x2464, 'M', u'5'), @@ -2468,6 +2499,10 @@ def _seg_23(): (0x24B7, 'M', u'b'), (0x24B8, 'M', u'c'), (0x24B9, 'M', u'd'), + ] + +def _seg_24(): + return [ (0x24BA, 'M', u'e'), (0x24BB, 'M', u'f'), (0x24BC, 'M', u'g'), @@ -2499,10 +2534,6 @@ def _seg_23(): (0x24D6, 'M', u'g'), (0x24D7, 'M', u'h'), (0x24D8, 'M', u'i'), - ] - -def _seg_24(): - return [ (0x24D9, 'M', u'j'), (0x24DA, 'M', u'k'), (0x24DB, 'M', u'l'), @@ -2533,10 +2564,7 @@ def _seg_24(): (0x2B74, 'X'), (0x2B76, 'V'), (0x2B96, 'X'), - (0x2B98, 'V'), - (0x2BC9, 'X'), - (0x2BCA, 'V'), - (0x2BFF, 'X'), + (0x2B97, 'V'), (0x2C00, 'M', u'ⰰ'), (0x2C01, 'M', u'ⰱ'), (0x2C02, 'M', u'ⰲ'), @@ -2575,6 +2603,10 @@ def _seg_24(): (0x2C23, 'M', u'ⱓ'), (0x2C24, 'M', u'ⱔ'), (0x2C25, 'M', u'ⱕ'), + ] + +def _seg_25(): + return [ (0x2C26, 'M', u'ⱖ'), (0x2C27, 'M', u'ⱗ'), (0x2C28, 'M', u'ⱘ'), @@ -2603,10 +2635,6 @@ def _seg_24(): (0x2C6E, 'M', u'ɱ'), (0x2C6F, 'M', u'ɐ'), (0x2C70, 'M', u'ɒ'), - ] - -def _seg_25(): - return [ (0x2C71, 'V'), (0x2C72, 'M', u'ⱳ'), (0x2C73, 'V'), @@ -2679,6 +2707,10 @@ def _seg_25(): (0x2CBC, 'M', u'ⲽ'), (0x2CBD, 'V'), (0x2CBE, 'M', u'ⲿ'), + ] + +def _seg_26(): + return [ (0x2CBF, 'V'), (0x2CC0, 'M', u'ⳁ'), (0x2CC1, 'V'), @@ -2707,10 +2739,6 @@ def _seg_25(): (0x2CD8, 'M', u'ⳙ'), (0x2CD9, 'V'), (0x2CDA, 'M', u'ⳛ'), - ] - -def _seg_26(): - return [ (0x2CDB, 'V'), (0x2CDC, 'M', u'ⳝ'), (0x2CDD, 'V'), @@ -2757,7 +2785,7 @@ def _seg_26(): (0x2DD8, 'V'), (0x2DDF, 'X'), (0x2DE0, 'V'), - (0x2E4F, 'X'), + (0x2E53, 'X'), (0x2E80, 'V'), (0x2E9A, 'X'), (0x2E9B, 'V'), @@ -2783,6 +2811,10 @@ def _seg_26(): (0x2F0F, 'M', u'几'), (0x2F10, 'M', u'凵'), (0x2F11, 'M', u'刀'), + ] + +def _seg_27(): + return [ (0x2F12, 'M', u'力'), (0x2F13, 'M', u'勹'), (0x2F14, 'M', u'匕'), @@ -2811,10 +2843,6 @@ def _seg_26(): (0x2F2B, 'M', u'尸'), (0x2F2C, 'M', u'屮'), (0x2F2D, 'M', u'山'), - ] - -def _seg_27(): - return [ (0x2F2E, 'M', u'巛'), (0x2F2F, 'M', u'工'), (0x2F30, 'M', u'己'), @@ -2887,6 +2915,10 @@ def _seg_27(): (0x2F73, 'M', u'穴'), (0x2F74, 'M', u'立'), (0x2F75, 'M', u'竹'), + ] + +def _seg_28(): + return [ (0x2F76, 'M', u'米'), (0x2F77, 'M', u'糸'), (0x2F78, 'M', u'缶'), @@ -2915,10 +2947,6 @@ def _seg_27(): (0x2F8F, 'M', u'行'), (0x2F90, 'M', u'衣'), (0x2F91, 'M', u'襾'), - ] - -def _seg_28(): - return [ (0x2F92, 'M', u'見'), (0x2F93, 'M', u'角'), (0x2F94, 'M', u'言'), @@ -2991,6 +3019,10 @@ def _seg_28(): (0x3000, '3', u' '), (0x3001, 'V'), (0x3002, 'M', u'.'), + ] + +def _seg_29(): + return [ (0x3003, 'V'), (0x3036, 'M', u'〒'), (0x3037, 'V'), @@ -3019,10 +3051,6 @@ def _seg_28(): (0x3136, 'M', u'ᆭ'), (0x3137, 'M', u'ᄃ'), (0x3138, 'M', u'ᄄ'), - ] - -def _seg_29(): - return [ (0x3139, 'M', u'ᄅ'), (0x313A, 'M', u'ᆰ'), (0x313B, 'M', u'ᆱ'), @@ -3095,6 +3123,10 @@ def _seg_29(): (0x317E, 'M', u'ᄶ'), (0x317F, 'M', u'ᅀ'), (0x3180, 'M', u'ᅇ'), + ] + +def _seg_30(): + return [ (0x3181, 'M', u'ᅌ'), (0x3182, 'M', u'ᇱ'), (0x3183, 'M', u'ᇲ'), @@ -3123,15 +3155,9 @@ def _seg_29(): (0x319B, 'M', u'丙'), (0x319C, 'M', u'丁'), (0x319D, 'M', u'天'), - ] - -def _seg_30(): - return [ (0x319E, 'M', u'地'), (0x319F, 'M', u'人'), (0x31A0, 'V'), - (0x31BB, 'X'), - (0x31C0, 'V'), (0x31E4, 'X'), (0x31F0, 'V'), (0x3200, '3', u'(ᄀ)'), @@ -3201,6 +3227,10 @@ def _seg_30(): (0x3240, '3', u'(祭)'), (0x3241, '3', u'(休)'), (0x3242, '3', u'(自)'), + ] + +def _seg_31(): + return [ (0x3243, '3', u'(至)'), (0x3244, 'M', u'問'), (0x3245, 'M', u'幼'), @@ -3227,10 +3257,6 @@ def _seg_30(): (0x3261, 'M', u'ᄂ'), (0x3262, 'M', u'ᄃ'), (0x3263, 'M', u'ᄅ'), - ] - -def _seg_31(): - return [ (0x3264, 'M', u'ᄆ'), (0x3265, 'M', u'ᄇ'), (0x3266, 'M', u'ᄉ'), @@ -3305,6 +3331,10 @@ def _seg_31(): (0x32AB, 'M', u'学'), (0x32AC, 'M', u'監'), (0x32AD, 'M', u'企'), + ] + +def _seg_32(): + return [ (0x32AE, 'M', u'資'), (0x32AF, 'M', u'協'), (0x32B0, 'M', u'夜'), @@ -3331,10 +3361,6 @@ def _seg_31(): (0x32C5, 'M', u'6月'), (0x32C6, 'M', u'7月'), (0x32C7, 'M', u'8月'), - ] - -def _seg_32(): - return [ (0x32C8, 'M', u'9月'), (0x32C9, 'M', u'10月'), (0x32CA, 'M', u'11月'), @@ -3390,7 +3416,7 @@ def _seg_32(): (0x32FC, 'M', u'ヰ'), (0x32FD, 'M', u'ヱ'), (0x32FE, 'M', u'ヲ'), - (0x32FF, 'X'), + (0x32FF, 'M', u'令和'), (0x3300, 'M', u'アパート'), (0x3301, 'M', u'アルファ'), (0x3302, 'M', u'アンペア'), @@ -3409,6 +3435,10 @@ def _seg_32(): (0x330F, 'M', u'ガンマ'), (0x3310, 'M', u'ギガ'), (0x3311, 'M', u'ギニー'), + ] + +def _seg_33(): + return [ (0x3312, 'M', u'キュリー'), (0x3313, 'M', u'ギルダー'), (0x3314, 'M', u'キロ'), @@ -3435,10 +3465,6 @@ def _seg_32(): (0x3329, 'M', u'ノット'), (0x332A, 'M', u'ハイツ'), (0x332B, 'M', u'パーセント'), - ] - -def _seg_33(): - return [ (0x332C, 'M', u'パーツ'), (0x332D, 'M', u'バーレル'), (0x332E, 'M', u'ピアストル'), @@ -3513,6 +3539,10 @@ def _seg_33(): (0x3373, 'M', u'au'), (0x3374, 'M', u'bar'), (0x3375, 'M', u'ov'), + ] + +def _seg_34(): + return [ (0x3376, 'M', u'pc'), (0x3377, 'M', u'dm'), (0x3378, 'M', u'dm2'), @@ -3539,10 +3569,6 @@ def _seg_33(): (0x338D, 'M', u'μg'), (0x338E, 'M', u'mg'), (0x338F, 'M', u'kg'), - ] - -def _seg_34(): - return [ (0x3390, 'M', u'hz'), (0x3391, 'M', u'khz'), (0x3392, 'M', u'mhz'), @@ -3617,6 +3643,10 @@ def _seg_34(): (0x33D7, 'M', u'ph'), (0x33D8, 'X'), (0x33D9, 'M', u'ppm'), + ] + +def _seg_35(): + return [ (0x33DA, 'M', u'pr'), (0x33DB, 'M', u'sr'), (0x33DC, 'M', u'sv'), @@ -3643,10 +3673,6 @@ def _seg_34(): (0x33F1, 'M', u'18日'), (0x33F2, 'M', u'19日'), (0x33F3, 'M', u'20日'), - ] - -def _seg_35(): - return [ (0x33F4, 'M', u'21日'), (0x33F5, 'M', u'22日'), (0x33F6, 'M', u'23日'), @@ -3660,9 +3686,7 @@ def _seg_35(): (0x33FE, 'M', u'31日'), (0x33FF, 'M', u'gal'), (0x3400, 'V'), - (0x4DB6, 'X'), - (0x4DC0, 'V'), - (0x9FF0, 'X'), + (0x9FFD, 'X'), (0xA000, 'V'), (0xA48D, 'X'), (0xA490, 'V'), @@ -3723,6 +3747,10 @@ def _seg_35(): (0xA685, 'V'), (0xA686, 'M', u'ꚇ'), (0xA687, 'V'), + ] + +def _seg_36(): + return [ (0xA688, 'M', u'ꚉ'), (0xA689, 'V'), (0xA68A, 'M', u'ꚋ'), @@ -3747,10 +3775,6 @@ def _seg_35(): (0xA69D, 'M', u'ь'), (0xA69E, 'V'), (0xA6F8, 'X'), - ] - -def _seg_36(): - return [ (0xA700, 'V'), (0xA722, 'M', u'ꜣ'), (0xA723, 'V'), @@ -3827,6 +3851,10 @@ def _seg_36(): (0xA76C, 'M', u'ꝭ'), (0xA76D, 'V'), (0xA76E, 'M', u'ꝯ'), + ] + +def _seg_37(): + return [ (0xA76F, 'V'), (0xA770, 'M', u'ꝯ'), (0xA771, 'V'), @@ -3851,10 +3879,6 @@ def _seg_36(): (0xA78E, 'V'), (0xA790, 'M', u'ꞑ'), (0xA791, 'V'), - ] - -def _seg_37(): - return [ (0xA792, 'M', u'ꞓ'), (0xA793, 'V'), (0xA796, 'M', u'ꞗ'), @@ -3891,14 +3915,31 @@ def _seg_37(): (0xA7B5, 'V'), (0xA7B6, 'M', u'ꞷ'), (0xA7B7, 'V'), - (0xA7B8, 'X'), + (0xA7B8, 'M', u'ꞹ'), (0xA7B9, 'V'), - (0xA7BA, 'X'), - (0xA7F7, 'V'), + (0xA7BA, 'M', u'ꞻ'), + (0xA7BB, 'V'), + (0xA7BC, 'M', u'ꞽ'), + (0xA7BD, 'V'), + (0xA7BE, 'M', u'ꞿ'), + (0xA7BF, 'V'), + (0xA7C0, 'X'), + (0xA7C2, 'M', u'ꟃ'), + (0xA7C3, 'V'), + (0xA7C4, 'M', u'ꞔ'), + (0xA7C5, 'M', u'ʂ'), + (0xA7C6, 'M', u'ᶎ'), + (0xA7C7, 'M', u'ꟈ'), + (0xA7C8, 'V'), + (0xA7C9, 'M', u'ꟊ'), + (0xA7CA, 'V'), + (0xA7CB, 'X'), + (0xA7F5, 'M', u'ꟶ'), + (0xA7F6, 'V'), (0xA7F8, 'M', u'ħ'), (0xA7F9, 'M', u'œ'), (0xA7FA, 'V'), - (0xA82C, 'X'), + (0xA82D, 'X'), (0xA830, 'V'), (0xA83A, 'X'), (0xA840, 'V'), @@ -3914,6 +3955,10 @@ def _seg_37(): (0xA980, 'V'), (0xA9CE, 'X'), (0xA9CF, 'V'), + ] + +def _seg_38(): + return [ (0xA9DA, 'X'), (0xA9DE, 'V'), (0xA9FF, 'X'), @@ -3943,7 +3988,9 @@ def _seg_37(): (0xAB5E, 'M', u'ɫ'), (0xAB5F, 'M', u'ꭒ'), (0xAB60, 'V'), - (0xAB66, 'X'), + (0xAB69, 'M', u'ʍ'), + (0xAB6A, 'V'), + (0xAB6C, 'X'), (0xAB70, 'M', u'Ꭰ'), (0xAB71, 'M', u'Ꭱ'), (0xAB72, 'M', u'Ꭲ'), @@ -3955,10 +4002,6 @@ def _seg_37(): (0xAB78, 'M', u'Ꭸ'), (0xAB79, 'M', u'Ꭹ'), (0xAB7A, 'M', u'Ꭺ'), - ] - -def _seg_38(): - return [ (0xAB7B, 'M', u'Ꭻ'), (0xAB7C, 'M', u'Ꭼ'), (0xAB7D, 'M', u'Ꭽ'), @@ -4016,6 +4059,10 @@ def _seg_38(): (0xABB1, 'M', u'Ꮱ'), (0xABB2, 'M', u'Ꮲ'), (0xABB3, 'M', u'Ꮳ'), + ] + +def _seg_39(): + return [ (0xABB4, 'M', u'Ꮴ'), (0xABB5, 'M', u'Ꮵ'), (0xABB6, 'M', u'Ꮶ'), @@ -4059,10 +4106,6 @@ def _seg_38(): (0xF913, 'M', u'邏'), (0xF914, 'M', u'樂'), (0xF915, 'M', u'洛'), - ] - -def _seg_39(): - return [ (0xF916, 'M', u'烙'), (0xF917, 'M', u'珞'), (0xF918, 'M', u'落'), @@ -4120,6 +4163,10 @@ def _seg_39(): (0xF94C, 'M', u'樓'), (0xF94D, 'M', u'淚'), (0xF94E, 'M', u'漏'), + ] + +def _seg_40(): + return [ (0xF94F, 'M', u'累'), (0xF950, 'M', u'縷'), (0xF951, 'M', u'陋'), @@ -4163,10 +4210,6 @@ def _seg_39(): (0xF977, 'M', u'亮'), (0xF978, 'M', u'兩'), (0xF979, 'M', u'凉'), - ] - -def _seg_40(): - return [ (0xF97A, 'M', u'梁'), (0xF97B, 'M', u'糧'), (0xF97C, 'M', u'良'), @@ -4224,6 +4267,10 @@ def _seg_40(): (0xF9B0, 'M', u'聆'), (0xF9B1, 'M', u'鈴'), (0xF9B2, 'M', u'零'), + ] + +def _seg_41(): + return [ (0xF9B3, 'M', u'靈'), (0xF9B4, 'M', u'領'), (0xF9B5, 'M', u'例'), @@ -4267,10 +4314,6 @@ def _seg_40(): (0xF9DB, 'M', u'率'), (0xF9DC, 'M', u'隆'), (0xF9DD, 'M', u'利'), - ] - -def _seg_41(): - return [ (0xF9DE, 'M', u'吏'), (0xF9DF, 'M', u'履'), (0xF9E0, 'M', u'易'), @@ -4328,6 +4371,10 @@ def _seg_41(): (0xFA16, 'M', u'猪'), (0xFA17, 'M', u'益'), (0xFA18, 'M', u'礼'), + ] + +def _seg_42(): + return [ (0xFA19, 'M', u'神'), (0xFA1A, 'M', u'祥'), (0xFA1B, 'M', u'福'), @@ -4371,10 +4418,6 @@ def _seg_41(): (0xFA44, 'M', u'梅'), (0xFA45, 'M', u'海'), (0xFA46, 'M', u'渚'), - ] - -def _seg_42(): - return [ (0xFA47, 'M', u'漢'), (0xFA48, 'M', u'煮'), (0xFA49, 'M', u'爫'), @@ -4432,6 +4475,10 @@ def _seg_42(): (0xFA7F, 'M', u'奔'), (0xFA80, 'M', u'婢'), (0xFA81, 'M', u'嬨'), + ] + +def _seg_43(): + return [ (0xFA82, 'M', u'廒'), (0xFA83, 'M', u'廙'), (0xFA84, 'M', u'彩'), @@ -4475,10 +4522,6 @@ def _seg_42(): (0xFAAA, 'M', u'着'), (0xFAAB, 'M', u'磌'), (0xFAAC, 'M', u'窱'), - ] - -def _seg_43(): - return [ (0xFAAD, 'M', u'節'), (0xFAAE, 'M', u'类'), (0xFAAF, 'M', u'絛'), @@ -4536,6 +4579,10 @@ def _seg_43(): (0xFB14, 'M', u'մե'), (0xFB15, 'M', u'մի'), (0xFB16, 'M', u'վն'), + ] + +def _seg_44(): + return [ (0xFB17, 'M', u'մխ'), (0xFB18, 'X'), (0xFB1D, 'M', u'יִ'), @@ -4579,10 +4626,6 @@ def _seg_43(): (0xFB43, 'M', u'ףּ'), (0xFB44, 'M', u'פּ'), (0xFB45, 'X'), - ] - -def _seg_44(): - return [ (0xFB46, 'M', u'צּ'), (0xFB47, 'M', u'קּ'), (0xFB48, 'M', u'רּ'), @@ -4640,6 +4683,10 @@ def _seg_44(): (0xFBEE, 'M', u'ئو'), (0xFBF0, 'M', u'ئۇ'), (0xFBF2, 'M', u'ئۆ'), + ] + +def _seg_45(): + return [ (0xFBF4, 'M', u'ئۈ'), (0xFBF6, 'M', u'ئې'), (0xFBF9, 'M', u'ئى'), @@ -4683,10 +4730,6 @@ def _seg_44(): (0xFC24, 'M', u'ضخ'), (0xFC25, 'M', u'ضم'), (0xFC26, 'M', u'طح'), - ] - -def _seg_45(): - return [ (0xFC27, 'M', u'طم'), (0xFC28, 'M', u'ظم'), (0xFC29, 'M', u'عج'), @@ -4744,6 +4787,10 @@ def _seg_45(): (0xFC5D, 'M', u'ىٰ'), (0xFC5E, '3', u' ٌّ'), (0xFC5F, '3', u' ٍّ'), + ] + +def _seg_46(): + return [ (0xFC60, '3', u' َّ'), (0xFC61, '3', u' ُّ'), (0xFC62, '3', u' ِّ'), @@ -4787,10 +4834,6 @@ def _seg_45(): (0xFC88, 'M', u'ما'), (0xFC89, 'M', u'مم'), (0xFC8A, 'M', u'نر'), - ] - -def _seg_46(): - return [ (0xFC8B, 'M', u'نز'), (0xFC8C, 'M', u'نم'), (0xFC8D, 'M', u'نن'), @@ -4848,6 +4891,10 @@ def _seg_46(): (0xFCC1, 'M', u'فم'), (0xFCC2, 'M', u'قح'), (0xFCC3, 'M', u'قم'), + ] + +def _seg_47(): + return [ (0xFCC4, 'M', u'كج'), (0xFCC5, 'M', u'كح'), (0xFCC6, 'M', u'كخ'), @@ -4891,10 +4938,6 @@ def _seg_46(): (0xFCEC, 'M', u'كم'), (0xFCED, 'M', u'لم'), (0xFCEE, 'M', u'نم'), - ] - -def _seg_47(): - return [ (0xFCEF, 'M', u'نه'), (0xFCF0, 'M', u'يم'), (0xFCF1, 'M', u'يه'), @@ -4952,6 +4995,10 @@ def _seg_47(): (0xFD25, 'M', u'شج'), (0xFD26, 'M', u'شح'), (0xFD27, 'M', u'شخ'), + ] + +def _seg_48(): + return [ (0xFD28, 'M', u'شم'), (0xFD29, 'M', u'شر'), (0xFD2A, 'M', u'سر'), @@ -4995,10 +5042,6 @@ def _seg_47(): (0xFD66, 'M', u'صمم'), (0xFD67, 'M', u'شحم'), (0xFD69, 'M', u'شجي'), - ] - -def _seg_48(): - return [ (0xFD6A, 'M', u'شمخ'), (0xFD6C, 'M', u'شمم'), (0xFD6E, 'M', u'ضحى'), @@ -5056,6 +5099,10 @@ def _seg_48(): (0xFDAC, 'M', u'لجي'), (0xFDAD, 'M', u'لمي'), (0xFDAE, 'M', u'يحي'), + ] + +def _seg_49(): + return [ (0xFDAF, 'M', u'يجي'), (0xFDB0, 'M', u'يمي'), (0xFDB1, 'M', u'ممي'), @@ -5099,10 +5146,6 @@ def _seg_48(): (0xFDFE, 'X'), (0xFE00, 'I'), (0xFE10, '3', u','), - ] - -def _seg_49(): - return [ (0xFE11, 'M', u'、'), (0xFE12, 'X'), (0xFE13, '3', u':'), @@ -5160,6 +5203,10 @@ def _seg_49(): (0xFE64, '3', u'<'), (0xFE65, '3', u'>'), (0xFE66, '3', u'='), + ] + +def _seg_50(): + return [ (0xFE67, 'X'), (0xFE68, '3', u'\\'), (0xFE69, '3', u'$'), @@ -5203,10 +5250,6 @@ def _seg_49(): (0xFEB1, 'M', u'س'), (0xFEB5, 'M', u'ش'), (0xFEB9, 'M', u'ص'), - ] - -def _seg_50(): - return [ (0xFEBD, 'M', u'ض'), (0xFEC1, 'M', u'ط'), (0xFEC5, 'M', u'ظ'), @@ -5264,6 +5307,10 @@ def _seg_50(): (0xFF21, 'M', u'a'), (0xFF22, 'M', u'b'), (0xFF23, 'M', u'c'), + ] + +def _seg_51(): + return [ (0xFF24, 'M', u'd'), (0xFF25, 'M', u'e'), (0xFF26, 'M', u'f'), @@ -5307,10 +5354,6 @@ def _seg_50(): (0xFF4C, 'M', u'l'), (0xFF4D, 'M', u'm'), (0xFF4E, 'M', u'n'), - ] - -def _seg_51(): - return [ (0xFF4F, 'M', u'o'), (0xFF50, 'M', u'p'), (0xFF51, 'M', u'q'), @@ -5368,6 +5411,10 @@ def _seg_51(): (0xFF85, 'M', u'ナ'), (0xFF86, 'M', u'ニ'), (0xFF87, 'M', u'ヌ'), + ] + +def _seg_52(): + return [ (0xFF88, 'M', u'ネ'), (0xFF89, 'M', u'ノ'), (0xFF8A, 'M', u'ハ'), @@ -5411,10 +5458,6 @@ def _seg_51(): (0xFFB0, 'M', u'ᄚ'), (0xFFB1, 'M', u'ᄆ'), (0xFFB2, 'M', u'ᄇ'), - ] - -def _seg_52(): - return [ (0xFFB3, 'M', u'ᄈ'), (0xFFB4, 'M', u'ᄡ'), (0xFFB5, 'M', u'ᄉ'), @@ -5472,6 +5515,10 @@ def _seg_52(): (0x10000, 'V'), (0x1000C, 'X'), (0x1000D, 'V'), + ] + +def _seg_53(): + return [ (0x10027, 'X'), (0x10028, 'V'), (0x1003B, 'X'), @@ -5490,7 +5537,7 @@ def _seg_52(): (0x10137, 'V'), (0x1018F, 'X'), (0x10190, 'V'), - (0x1019C, 'X'), + (0x1019D, 'X'), (0x101A0, 'V'), (0x101A1, 'X'), (0x101D0, 'V'), @@ -5515,10 +5562,6 @@ def _seg_52(): (0x103D6, 'X'), (0x10400, 'M', u'𐐨'), (0x10401, 'M', u'𐐩'), - ] - -def _seg_53(): - return [ (0x10402, 'M', u'𐐪'), (0x10403, 'M', u'𐐫'), (0x10404, 'M', u'𐐬'), @@ -5576,6 +5619,10 @@ def _seg_53(): (0x104BC, 'M', u'𐓤'), (0x104BD, 'M', u'𐓥'), (0x104BE, 'M', u'𐓦'), + ] + +def _seg_54(): + return [ (0x104BF, 'M', u'𐓧'), (0x104C0, 'M', u'𐓨'), (0x104C1, 'M', u'𐓩'), @@ -5619,10 +5666,6 @@ def _seg_53(): (0x1080A, 'V'), (0x10836, 'X'), (0x10837, 'V'), - ] - -def _seg_54(): - return [ (0x10839, 'X'), (0x1083C, 'V'), (0x1083D, 'X'), @@ -5680,6 +5723,10 @@ def _seg_54(): (0x10B9D, 'X'), (0x10BA9, 'V'), (0x10BB0, 'X'), + ] + +def _seg_55(): + return [ (0x10C00, 'V'), (0x10C49, 'X'), (0x10C80, 'M', u'𐳀'), @@ -5723,10 +5770,6 @@ def _seg_54(): (0x10CA6, 'M', u'𐳦'), (0x10CA7, 'M', u'𐳧'), (0x10CA8, 'M', u'𐳨'), - ] - -def _seg_55(): - return [ (0x10CA9, 'M', u'𐳩'), (0x10CAA, 'M', u'𐳪'), (0x10CAB, 'M', u'𐳫'), @@ -5746,10 +5789,20 @@ def _seg_55(): (0x10D3A, 'X'), (0x10E60, 'V'), (0x10E7F, 'X'), + (0x10E80, 'V'), + (0x10EAA, 'X'), + (0x10EAB, 'V'), + (0x10EAE, 'X'), + (0x10EB0, 'V'), + (0x10EB2, 'X'), (0x10F00, 'V'), (0x10F28, 'X'), (0x10F30, 'V'), (0x10F5A, 'X'), + (0x10FB0, 'V'), + (0x10FCC, 'X'), + (0x10FE0, 'V'), + (0x10FF7, 'X'), (0x11000, 'V'), (0x1104E, 'X'), (0x11052, 'V'), @@ -5765,17 +5818,19 @@ def _seg_55(): (0x11100, 'V'), (0x11135, 'X'), (0x11136, 'V'), - (0x11147, 'X'), + (0x11148, 'X'), (0x11150, 'V'), (0x11177, 'X'), (0x11180, 'V'), - (0x111CE, 'X'), - (0x111D0, 'V'), (0x111E0, 'X'), (0x111E1, 'V'), (0x111F5, 'X'), (0x11200, 'V'), (0x11212, 'X'), + ] + +def _seg_56(): + return [ (0x11213, 'V'), (0x1123F, 'X'), (0x11280, 'V'), @@ -5823,15 +5878,9 @@ def _seg_55(): (0x11370, 'V'), (0x11375, 'X'), (0x11400, 'V'), - (0x1145A, 'X'), - (0x1145B, 'V'), (0x1145C, 'X'), (0x1145D, 'V'), - ] - -def _seg_56(): - return [ - (0x1145F, 'X'), + (0x11462, 'X'), (0x11480, 'V'), (0x114C8, 'X'), (0x114D0, 'V'), @@ -5847,7 +5896,7 @@ def _seg_56(): (0x11660, 'V'), (0x1166D, 'X'), (0x11680, 'V'), - (0x116B8, 'X'), + (0x116B9, 'X'), (0x116C0, 'V'), (0x116CA, 'X'), (0x11700, 'V'), @@ -5882,6 +5931,10 @@ def _seg_56(): (0x118B5, 'M', u'𑣕'), (0x118B6, 'M', u'𑣖'), (0x118B7, 'M', u'𑣗'), + ] + +def _seg_57(): + return [ (0x118B8, 'M', u'𑣘'), (0x118B9, 'M', u'𑣙'), (0x118BA, 'M', u'𑣚'), @@ -5893,12 +5946,30 @@ def _seg_56(): (0x118C0, 'V'), (0x118F3, 'X'), (0x118FF, 'V'), - (0x11900, 'X'), + (0x11907, 'X'), + (0x11909, 'V'), + (0x1190A, 'X'), + (0x1190C, 'V'), + (0x11914, 'X'), + (0x11915, 'V'), + (0x11917, 'X'), + (0x11918, 'V'), + (0x11936, 'X'), + (0x11937, 'V'), + (0x11939, 'X'), + (0x1193B, 'V'), + (0x11947, 'X'), + (0x11950, 'V'), + (0x1195A, 'X'), + (0x119A0, 'V'), + (0x119A8, 'X'), + (0x119AA, 'V'), + (0x119D8, 'X'), + (0x119DA, 'V'), + (0x119E5, 'X'), (0x11A00, 'V'), (0x11A48, 'X'), (0x11A50, 'V'), - (0x11A84, 'X'), - (0x11A86, 'V'), (0x11AA3, 'X'), (0x11AC0, 'V'), (0x11AF9, 'X'), @@ -5931,10 +6002,6 @@ def _seg_56(): (0x11D50, 'V'), (0x11D5A, 'X'), (0x11D60, 'V'), - ] - -def _seg_57(): - return [ (0x11D66, 'X'), (0x11D67, 'V'), (0x11D69, 'X'), @@ -5948,7 +6015,11 @@ def _seg_57(): (0x11DAA, 'X'), (0x11EE0, 'V'), (0x11EF9, 'X'), - (0x12000, 'V'), + (0x11FB0, 'V'), + (0x11FB1, 'X'), + (0x11FC0, 'V'), + (0x11FF2, 'X'), + (0x11FFF, 'V'), (0x1239A, 'X'), (0x12400, 'V'), (0x1246F, 'X'), @@ -5964,6 +6035,10 @@ def _seg_57(): (0x16A39, 'X'), (0x16A40, 'V'), (0x16A5F, 'X'), + ] + +def _seg_58(): + return [ (0x16A60, 'V'), (0x16A6A, 'X'), (0x16A6E, 'V'), @@ -5982,22 +6057,62 @@ def _seg_57(): (0x16B78, 'X'), (0x16B7D, 'V'), (0x16B90, 'X'), + (0x16E40, 'M', u'𖹠'), + (0x16E41, 'M', u'𖹡'), + (0x16E42, 'M', u'𖹢'), + (0x16E43, 'M', u'𖹣'), + (0x16E44, 'M', u'𖹤'), + (0x16E45, 'M', u'𖹥'), + (0x16E46, 'M', u'𖹦'), + (0x16E47, 'M', u'𖹧'), + (0x16E48, 'M', u'𖹨'), + (0x16E49, 'M', u'𖹩'), + (0x16E4A, 'M', u'𖹪'), + (0x16E4B, 'M', u'𖹫'), + (0x16E4C, 'M', u'𖹬'), + (0x16E4D, 'M', u'𖹭'), + (0x16E4E, 'M', u'𖹮'), + (0x16E4F, 'M', u'𖹯'), + (0x16E50, 'M', u'𖹰'), + (0x16E51, 'M', u'𖹱'), + (0x16E52, 'M', u'𖹲'), + (0x16E53, 'M', u'𖹳'), + (0x16E54, 'M', u'𖹴'), + (0x16E55, 'M', u'𖹵'), + (0x16E56, 'M', u'𖹶'), + (0x16E57, 'M', u'𖹷'), + (0x16E58, 'M', u'𖹸'), + (0x16E59, 'M', u'𖹹'), + (0x16E5A, 'M', u'𖹺'), + (0x16E5B, 'M', u'𖹻'), + (0x16E5C, 'M', u'𖹼'), + (0x16E5D, 'M', u'𖹽'), + (0x16E5E, 'M', u'𖹾'), + (0x16E5F, 'M', u'𖹿'), (0x16E60, 'V'), (0x16E9B, 'X'), (0x16F00, 'V'), - (0x16F45, 'X'), - (0x16F50, 'V'), - (0x16F7F, 'X'), + (0x16F4B, 'X'), + (0x16F4F, 'V'), + (0x16F88, 'X'), (0x16F8F, 'V'), (0x16FA0, 'X'), (0x16FE0, 'V'), - (0x16FE2, 'X'), + (0x16FE5, 'X'), + (0x16FF0, 'V'), + (0x16FF2, 'X'), (0x17000, 'V'), - (0x187F2, 'X'), + (0x187F8, 'X'), (0x18800, 'V'), - (0x18AF3, 'X'), + (0x18CD6, 'X'), + (0x18D00, 'V'), + (0x18D09, 'X'), (0x1B000, 'V'), (0x1B11F, 'X'), + (0x1B150, 'V'), + (0x1B153, 'X'), + (0x1B164, 'V'), + (0x1B168, 'X'), (0x1B170, 'V'), (0x1B2FC, 'X'), (0x1BC00, 'V'), @@ -6024,6 +6139,10 @@ def _seg_57(): (0x1D163, 'M', u'𝅘𝅥𝅱'), (0x1D164, 'M', u'𝅘𝅥𝅲'), (0x1D165, 'V'), + ] + +def _seg_59(): + return [ (0x1D173, 'X'), (0x1D17B, 'V'), (0x1D1BB, 'M', u'𝆹𝅥'), @@ -6035,10 +6154,6 @@ def _seg_57(): (0x1D1C1, 'V'), (0x1D1E9, 'X'), (0x1D200, 'V'), - ] - -def _seg_58(): - return [ (0x1D246, 'X'), (0x1D2E0, 'V'), (0x1D2F4, 'X'), @@ -6128,6 +6243,10 @@ def _seg_58(): (0x1D44F, 'M', u'b'), (0x1D450, 'M', u'c'), (0x1D451, 'M', u'd'), + ] + +def _seg_60(): + return [ (0x1D452, 'M', u'e'), (0x1D453, 'M', u'f'), (0x1D454, 'M', u'g'), @@ -6139,10 +6258,6 @@ def _seg_58(): (0x1D45A, 'M', u'm'), (0x1D45B, 'M', u'n'), (0x1D45C, 'M', u'o'), - ] - -def _seg_59(): - return [ (0x1D45D, 'M', u'p'), (0x1D45E, 'M', u'q'), (0x1D45F, 'M', u'r'), @@ -6232,6 +6347,10 @@ def _seg_59(): (0x1D4B6, 'M', u'a'), (0x1D4B7, 'M', u'b'), (0x1D4B8, 'M', u'c'), + ] + +def _seg_61(): + return [ (0x1D4B9, 'M', u'd'), (0x1D4BA, 'X'), (0x1D4BB, 'M', u'f'), @@ -6243,10 +6362,6 @@ def _seg_59(): (0x1D4C1, 'M', u'l'), (0x1D4C2, 'M', u'm'), (0x1D4C3, 'M', u'n'), - ] - -def _seg_60(): - return [ (0x1D4C4, 'X'), (0x1D4C5, 'M', u'p'), (0x1D4C6, 'M', u'q'), @@ -6336,6 +6451,10 @@ def _seg_60(): (0x1D51B, 'M', u'x'), (0x1D51C, 'M', u'y'), (0x1D51D, 'X'), + ] + +def _seg_62(): + return [ (0x1D51E, 'M', u'a'), (0x1D51F, 'M', u'b'), (0x1D520, 'M', u'c'), @@ -6347,10 +6466,6 @@ def _seg_60(): (0x1D526, 'M', u'i'), (0x1D527, 'M', u'j'), (0x1D528, 'M', u'k'), - ] - -def _seg_61(): - return [ (0x1D529, 'M', u'l'), (0x1D52A, 'M', u'm'), (0x1D52B, 'M', u'n'), @@ -6440,6 +6555,10 @@ def _seg_61(): (0x1D581, 'M', u'v'), (0x1D582, 'M', u'w'), (0x1D583, 'M', u'x'), + ] + +def _seg_63(): + return [ (0x1D584, 'M', u'y'), (0x1D585, 'M', u'z'), (0x1D586, 'M', u'a'), @@ -6451,10 +6570,6 @@ def _seg_61(): (0x1D58C, 'M', u'g'), (0x1D58D, 'M', u'h'), (0x1D58E, 'M', u'i'), - ] - -def _seg_62(): - return [ (0x1D58F, 'M', u'j'), (0x1D590, 'M', u'k'), (0x1D591, 'M', u'l'), @@ -6544,6 +6659,10 @@ def _seg_62(): (0x1D5E5, 'M', u'r'), (0x1D5E6, 'M', u's'), (0x1D5E7, 'M', u't'), + ] + +def _seg_64(): + return [ (0x1D5E8, 'M', u'u'), (0x1D5E9, 'M', u'v'), (0x1D5EA, 'M', u'w'), @@ -6555,10 +6674,6 @@ def _seg_62(): (0x1D5F0, 'M', u'c'), (0x1D5F1, 'M', u'd'), (0x1D5F2, 'M', u'e'), - ] - -def _seg_63(): - return [ (0x1D5F3, 'M', u'f'), (0x1D5F4, 'M', u'g'), (0x1D5F5, 'M', u'h'), @@ -6648,6 +6763,10 @@ def _seg_63(): (0x1D649, 'M', u'n'), (0x1D64A, 'M', u'o'), (0x1D64B, 'M', u'p'), + ] + +def _seg_65(): + return [ (0x1D64C, 'M', u'q'), (0x1D64D, 'M', u'r'), (0x1D64E, 'M', u's'), @@ -6659,10 +6778,6 @@ def _seg_63(): (0x1D654, 'M', u'y'), (0x1D655, 'M', u'z'), (0x1D656, 'M', u'a'), - ] - -def _seg_64(): - return [ (0x1D657, 'M', u'b'), (0x1D658, 'M', u'c'), (0x1D659, 'M', u'd'), @@ -6752,6 +6867,10 @@ def _seg_64(): (0x1D6AE, 'M', u'η'), (0x1D6AF, 'M', u'θ'), (0x1D6B0, 'M', u'ι'), + ] + +def _seg_66(): + return [ (0x1D6B1, 'M', u'κ'), (0x1D6B2, 'M', u'λ'), (0x1D6B3, 'M', u'μ'), @@ -6763,10 +6882,6 @@ def _seg_64(): (0x1D6B9, 'M', u'θ'), (0x1D6BA, 'M', u'σ'), (0x1D6BB, 'M', u'τ'), - ] - -def _seg_65(): - return [ (0x1D6BC, 'M', u'υ'), (0x1D6BD, 'M', u'φ'), (0x1D6BE, 'M', u'χ'), @@ -6856,6 +6971,10 @@ def _seg_65(): (0x1D714, 'M', u'ω'), (0x1D715, 'M', u'∂'), (0x1D716, 'M', u'ε'), + ] + +def _seg_67(): + return [ (0x1D717, 'M', u'θ'), (0x1D718, 'M', u'κ'), (0x1D719, 'M', u'φ'), @@ -6867,10 +6986,6 @@ def _seg_65(): (0x1D71F, 'M', u'δ'), (0x1D720, 'M', u'ε'), (0x1D721, 'M', u'ζ'), - ] - -def _seg_66(): - return [ (0x1D722, 'M', u'η'), (0x1D723, 'M', u'θ'), (0x1D724, 'M', u'ι'), @@ -6960,6 +7075,10 @@ def _seg_66(): (0x1D779, 'M', u'κ'), (0x1D77A, 'M', u'λ'), (0x1D77B, 'M', u'μ'), + ] + +def _seg_68(): + return [ (0x1D77C, 'M', u'ν'), (0x1D77D, 'M', u'ξ'), (0x1D77E, 'M', u'ο'), @@ -6971,10 +7090,6 @@ def _seg_66(): (0x1D785, 'M', u'φ'), (0x1D786, 'M', u'χ'), (0x1D787, 'M', u'ψ'), - ] - -def _seg_67(): - return [ (0x1D788, 'M', u'ω'), (0x1D789, 'M', u'∂'), (0x1D78A, 'M', u'ε'), @@ -7064,6 +7179,10 @@ def _seg_67(): (0x1D7E1, 'M', u'9'), (0x1D7E2, 'M', u'0'), (0x1D7E3, 'M', u'1'), + ] + +def _seg_69(): + return [ (0x1D7E4, 'M', u'2'), (0x1D7E5, 'M', u'3'), (0x1D7E6, 'M', u'4'), @@ -7075,10 +7194,6 @@ def _seg_67(): (0x1D7EC, 'M', u'0'), (0x1D7ED, 'M', u'1'), (0x1D7EE, 'M', u'2'), - ] - -def _seg_68(): - return [ (0x1D7EF, 'M', u'3'), (0x1D7F0, 'M', u'4'), (0x1D7F1, 'M', u'5'), @@ -7112,6 +7227,18 @@ def _seg_68(): (0x1E025, 'X'), (0x1E026, 'V'), (0x1E02B, 'X'), + (0x1E100, 'V'), + (0x1E12D, 'X'), + (0x1E130, 'V'), + (0x1E13E, 'X'), + (0x1E140, 'V'), + (0x1E14A, 'X'), + (0x1E14E, 'V'), + (0x1E150, 'X'), + (0x1E2C0, 'V'), + (0x1E2FA, 'X'), + (0x1E2FF, 'V'), + (0x1E300, 'X'), (0x1E800, 'V'), (0x1E8C5, 'X'), (0x1E8C7, 'V'), @@ -7151,13 +7278,19 @@ def _seg_68(): (0x1E920, 'M', u'𞥂'), (0x1E921, 'M', u'𞥃'), (0x1E922, 'V'), - (0x1E94B, 'X'), + (0x1E94C, 'X'), (0x1E950, 'V'), (0x1E95A, 'X'), (0x1E95E, 'V'), (0x1E960, 'X'), + ] + +def _seg_70(): + return [ (0x1EC71, 'V'), (0x1ECB5, 'X'), + (0x1ED01, 'V'), + (0x1ED3E, 'X'), (0x1EE00, 'M', u'ا'), (0x1EE01, 'M', u'ب'), (0x1EE02, 'M', u'ج'), @@ -7179,10 +7312,6 @@ def _seg_68(): (0x1EE12, 'M', u'ق'), (0x1EE13, 'M', u'ر'), (0x1EE14, 'M', u'ش'), - ] - -def _seg_69(): - return [ (0x1EE15, 'M', u'ت'), (0x1EE16, 'M', u'ث'), (0x1EE17, 'M', u'خ'), @@ -7258,6 +7387,10 @@ def _seg_69(): (0x1EE68, 'M', u'ط'), (0x1EE69, 'M', u'ي'), (0x1EE6A, 'M', u'ك'), + ] + +def _seg_71(): + return [ (0x1EE6B, 'X'), (0x1EE6C, 'M', u'م'), (0x1EE6D, 'M', u'ن'), @@ -7283,10 +7416,6 @@ def _seg_69(): (0x1EE81, 'M', u'ب'), (0x1EE82, 'M', u'ج'), (0x1EE83, 'M', u'د'), - ] - -def _seg_70(): - return [ (0x1EE84, 'M', u'ه'), (0x1EE85, 'M', u'و'), (0x1EE86, 'M', u'ز'), @@ -7362,10 +7491,13 @@ def _seg_70(): (0x1F106, '3', u'5,'), (0x1F107, '3', u'6,'), (0x1F108, '3', u'7,'), + ] + +def _seg_72(): + return [ (0x1F109, '3', u'8,'), (0x1F10A, '3', u'9,'), (0x1F10B, 'V'), - (0x1F10D, 'X'), (0x1F110, '3', u'(a)'), (0x1F111, '3', u'(b)'), (0x1F112, '3', u'(c)'), @@ -7387,10 +7519,6 @@ def _seg_70(): (0x1F122, '3', u'(s)'), (0x1F123, '3', u'(t)'), (0x1F124, '3', u'(u)'), - ] - -def _seg_71(): - return [ (0x1F125, '3', u'(v)'), (0x1F126, '3', u'(w)'), (0x1F127, '3', u'(x)'), @@ -7437,11 +7565,11 @@ def _seg_71(): (0x1F150, 'V'), (0x1F16A, 'M', u'mc'), (0x1F16B, 'M', u'md'), - (0x1F16C, 'X'), - (0x1F170, 'V'), + (0x1F16C, 'M', u'mr'), + (0x1F16D, 'V'), (0x1F190, 'M', u'dj'), (0x1F191, 'V'), - (0x1F1AD, 'X'), + (0x1F1AE, 'X'), (0x1F1E6, 'V'), (0x1F200, 'M', u'ほか'), (0x1F201, 'M', u'ココ'), @@ -7467,6 +7595,10 @@ def _seg_71(): (0x1F221, 'M', u'終'), (0x1F222, 'M', u'生'), (0x1F223, 'M', u'販'), + ] + +def _seg_73(): + return [ (0x1F224, 'M', u'声'), (0x1F225, 'M', u'吹'), (0x1F226, 'M', u'演'), @@ -7491,10 +7623,6 @@ def _seg_71(): (0x1F239, 'M', u'割'), (0x1F23A, 'M', u'営'), (0x1F23B, 'M', u'配'), - ] - -def _seg_72(): - return [ (0x1F23C, 'X'), (0x1F240, 'M', u'〔本〕'), (0x1F241, 'M', u'〔三〕'), @@ -7512,15 +7640,17 @@ def _seg_72(): (0x1F260, 'V'), (0x1F266, 'X'), (0x1F300, 'V'), - (0x1F6D5, 'X'), + (0x1F6D8, 'X'), (0x1F6E0, 'V'), (0x1F6ED, 'X'), (0x1F6F0, 'V'), - (0x1F6FA, 'X'), + (0x1F6FD, 'X'), (0x1F700, 'V'), (0x1F774, 'X'), (0x1F780, 'V'), (0x1F7D9, 'X'), + (0x1F7E0, 'V'), + (0x1F7EC, 'X'), (0x1F800, 'V'), (0x1F80C, 'X'), (0x1F810, 'V'), @@ -7531,28 +7661,51 @@ def _seg_72(): (0x1F888, 'X'), (0x1F890, 'V'), (0x1F8AE, 'X'), + (0x1F8B0, 'V'), + (0x1F8B2, 'X'), (0x1F900, 'V'), - (0x1F90C, 'X'), - (0x1F910, 'V'), - (0x1F93F, 'X'), - (0x1F940, 'V'), - (0x1F971, 'X'), - (0x1F973, 'V'), - (0x1F977, 'X'), + (0x1F979, 'X'), (0x1F97A, 'V'), - (0x1F97B, 'X'), - (0x1F97C, 'V'), - (0x1F9A3, 'X'), - (0x1F9B0, 'V'), - (0x1F9BA, 'X'), - (0x1F9C0, 'V'), - (0x1F9C3, 'X'), - (0x1F9D0, 'V'), - (0x1FA00, 'X'), + (0x1F9CC, 'X'), + (0x1F9CD, 'V'), + (0x1FA54, 'X'), (0x1FA60, 'V'), (0x1FA6E, 'X'), + (0x1FA70, 'V'), + (0x1FA75, 'X'), + (0x1FA78, 'V'), + (0x1FA7B, 'X'), + (0x1FA80, 'V'), + (0x1FA87, 'X'), + (0x1FA90, 'V'), + (0x1FAA9, 'X'), + (0x1FAB0, 'V'), + (0x1FAB7, 'X'), + (0x1FAC0, 'V'), + (0x1FAC3, 'X'), + (0x1FAD0, 'V'), + (0x1FAD7, 'X'), + (0x1FB00, 'V'), + (0x1FB93, 'X'), + (0x1FB94, 'V'), + (0x1FBCB, 'X'), + (0x1FBF0, 'M', u'0'), + (0x1FBF1, 'M', u'1'), + (0x1FBF2, 'M', u'2'), + (0x1FBF3, 'M', u'3'), + (0x1FBF4, 'M', u'4'), + (0x1FBF5, 'M', u'5'), + (0x1FBF6, 'M', u'6'), + (0x1FBF7, 'M', u'7'), + (0x1FBF8, 'M', u'8'), + (0x1FBF9, 'M', u'9'), + ] + +def _seg_74(): + return [ + (0x1FBFA, 'X'), (0x20000, 'V'), - (0x2A6D7, 'X'), + (0x2A6DE, 'X'), (0x2A700, 'V'), (0x2B735, 'X'), (0x2B740, 'V'), @@ -7595,10 +7748,6 @@ def _seg_72(): (0x2F81F, 'M', u'㓟'), (0x2F820, 'M', u'刻'), (0x2F821, 'M', u'剆'), - ] - -def _seg_73(): - return [ (0x2F822, 'M', u'割'), (0x2F823, 'M', u'剷'), (0x2F824, 'M', u'㔕'), @@ -7654,6 +7803,10 @@ def _seg_73(): (0x2F859, 'M', u'𡓤'), (0x2F85A, 'M', u'売'), (0x2F85B, 'M', u'壷'), + ] + +def _seg_75(): + return [ (0x2F85C, 'M', u'夆'), (0x2F85D, 'M', u'多'), (0x2F85E, 'M', u'夢'), @@ -7699,10 +7852,6 @@ def _seg_73(): (0x2F887, 'M', u'幩'), (0x2F888, 'M', u'㡢'), (0x2F889, 'M', u'𢆃'), - ] - -def _seg_74(): - return [ (0x2F88A, 'M', u'㡼'), (0x2F88B, 'M', u'庰'), (0x2F88C, 'M', u'庳'), @@ -7758,6 +7907,10 @@ def _seg_74(): (0x2F8C0, 'M', u'揅'), (0x2F8C1, 'M', u'掩'), (0x2F8C2, 'M', u'㨮'), + ] + +def _seg_76(): + return [ (0x2F8C3, 'M', u'摩'), (0x2F8C4, 'M', u'摾'), (0x2F8C5, 'M', u'撝'), @@ -7803,10 +7956,6 @@ def _seg_74(): (0x2F8ED, 'M', u'櫛'), (0x2F8EE, 'M', u'㰘'), (0x2F8EF, 'M', u'次'), - ] - -def _seg_75(): - return [ (0x2F8F0, 'M', u'𣢧'), (0x2F8F1, 'M', u'歔'), (0x2F8F2, 'M', u'㱎'), @@ -7862,6 +8011,10 @@ def _seg_75(): (0x2F924, 'M', u'犀'), (0x2F925, 'M', u'犕'), (0x2F926, 'M', u'𤜵'), + ] + +def _seg_77(): + return [ (0x2F927, 'M', u'𤠔'), (0x2F928, 'M', u'獺'), (0x2F929, 'M', u'王'), @@ -7907,10 +8060,6 @@ def _seg_75(): (0x2F953, 'M', u'祖'), (0x2F954, 'M', u'𥚚'), (0x2F955, 'M', u'𥛅'), - ] - -def _seg_76(): - return [ (0x2F956, 'M', u'福'), (0x2F957, 'M', u'秫'), (0x2F958, 'M', u'䄯'), @@ -7966,6 +8115,10 @@ def _seg_76(): (0x2F98B, 'M', u'舁'), (0x2F98C, 'M', u'舄'), (0x2F98D, 'M', u'辞'), + ] + +def _seg_78(): + return [ (0x2F98E, 'M', u'䑫'), (0x2F98F, 'M', u'芑'), (0x2F990, 'M', u'芋'), @@ -8011,10 +8164,6 @@ def _seg_76(): (0x2F9B8, 'M', u'蚈'), (0x2F9B9, 'M', u'蜎'), (0x2F9BA, 'M', u'蛢'), - ] - -def _seg_77(): - return [ (0x2F9BB, 'M', u'蝹'), (0x2F9BC, 'M', u'蜨'), (0x2F9BD, 'M', u'蝫'), @@ -8070,6 +8219,10 @@ def _seg_77(): (0x2F9EF, 'M', u'䦕'), (0x2F9F0, 'M', u'閷'), (0x2F9F1, 'M', u'𨵷'), + ] + +def _seg_79(): + return [ (0x2F9F2, 'M', u'䧦'), (0x2F9F3, 'M', u'雃'), (0x2F9F4, 'M', u'嶲'), @@ -8114,11 +8267,9 @@ def _seg_77(): (0x2FA1C, 'M', u'鼻'), (0x2FA1D, 'M', u'𪘀'), (0x2FA1E, 'X'), + (0x30000, 'V'), + (0x3134B, 'X'), (0xE0100, 'I'), - ] - -def _seg_78(): - return [ (0xE01F0, 'X'), ] @@ -8202,4 +8353,5 @@ uts46data = tuple( + _seg_76() + _seg_77() + _seg_78() + + _seg_79() ) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/ipaddress.py b/venv/lib/python3.8/site-packages/pip/_vendor/ipaddress.py index f2d0766..3e6f9e4 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/ipaddress.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/ipaddress.py @@ -14,7 +14,7 @@ from __future__ import unicode_literals import itertools import struct -__version__ = '1.0.22' +__version__ = '1.0.23' # Compatibility functions _compat_int_types = (int,) @@ -1103,7 +1103,8 @@ class _BaseNetwork(_IPAddressBase): try: # Always false if one is v4 and the other is v6. if a._version != b._version: - raise TypeError("%s and %s are not of the same version" (a, b)) + raise TypeError( + "%s and %s are not of the same version" % (a, b)) return (b.network_address <= a.network_address and b.broadcast_address >= a.broadcast_address) except AttributeError: diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__init__.py deleted file mode 100644 index a6f44a5..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__init__.py +++ /dev/null @@ -1,347 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -lockfile.py - Platform-independent advisory file locks. - -Requires Python 2.5 unless you apply 2.4.diff -Locking is done on a per-thread basis instead of a per-process basis. - -Usage: - ->>> lock = LockFile('somefile') ->>> try: -... lock.acquire() -... except AlreadyLocked: -... print 'somefile', 'is locked already.' -... except LockFailed: -... print 'somefile', 'can\\'t be locked.' -... else: -... print 'got lock' -got lock ->>> print lock.is_locked() -True ->>> lock.release() - ->>> lock = LockFile('somefile') ->>> print lock.is_locked() -False ->>> with lock: -... print lock.is_locked() -True ->>> print lock.is_locked() -False - ->>> lock = LockFile('somefile') ->>> # It is okay to lock twice from the same thread... ->>> with lock: -... lock.acquire() -... ->>> # Though no counter is kept, so you can't unlock multiple times... ->>> print lock.is_locked() -False - -Exceptions: - - Error - base class for other exceptions - LockError - base class for all locking exceptions - AlreadyLocked - Another thread or process already holds the lock - LockFailed - Lock failed for some other reason - UnlockError - base class for all unlocking exceptions - AlreadyUnlocked - File was not locked. - NotMyLock - File was locked but not by the current thread/process -""" - -from __future__ import absolute_import - -import functools -import os -import socket -import threading -import warnings - -# Work with PEP8 and non-PEP8 versions of threading module. -if not hasattr(threading, "current_thread"): - threading.current_thread = threading.currentThread -if not hasattr(threading.Thread, "get_name"): - threading.Thread.get_name = threading.Thread.getName - -__all__ = ['Error', 'LockError', 'LockTimeout', 'AlreadyLocked', - 'LockFailed', 'UnlockError', 'NotLocked', 'NotMyLock', - 'LinkFileLock', 'MkdirFileLock', 'SQLiteFileLock', - 'LockBase', 'locked'] - - -class Error(Exception): - """ - Base class for other exceptions. - - >>> try: - ... raise Error - ... except Exception: - ... pass - """ - pass - - -class LockError(Error): - """ - Base class for error arising from attempts to acquire the lock. - - >>> try: - ... raise LockError - ... except Error: - ... pass - """ - pass - - -class LockTimeout(LockError): - """Raised when lock creation fails within a user-defined period of time. - - >>> try: - ... raise LockTimeout - ... except LockError: - ... pass - """ - pass - - -class AlreadyLocked(LockError): - """Some other thread/process is locking the file. - - >>> try: - ... raise AlreadyLocked - ... except LockError: - ... pass - """ - pass - - -class LockFailed(LockError): - """Lock file creation failed for some other reason. - - >>> try: - ... raise LockFailed - ... except LockError: - ... pass - """ - pass - - -class UnlockError(Error): - """ - Base class for errors arising from attempts to release the lock. - - >>> try: - ... raise UnlockError - ... except Error: - ... pass - """ - pass - - -class NotLocked(UnlockError): - """Raised when an attempt is made to unlock an unlocked file. - - >>> try: - ... raise NotLocked - ... except UnlockError: - ... pass - """ - pass - - -class NotMyLock(UnlockError): - """Raised when an attempt is made to unlock a file someone else locked. - - >>> try: - ... raise NotMyLock - ... except UnlockError: - ... pass - """ - pass - - -class _SharedBase(object): - def __init__(self, path): - self.path = path - - def acquire(self, timeout=None): - """ - Acquire the lock. - - * If timeout is omitted (or None), wait forever trying to lock the - file. - - * If timeout > 0, try to acquire the lock for that many seconds. If - the lock period expires and the file is still locked, raise - LockTimeout. - - * If timeout <= 0, raise AlreadyLocked immediately if the file is - already locked. - """ - raise NotImplemented("implement in subclass") - - def release(self): - """ - Release the lock. - - If the file is not locked, raise NotLocked. - """ - raise NotImplemented("implement in subclass") - - def __enter__(self): - """ - Context manager support. - """ - self.acquire() - return self - - def __exit__(self, *_exc): - """ - Context manager support. - """ - self.release() - - def __repr__(self): - return "<%s: %r>" % (self.__class__.__name__, self.path) - - -class LockBase(_SharedBase): - """Base class for platform-specific lock classes.""" - def __init__(self, path, threaded=True, timeout=None): - """ - >>> lock = LockBase('somefile') - >>> lock = LockBase('somefile', threaded=False) - """ - super(LockBase, self).__init__(path) - self.lock_file = os.path.abspath(path) + ".lock" - self.hostname = socket.gethostname() - self.pid = os.getpid() - if threaded: - t = threading.current_thread() - # Thread objects in Python 2.4 and earlier do not have ident - # attrs. Worm around that. - ident = getattr(t, "ident", hash(t)) - self.tname = "-%x" % (ident & 0xffffffff) - else: - self.tname = "" - dirname = os.path.dirname(self.lock_file) - - # unique name is mostly about the current process, but must - # also contain the path -- otherwise, two adjacent locked - # files conflict (one file gets locked, creating lock-file and - # unique file, the other one gets locked, creating lock-file - # and overwriting the already existing lock-file, then one - # gets unlocked, deleting both lock-file and unique file, - # finally the last lock errors out upon releasing. - self.unique_name = os.path.join(dirname, - "%s%s.%s%s" % (self.hostname, - self.tname, - self.pid, - hash(self.path))) - self.timeout = timeout - - def is_locked(self): - """ - Tell whether or not the file is locked. - """ - raise NotImplemented("implement in subclass") - - def i_am_locking(self): - """ - Return True if this object is locking the file. - """ - raise NotImplemented("implement in subclass") - - def break_lock(self): - """ - Remove a lock. Useful if a locking thread failed to unlock. - """ - raise NotImplemented("implement in subclass") - - def __repr__(self): - return "<%s: %r -- %r>" % (self.__class__.__name__, self.unique_name, - self.path) - - -def _fl_helper(cls, mod, *args, **kwds): - warnings.warn("Import from %s module instead of lockfile package" % mod, - DeprecationWarning, stacklevel=2) - # This is a bit funky, but it's only for awhile. The way the unit tests - # are constructed this function winds up as an unbound method, so it - # actually takes three args, not two. We want to toss out self. - if not isinstance(args[0], str): - # We are testing, avoid the first arg - args = args[1:] - if len(args) == 1 and not kwds: - kwds["threaded"] = True - return cls(*args, **kwds) - - -def LinkFileLock(*args, **kwds): - """Factory function provided for backwards compatibility. - - Do not use in new code. Instead, import LinkLockFile from the - lockfile.linklockfile module. - """ - from . import linklockfile - return _fl_helper(linklockfile.LinkLockFile, "lockfile.linklockfile", - *args, **kwds) - - -def MkdirFileLock(*args, **kwds): - """Factory function provided for backwards compatibility. - - Do not use in new code. Instead, import MkdirLockFile from the - lockfile.mkdirlockfile module. - """ - from . import mkdirlockfile - return _fl_helper(mkdirlockfile.MkdirLockFile, "lockfile.mkdirlockfile", - *args, **kwds) - - -def SQLiteFileLock(*args, **kwds): - """Factory function provided for backwards compatibility. - - Do not use in new code. Instead, import SQLiteLockFile from the - lockfile.mkdirlockfile module. - """ - from . import sqlitelockfile - return _fl_helper(sqlitelockfile.SQLiteLockFile, "lockfile.sqlitelockfile", - *args, **kwds) - - -def locked(path, timeout=None): - """Decorator which enables locks for decorated function. - - Arguments: - - path: path for lockfile. - - timeout (optional): Timeout for acquiring lock. - - Usage: - @locked('/var/run/myname', timeout=0) - def myname(...): - ... - """ - def decor(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - lock = FileLock(path, timeout=timeout) - lock.acquire() - try: - return func(*args, **kwargs) - finally: - lock.release() - return wrapper - return decor - - -if hasattr(os, "link"): - from . import linklockfile as _llf - LockFile = _llf.LinkLockFile -else: - from . import mkdirlockfile as _mlf - LockFile = _mlf.MkdirLockFile - -FileLock = LockFile diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 4b051b501153463dcdf0047272bbbfc6cb3006fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9765 zcmcgy%aa?&d7l{!fC2Ww<x(U?Jx3x}ODJ4Wk?n(NiXknDid^zW<|A@YjwiF|1~E$j z1N96@E^1k>$}&Y>9H(+fRh~uWRpBjHAAR%5hg42;%^{^fAQz=v%<tFp0I=NU!%{q` z>FIZW-`8J%ug2Adg}Q;~zi<5ekN@_BVf+^h)6W75=kZ2&Ov4aH%MhlpdS>5hStj$P zUa3{mU%O@NZ@E?0-%6{ZztvV%I<g|{9V_~ttZdd~#jCSsb54{|x53=zJX3E$R76!c zq9*EMPRxr1u_z9RC2>$JUt4G`eq@M4qH@O&6?tH%)LKIM1yM!0Dwj|`i1K0KpzO$l zC@-UYMAT5O>GC0zkBU0VbzOb|<rl>q%5!@BVU&-Fd6ehnVT?b5@=Ia?<po_nit@|i z6_j6*FQWYz%CCxpC?Ax^P<~0gCSJc|v|bjjSj6`g@rF2n@2lcXv4rny;-ok(mhYIY z*MYw+PV88JVX95BBHrq`{Wn@~nudIH^LXpTU>S9*s9R~hg}S#kS6e6KiPlL`x@<HW z{%d8!sQ1G5^-j=}&Eb~2=6>4q<4&mhYr#Osp+qu>U0>V?qEKzQ?B{Yo)U4Mp$<IfD zl9BuAR@@B-?z_!zxuZc(Mv=P}j$D5@>}{d)n@tgPI`vO5Di~aIgUA)(K)M*<yF;ng z;;xdua5wx2O~D|FSqeK@>rjPl&ZwKQ=+(%-CePIC=gytefVl6uocSUEJGmN#eMt~k z8@fGKTW9LcX4B<EsGELUgM6}~tL3e>9LDa29s$_mG*V0k3{?QsCv%>1R{<cWk;3)U zG0oNKi8LTS)_?LWZGZ5i)!5xgDJexhNiPCoIk?&C*TPsYxmwS28nd)jqZCA53KNjJ zqDHcyOjF68^dpJ-qV7r5+Goy-KH$<5+zjHb2Bv^=pCJVp`?RN1J`+&K-H&6kOnBYj za^p}h@5VQSwsbox?7MMSx{=?P$Z!)uy?sE{BWL$t_dM=i>4u|gU3U<=?Qk@RrQ&+m z!5F99DAb&c4a0tcwXyeZf7FYEA&x;D^ktMU_+(5!)QlE{g9w~UX8cg8P~o(JtEJoS z`CxDyIyVG5%1zmly>(yqCui+5#_#nsZaiCijO6GU2FI!w2I)fC$-~0=Da+W}?S?%O zY2p&+0*oA#i<-$X6X9|@X^9B%0A^TVJECw<485wU_XHeL@;)7lbRrzVHJ69pz3E5T zyY!UcEENk9*7Y#{zCPE}orw{KZ;WC+ZUcM;CTfqAqNq!0aylbO{R^tFhM64jH=?jN zilrCyhoOqslf`U=mySrBYclo*V8x`Yu}o^krX_RCUID*^qc~ZZ*^WdD#+0DR+!U3P z8ldMmDReePB$@vt7-(t7rexv!*F~U62VGpe{DV(|SQcf6wciDgC6%6@sZDgIAL!y# zD=#4<jg~2lmL*JRVhb9gq@W;-@l8!s&hrFbg={9tDVMd}Wg!)2$`3G76GeAnZ6<n) zgK?&4aor(~gD$Q=v=hhEMD@I+?s@%CjCvCJdC&WN<o8H!l&YR5!nWr<G}KYRtCKI! zosRp%)5Bm0O%}yCC2Q|?zd5?~jnHSMe!UyeZ=pI(+E8tr_Pk&a#GVILs4@Q@W{Yej zj%hp3O}h$d_g5N|U9^+>`1>k|$nRQ^`Ee}!!x)DybTchgoWG}$mb<(+dAZKsq*co~ zr6x2}FS3qc{~_Mr9PuhfkN^G>w_Uh5yK<0<?KVV046&vKM&weR1T+Fh5v%|K#XUfG zSOh_+^*`n7vtXW`tAc?t)+&hdy!aFPjVb)A&%N;u@xOO@A`54Q3iS(Fj(bnhL)Lp5 zqBAn%YeSWQ_P-LUHKKZ#v`%fqnLWmK?x_@>hAgK`CF0kHDdD{Jl`y4uGydy+Pjlq% zdz>>n?3s`AloHsDzdq&9%g}^;XA1Y{mt=Fq{V%5vw2y<EN-T17-xsil!rVkcW2()` z0MEeOg`(Sy?i3}S7ioh0vniyX{}j&?>A!n+q|*aH3yAKGgw?E1Ic*Y+*S?yuuu{H8 z^a=dmJQ4j8TF<k`IV2O!FD&?%C3wrWD8s+B=|`icOkWz`3jJw(tMsYyb+jjWAer+n zcYP%V6<yoHjQPVn-}muG<iu@r+wc$ofO%oA!?Lo6e%x(Xi5<yaN4<m|yA%>lfK)C2 zE9cOYo8uRz7HsAn*7skU1c?!6*fIYUaR=Hq{?B0iXp+-ZxsZB>yALUw-gZCkXlozV zoAyQe0a#zSCt>ieW3L;hV1x!SWu3eM`yJ+w7VWvW(v`(3?(}(hZ0>XJJEu5$FB?Eh z(zxr#IBbJ07gP=hB7$rCac63FsuQY~T#d?GL+zpa15v0Nq7cPF<~B%i%GCzi)GU<0 znO4ns_c2h<zDHQ~z+LV|(C<qT__2iZAAoL|g2Sp)E98C#VVySGzdQ`{x+nXz#9<pm zqYdpGtv@uAMI4il^F}EemU<amnp9~fU}JVOO*J#39u_>aI6gGZGg*6^7I6MBUoh+A z95eo5fx@NKx893g$Sf12r+kx~UWK@uI4kN^th}yXL;BFvh&_f+rbT{^F6kMl%;J-^ zKN+8G<G%60FpX_}{Jwm<z~}uCp6@NqT!^p0ksA%^=1d@LnCcBIt=?o(SlQZQOlqEo z4U@|AenIGHFdMdGjt@`MyXZ3mA*s#xBfJqQo<k^1oKZ_5l4w9msN?wNTW)(W@pi)i zAt7(kcK;=3;*^HHTS%lGX4dD9Qxa<NM3Y!RJZ&1AOs$S}gmkjj$IjW6=#0Cf&NWKJ zRx_pNsY4i$imbiJ0+5s(f-1j4w|(SR+JTa=md^G9r##H$6(*YIL|&~hS!L2-GT8#1 z)0X=&H2e!*O-RRdO7$hjajH&5v89c7=F$6vn&`VoCK`a!|E|$7wFam?T?5=TY@<~J zoen5Ek>lnrXJ?p46r-VR2c4juc>|1kAb@gZy`2L>=xBY@SmUNd|Ar(sVr<5ab>G@H zADE^Qmp1MDW#)x>6zt+v;_7|p0duvubib~1bK92Mi0AJwJTPwC@#3~EtoXpTy<_f_ zZkI)AyDaSU#u1KL8dOA?Up?<ZY<uN_dAp)Z%i9%EK}`+s65ct?VQgZSj(x;<U}4mu z?GjRij)A^24vOQnD>_Mv%tR+CPx(B#AC!TPYDw{)4w*HI`N!oZMQ2hD7@r-N)>dxy zNU=vhdGwQ#kr?CJO0*I+nXESsCuJOG_?+Ax%~pvOMw)MvD&iVcz)6ksd9>D&N<^s~ zCv%8sbi*jtK@F$KRZu+)L{ef>OCf~5Q(Ql(q7jCnO6;y5b(3;BxQZZ!p2gk_gF!Mk z8U&w@q;~9;i(!pwD)XrQ6DLPnHzj7Q-bS_hHWJ9jlgv+8o`>W=@kSIBMtR9xHtYD= zVE!d@$*P!(HOH)=jGABDk1FNyL25T{NMSWRCJ-n+-shxysDN)5dvHZUg~Gdqut(%h zX+b|N_;>5JDH*@F6fGjT|HHL25w=`_TQolxycY_1FUfeM1}=lMsbYp55N>SBwl-=A z?W{wZa;WP*4et5C^ZPmmjq(3G1^VF$=u<tO3;Ojb==<Rf>H1oD!0fpi$<C-pMAE7h zcE*77cx2&^OqAHuP^oWVg6kR=6Ph94gF^)(llI5Zpb*nca|D@bEdr5I>XdR#vY2TS zcWq7U6FcQ-tx3Lvk^8C>E%vK~iUAtKoHy-9Gt8W+66?x(qrO|05T;b2{2p`XnOtB( zU6L$h8m$eEhR&L(7P<y$P>7=AKk#O%#Wok;a4P)GSlpxmBZhy#o}VI#p-Djt^N0~! z!V;yQmMFltEny!sV&3C5kuMA5&#Ys{Z7VKsTRWyGU$@l7?NW3R!nY)<XCbDyt?kmE z(;{%z$G;0J5T;2QHd}%7se^*kH%H`UN-{(e+t*>ve8IB>SEG(NVEcLxMtV<ykj58G zuBfwYtt8G(Uk$)UQDQTfEPnvyE!#R|^;z1K)ETkEEQ7X8N)g0dsV4^wJ1Mn$QBndV ziR~-SaQ&u;rU*&(i~we*=XGTdqIjPBNOQx0u(Avbf@#s3H<wJuRHR#*P5DzohOefo ziwtf<t)9_0Z{y}PwzjR!k|=ecj{X5EQd7wuKe*_(V|`;c8nkuL4H4}d&=zS(W&?Bp zl8EuQ!#?DHuo3ivcq_B^KM1ujLtKtV_(0x7FCpn`q_=aY+%yR8G8WCVagoH%?_>0l z&9|W0LzldeZB=?6)rY_YcK!TxkMZHW@65o4t$qi+)g>mRPZ|c#mqwg=oh>9#+GoPT z+A!kX^GhT-1-en0C($2Sc)v28|LM0vXC39wvE7HzeclA*)Z3HN3o~8DNAk|infjd8 zS4m7w>-3T#Uw($zy3;OVFJj=z{|mAI`L{ys^bRFQ_cx<9gw0~~IgXUfi99}<=bEz( zIlVtC=$+l-<PgjdT=&{V@B<k6&YlF<HUwJv<WhuREqd-6cg>DPS#rm@4JiWYTJjyt z^8sQD%7^rTbrZC^t{nIqxYgI1H@&A6X%7mMOuS^0<AS<2qVtY>PHjG{K?KL$Gdk4~ zjDiSxd*;3)m@=f8@_UUlZWepc15!7g+MPr5a76YmfZRlJ&$CgAldGq1`0BJ84NmvB zXmGB=gihlF@4Yjzo?TovxM_!zxQuFKz~-~@PM7%^6;D!9y-`s|^wVSGzIo4hV3Le? ztq%XX0z&SXx1sJx%Js)&3#09?bNIV@_&xI;sQ*)ow7+lCD<3c3qppJt|IGMD><8*C z*8eaKmsxa#U5tej>QLm8Lna<##wSUIlASt;G(lIJdz6|L96T|elj=={KWRwy`(z%* z<_zc{$F$5vYy4J9(dJov@ehD=O}*!nVm1_kyPD>KFoXsyvo?aC{v$5*$4DMpla&Fz zuGh-2tmpfPE2s91V=h-y@sEJe?5Y}Mpr?a_E~oaH=wt9F%xNKi5V`MgK5mmSzgPza zpnSBRQ9od}D@f>SHx%t5UMO}(u!(VnsJOlA$4u6kyu;*MOfDixs&HnsSF?~^`d-m~ zS?cms(t>t<*1>a%>+?<$caFH6tQB{h`btq>uPJ)Diu|DH>nhS-F=DN#ppr^zmTRv) zb=oM06}6b6bX7d@iug{{Vq$we#7{4yGSSz*WDrI9+_JqsT6m?W{)ov$eCV9s4(DuY zMxE2*frPTZF>fJ;kp4<_eCJKpz*^xi{WATvU0IsPZ%+Tx@7mHCXVIDCuYL^UOb47* GvHlNEoM<-y diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-38.pyc deleted file mode 100644 index 74ccf1191a702199b1e48ecc9f1e9140515419ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2273 zcma)7&5smC6tC*;>F(*B9Tu1%A8J~Jg-(D?kVs-=K~#td4koJ+I>t`#R4w#Of6P|Z z06Q5j!XLoNL=%&lBZ&vE{wsCW#O#%$2k^b>S=c3zSV_Hpuj+l(d%vpwZgDXnF#fss z$B#b%_ZJGghXcYDnDQGSj4+y$g2t30Z{=2OnXet&%w|sR6pgr1xUpM!u~+!9Uo_)p z5ySx{*9mJd_c38EZ#=T&1!k?0$lC_5B%*p>x-P4Hq<E4Q!%C>`HpLBB`!}lI;A$$l z4v@Q+W;tiN*{u|cbN1^k6!ZepZ?l3|Bc&HV%LPxF+2O2*adr<Igex%RCqOufDI;(e z3g=kFlRT!eQ|B8un8*CbBz9So1@QIQ0&Bt7Hz#Q8){U$jnA{+>@o&h5X|Knn3{@4T z;RY;+Bbk+V!c<j7)(eNC8gikw!fGST!T9v~=v)wlFjiMr!yFx43U_-weM(jZM@Ofk z|EYH-RCn?GoL#z>=91TT-JS)<-5J<hALi#UWe5cycNCeBK4tWgHMM4hlJ7}*+#$*y z1ma@~G9}7k7U~=#kLXYIHYu%JWCGP2G{qMaS~{@Tcu18yb!X(EHQ(vO*B&^cKY^8t zunv*DsgHhOHfNTJ^fN>X2Eh|5I`dfGbOCi{wBLGYPoOUYOZ<Ktu(!4o^I08fVuAN( z;B&For?`(1|5k0*fVF*fzGYi2G53`W*8A%mA!-1ecZ@ut!xr;rfbrX8vwzD(+w5b^ zsM*!l{q^y|4Ff~$Zx4#Bcz99@1nf4Jcf35uV0b^x6!sl)(Aykkg4f;Ms03JyJ11qB z$uO;fYPLAr#`}2Z*I#h_c{w_u9RN$I7e-~aIpRr~7F;)ac?CDZ`|9SGLR3ODz(jj$ zj(i6hZB<e`h%VhkL?wtG?cH267TS?2Roa&-DUFUhGGBpk(9SRg@HCNa$ei<G<bVOs zH^c#4^Lfb<6T>w|@+lD^Z2Wt5MHR!9VKzLQmEb?m&z`?~Vf5gmD#b-JlY3xXi4{x< zGg`suJHol)miFd_+7Axpc_4&Zv_sppV;!JAU825&@{-l2zU|r_+JaTba-RE+L!B3{ zb;2HZcHf<IbB8_b&(1&|UjT!AeAy;sN@heJR)Bp#hc!pbyUOlcQ-kRll^2w2us`2b z_S6I21|nt78`K!2*xm6`-QKcN^VW`!)hl>j&d!AEBNgKA`c_!*sHvNoOzJ)1LQdis zk`55<@&}nzQtZPO56Mv^hk!h#;yvWUm*fNBv?qAZ;n}<hf@}dHrh09tWQ)F5p}FeY zE7S&a1@~}@H{YJoHHg}c9Ftp}<q6O*>4=lag)a#vBR&Lj8KyL^4;>%c)1a59etQC^ z!MJWwwX7(##D+wi8AWM|*Bki0%jf`qDpptEfg{hveLYE2!o#pHjv#qMy1JDmX<<46 zm-i}YN%N0{0=8aQ*3$Fwk-hov(ti69-UmOsYbcH?Vvq&(#J}kp5vM>UYP_B>Ho0#1 zn{o}-;Q<<$WUphU_@)zR^7x%SIlj`0pmR;_C*~zd5*;K-QL$0Zfo~<r<|xhajRDC^ z5?1w+L>$KqmXTm11vW!ONW#6u^cqWr(|``HrW-8#zHj>tfvZsq18$7eNI(dIcn}AX q7?=}*>6_=Qz5xd6_$Hax$ar{DQ0;$OpJ5d*wnT%L<x}4Zo&NxUycp~N diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-38.pyc deleted file mode 100644 index d3a110e4ace7abab16da88f796c2916640d12137..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2641 zcmb7FJ8v6D5Z=8PkH?2-TbAWVaR?$iL~JQhoTP~rzXJm{6F>@L6G#px?#Vjw9@OsA zmI$he{1ei|6<NAVn?I0W;A*P?DFU}CQ`ni=BdrJQB74}`*_*wa*Eh4@*J>Vt@%NM8 zewwcm@)vFn4+}QeVG0I>5k?b|(l$+vwn1@kBxc*xtJSvjYPW5@I&FuU%t}hB+ji4( zyPSG$FRipIX|-KVYwa2(-w<Xq=NVy6<nEj8Ix|*Dv-Aoyk*1+$!gY}+eHjID+RM3A zE{mVUBF?kcD~d-P<=)Rb-J79^l!x5iFis+-%B@`DcEUc`#f_>UU5nEw?@Lv?k?<&F zS`x7iYCJql*j$GxZUc!(n=;Zi7zIxo%wqO43cj9T4l4m?GnbX05%AVy6<ABG%4)E> ztj=a&Ei)6mI;m<8x-90}Ot5nB0doEZu>Sh4-vMi6oIUnK9}Yzwne*MnwN?kiKOM-I zVBUf$z5pW0hz`k+4vnEXwkVOtmN~M9WXopoe#?Pbg6VFUb7X7`Nl?}SHV4A<Cu3!0 z#ZS<XYyJ`QKDs3GG(zhxHUH1y%f8&iz((xa-7pc+!N-Hrf>>M-3!>HZxDD1THwfY^ zmO-G5Tqvs-%1vc$<#DFUXi|XMmAjb>nT2Vj>|!x{F;kU(7H{{X00m7;St3d{cwPT= zs$Z34k?R+P&x7ROTT3$SE%oBwl{gbJOp+_hn^*fgpXDLG)H8SzWi01Qs2;U1rI@nm zZn3w^p+pGk5lD#LFg@x}i(0R(H-ot&5nP;l*D>(uWT4|NOr66zpm+$->XvzRNHfeF z*`tz<=$Pyo6Uj2Hv}^HY$TIzM`rhT&nXzYPbqTP96Xtoc5BotwP7pArl>9)lUo0Y> zuE+nO1Rq%%xnshtvt-X2T3cmV-txKz|5KV<l~EP+*T$4Te*}fSI<@R&Vb9P28(vOq z`9s#34W}z}WS{;_!HOA%Xq)Weiv}PPEC9&~h8VPqlaI)D>miXRQ4@3bjnSzwScTfQ zTS%Mb7RS<l{QOrOzkmG-yAwy`4=zq>*MAzux>RKDhn?*{luH5Ojhy=nVlcZP{8;#5 zQQ%q>vB9Yg-5Y%PNY`2fN0sq(y*bOzz~7aHXi;Vw?(iD!ZJm1FK)&?t>K)E=u1v8j zlpF1I0Js~uvLnv3Tse2{JiNEMR^ZQxc48p~pM?*383}rzY>`A!k2}a)c`wS8-AQt& z51XIHL)r!x&=+VsEc8*C@PCcnf}F*VOB0vR!$w>MLg-2A(gt-6mpVq>G=Q(uDy<rI z!=bYvvkdFCYXeB%I7Zc+H5znq`Y2Q<|LkDsrvrIxgBq#d0W%~cGA3eP0v;iM#w7O_ z06Rv}b;eX&l@5bWGnE1wb@mYpz`GzRBd>F9wg!zNS6MEnc{*Rb!J3QMWq-XdeUw6r zgi7~RITk@7<Jbyy%yq)}hq%>I$NExEKTG1Qt8AV^3F|z*phc{)8yt=(kCF(kkQ?w? zV0{xE&$^D{@kmY1zCTjf7bMxDBa8ynz$$q`TTQF55ru`Jh%3H?<ft|LGQ7J7Q|PWi z2WO6E>aF|lw_pywE^?L6N(#9#!4eBC;h%yC5QjRB8>A!m4ue!R4#HH&9ImJPXc>YS zV^n=JICsptLr0Goh|avdy6(c}aESO#xX7^iLAY*{AJ0JxBqLj&z@}mj>DWNfY@dVo z2q)cI5JH7R?r~p=qD`O<G4)qK9iKt62&8Ff5GV_;j$^@B-a6b}UF|F)ULcYP;GjY0 z>0th-uLnn)##*ZhN%rtY!{5S<<^@5TvwnhnH3+u*VKR}Ff`H|nAkbF{{}>eTPmt)O zEF<?hk^@+14r`xRfK*}X%LnS3dNuE&>$;|EX<2gy^=|ZKpMzeGLFZV)`~nheYurcj o0T4y>C9FGAQA+6SLC4ZRe3uo<{i^V61v`W;m<F^S{TROWANVqC_y7O^ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-38.pyc deleted file mode 100644 index 42efb16f247e057edbf533700f254fecff1bde6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4845 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-38.pyc deleted file mode 100644 index 1e38b76eda937ee65b18c10ddb81095aec10c0f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3700 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-38.pyc deleted file mode 100644 index f7562045d8705671219524264e76f50e1c9cbce6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2162 zcmZ`)%W@nw6qVG^dH4}yk~lG;c_d`2h+Q>MzygAS1U6w<*c7A}bhStAxIO(COKO9s zCL7`pU<-@X%rZNQ9aVe)-_TnYlz)K*;a+u5VjNpjlCB<ob#(60ov-KSngq(<2fu#z z0a$<G;AAmjumM%xgN74M6OvM&QnXpZe5QNDH@Lyg#7r&UN^Rdx9p6b^-%T5SgOV=@ zx43;oxE)!K48O_QCh0iG;E{A_xe#v4JSkKZ#OW{>s&`Cr!7AN*d4KR}D5J8`%M}hH zuFWqGaZt9f-HOvFFH|}ANg|?<>y?Q2(f7$>z+eNayaP={e98%6r+|Bro7_60zR53e zn>%1x+~tiU;@iB*ThKea&F7$Z`8;2MzQGN^zf>-49;Qj04G_lXaT1N*Ldy&L{YXkr z<zDFRz_eG$ID6p9YV*x*XKkz3M_y+IZ5!%mP~}Z%6q(R58PhQv8&i`K#rBMeIVOA7 zlybU4#w4&f0Sv4s@M0ZXppViGf;fv+5R@#Jr8x}MZfVJ3605RRWbu9x1zDIz9kVoL zl<bJM{z&a2aX_u3DlVT8u>>ps++A1caD5mLZ^fBZVUpbH?!H_6@J=4$q^`k1l<{1w zCvb7R>w105*?4VuC{SQ?P^G>zTV$ilr-)md;qEioH!FBE7pkV^PcX(1v_V6($23DS z$U~~=gigsrR<CrSrvp=TfjIg;%#W58n;5XSB9Bq>4ap8nqU=Fa{6Pu+#$@75iQxA^ z(wnn09#@{n47@$Az5b+J&cIjWB6&oAq}jY`a`at~;fq#{<2UHdt0ZF_0!GPwvfuqy zd*AQsu-QF<5+B{D#p`_^#tJopn(6Nsv4}im(A&v{cU_K_uS+kMURWtyFGc(qd42H9 z&scu{xYHIFU|gCQL(xLhsbeALanwME0mi6wzS_JiL@vs99E53r3vjq_V4IeNK-NJx zNfZq`hFHLP?c9Z62l@cihZc!=3HLfRY8=QL&=7lxx^$7cCZo%Ap1I66mSM(Z=D)6K zQuC?JJY#g}v=C}PeWYhr&_*q29oz;3B1Wb}URDro;Gfm;xCrwG%&#d^$EluI*2IQg z4n{(=Z}dis6`@(KYBEPxs~O}X;%|G~h4OH9`_O~;;+BnAYMvr4EI?4vw1O5s+=_3z z$S@m-OEB|<R<xbwNkmBm3GF@DB6Z@eSfcavMK0>S=W~H^Rb-D&P?g4%Zo;v>j;Ya9 zZ`+RLGf3i9MEZX~;uV<t2*K!wM@K8C1M=+N=fm*e`;##8YmmS2!2u*_tpQ|v@fvJ` zG=;*f$a@_vq^fi={b-nYp)+A3(;HAFvQ2=k#iygy7oeUH^Z976frFE1#g*r1D}hv4 zt+TKS{Q4|}Wpf*DG0+;h1AD4mhhe>P8s_tj9k$i$K*XAuxG^z9;%){(n)4z-yB!4k zMVQnpP7v_C9|Ss|id6*SVS^zQT8eL?^*q4Z!WStT(4g8R5{!?qX*b_+9oKM8z1C^r zxjTg_1e_~S3)Ssk2CF3c&!y76R=Z9Vm?QMZXPsEOA6B=xjgMF2-Zpco%T~?*04|p5 AuK)l5 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/linklockfile.py b/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/linklockfile.py deleted file mode 100644 index 2ca9be0..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/linklockfile.py +++ /dev/null @@ -1,73 +0,0 @@ -from __future__ import absolute_import - -import time -import os - -from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, - AlreadyLocked) - - -class LinkLockFile(LockBase): - """Lock access to a file using atomic property of link(2). - - >>> lock = LinkLockFile('somefile') - >>> lock = LinkLockFile('somefile', threaded=False) - """ - - def acquire(self, timeout=None): - try: - open(self.unique_name, "wb").close() - except IOError: - raise LockFailed("failed to create %s" % self.unique_name) - - timeout = timeout if timeout is not None else self.timeout - end_time = time.time() - if timeout is not None and timeout > 0: - end_time += timeout - - while True: - # Try and create a hard link to it. - try: - os.link(self.unique_name, self.lock_file) - except OSError: - # Link creation failed. Maybe we've double-locked? - nlinks = os.stat(self.unique_name).st_nlink - if nlinks == 2: - # The original link plus the one I created == 2. We're - # good to go. - return - else: - # Otherwise the lock creation failed. - if timeout is not None and time.time() > end_time: - os.unlink(self.unique_name) - if timeout > 0: - raise LockTimeout("Timeout waiting to acquire" - " lock for %s" % - self.path) - else: - raise AlreadyLocked("%s is already locked" % - self.path) - time.sleep(timeout is not None and timeout / 10 or 0.1) - else: - # Link creation succeeded. We're good to go. - return - - def release(self): - if not self.is_locked(): - raise NotLocked("%s is not locked" % self.path) - elif not os.path.exists(self.unique_name): - raise NotMyLock("%s is locked, but not by me" % self.path) - os.unlink(self.unique_name) - os.unlink(self.lock_file) - - def is_locked(self): - return os.path.exists(self.lock_file) - - def i_am_locking(self): - return (self.is_locked() and - os.path.exists(self.unique_name) and - os.stat(self.unique_name).st_nlink == 2) - - def break_lock(self): - if os.path.exists(self.lock_file): - os.unlink(self.lock_file) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/mkdirlockfile.py b/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/mkdirlockfile.py deleted file mode 100644 index 05a8c96..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/mkdirlockfile.py +++ /dev/null @@ -1,84 +0,0 @@ -from __future__ import absolute_import, division - -import time -import os -import sys -import errno - -from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, - AlreadyLocked) - - -class MkdirLockFile(LockBase): - """Lock file by creating a directory.""" - def __init__(self, path, threaded=True, timeout=None): - """ - >>> lock = MkdirLockFile('somefile') - >>> lock = MkdirLockFile('somefile', threaded=False) - """ - LockBase.__init__(self, path, threaded, timeout) - # Lock file itself is a directory. Place the unique file name into - # it. - self.unique_name = os.path.join(self.lock_file, - "%s.%s%s" % (self.hostname, - self.tname, - self.pid)) - - def acquire(self, timeout=None): - timeout = timeout if timeout is not None else self.timeout - end_time = time.time() - if timeout is not None and timeout > 0: - end_time += timeout - - if timeout is None: - wait = 0.1 - else: - wait = max(0, timeout / 10) - - while True: - try: - os.mkdir(self.lock_file) - except OSError: - err = sys.exc_info()[1] - if err.errno == errno.EEXIST: - # Already locked. - if os.path.exists(self.unique_name): - # Already locked by me. - return - if timeout is not None and time.time() > end_time: - if timeout > 0: - raise LockTimeout("Timeout waiting to acquire" - " lock for %s" % - self.path) - else: - # Someone else has the lock. - raise AlreadyLocked("%s is already locked" % - self.path) - time.sleep(wait) - else: - # Couldn't create the lock for some other reason - raise LockFailed("failed to create %s" % self.lock_file) - else: - open(self.unique_name, "wb").close() - return - - def release(self): - if not self.is_locked(): - raise NotLocked("%s is not locked" % self.path) - elif not os.path.exists(self.unique_name): - raise NotMyLock("%s is locked, but not by me" % self.path) - os.unlink(self.unique_name) - os.rmdir(self.lock_file) - - def is_locked(self): - return os.path.exists(self.lock_file) - - def i_am_locking(self): - return (self.is_locked() and - os.path.exists(self.unique_name)) - - def break_lock(self): - if os.path.exists(self.lock_file): - for name in os.listdir(self.lock_file): - os.unlink(os.path.join(self.lock_file, name)) - os.rmdir(self.lock_file) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/pidlockfile.py b/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/pidlockfile.py deleted file mode 100644 index 069e85b..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/pidlockfile.py +++ /dev/null @@ -1,190 +0,0 @@ -# -*- coding: utf-8 -*- - -# pidlockfile.py -# -# Copyright © 2008–2009 Ben Finney <ben+python@benfinney.id.au> -# -# This is free software: you may copy, modify, and/or distribute this work -# under the terms of the Python Software Foundation License, version 2 or -# later as published by the Python Software Foundation. -# No warranty expressed or implied. See the file LICENSE.PSF-2 for details. - -""" Lockfile behaviour implemented via Unix PID files. - """ - -from __future__ import absolute_import - -import errno -import os -import time - -from . import (LockBase, AlreadyLocked, LockFailed, NotLocked, NotMyLock, - LockTimeout) - - -class PIDLockFile(LockBase): - """ Lockfile implemented as a Unix PID file. - - The lock file is a normal file named by the attribute `path`. - A lock's PID file contains a single line of text, containing - the process ID (PID) of the process that acquired the lock. - - >>> lock = PIDLockFile('somefile') - >>> lock = PIDLockFile('somefile') - """ - - def __init__(self, path, threaded=False, timeout=None): - # pid lockfiles don't support threaded operation, so always force - # False as the threaded arg. - LockBase.__init__(self, path, False, timeout) - self.unique_name = self.path - - def read_pid(self): - """ Get the PID from the lock file. - """ - return read_pid_from_pidfile(self.path) - - def is_locked(self): - """ Test if the lock is currently held. - - The lock is held if the PID file for this lock exists. - - """ - return os.path.exists(self.path) - - def i_am_locking(self): - """ Test if the lock is held by the current process. - - Returns ``True`` if the current process ID matches the - number stored in the PID file. - """ - return self.is_locked() and os.getpid() == self.read_pid() - - def acquire(self, timeout=None): - """ Acquire the lock. - - Creates the PID file for this lock, or raises an error if - the lock could not be acquired. - """ - - timeout = timeout if timeout is not None else self.timeout - end_time = time.time() - if timeout is not None and timeout > 0: - end_time += timeout - - while True: - try: - write_pid_to_pidfile(self.path) - except OSError as exc: - if exc.errno == errno.EEXIST: - # The lock creation failed. Maybe sleep a bit. - if time.time() > end_time: - if timeout is not None and timeout > 0: - raise LockTimeout("Timeout waiting to acquire" - " lock for %s" % - self.path) - else: - raise AlreadyLocked("%s is already locked" % - self.path) - time.sleep(timeout is not None and timeout / 10 or 0.1) - else: - raise LockFailed("failed to create %s" % self.path) - else: - return - - def release(self): - """ Release the lock. - - Removes the PID file to release the lock, or raises an - error if the current process does not hold the lock. - - """ - if not self.is_locked(): - raise NotLocked("%s is not locked" % self.path) - if not self.i_am_locking(): - raise NotMyLock("%s is locked, but not by me" % self.path) - remove_existing_pidfile(self.path) - - def break_lock(self): - """ Break an existing lock. - - Removes the PID file if it already exists, otherwise does - nothing. - - """ - remove_existing_pidfile(self.path) - - -def read_pid_from_pidfile(pidfile_path): - """ Read the PID recorded in the named PID file. - - Read and return the numeric PID recorded as text in the named - PID file. If the PID file cannot be read, or if the content is - not a valid PID, return ``None``. - - """ - pid = None - try: - pidfile = open(pidfile_path, 'r') - except IOError: - pass - else: - # According to the FHS 2.3 section on PID files in /var/run: - # - # The file must consist of the process identifier in - # ASCII-encoded decimal, followed by a newline character. - # - # Programs that read PID files should be somewhat flexible - # in what they accept; i.e., they should ignore extra - # whitespace, leading zeroes, absence of the trailing - # newline, or additional lines in the PID file. - - line = pidfile.readline().strip() - try: - pid = int(line) - except ValueError: - pass - pidfile.close() - - return pid - - -def write_pid_to_pidfile(pidfile_path): - """ Write the PID in the named PID file. - - Get the numeric process ID (“PID”) of the current process - and write it to the named file as a line of text. - - """ - open_flags = (os.O_CREAT | os.O_EXCL | os.O_WRONLY) - open_mode = 0o644 - pidfile_fd = os.open(pidfile_path, open_flags, open_mode) - pidfile = os.fdopen(pidfile_fd, 'w') - - # According to the FHS 2.3 section on PID files in /var/run: - # - # The file must consist of the process identifier in - # ASCII-encoded decimal, followed by a newline character. For - # example, if crond was process number 25, /var/run/crond.pid - # would contain three characters: two, five, and newline. - - pid = os.getpid() - pidfile.write("%s\n" % pid) - pidfile.close() - - -def remove_existing_pidfile(pidfile_path): - """ Remove the named PID file if it exists. - - Removing a PID file that doesn't already exist puts us in the - desired state, so we ignore the condition if the file does not - exist. - - """ - try: - os.remove(pidfile_path) - except OSError as exc: - if exc.errno == errno.ENOENT: - pass - else: - raise diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/sqlitelockfile.py b/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/sqlitelockfile.py deleted file mode 100644 index f997e24..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/sqlitelockfile.py +++ /dev/null @@ -1,156 +0,0 @@ -from __future__ import absolute_import, division - -import time -import os - -try: - unicode -except NameError: - unicode = str - -from . import LockBase, NotLocked, NotMyLock, LockTimeout, AlreadyLocked - - -class SQLiteLockFile(LockBase): - "Demonstrate SQL-based locking." - - testdb = None - - def __init__(self, path, threaded=True, timeout=None): - """ - >>> lock = SQLiteLockFile('somefile') - >>> lock = SQLiteLockFile('somefile', threaded=False) - """ - LockBase.__init__(self, path, threaded, timeout) - self.lock_file = unicode(self.lock_file) - self.unique_name = unicode(self.unique_name) - - if SQLiteLockFile.testdb is None: - import tempfile - _fd, testdb = tempfile.mkstemp() - os.close(_fd) - os.unlink(testdb) - del _fd, tempfile - SQLiteLockFile.testdb = testdb - - import sqlite3 - self.connection = sqlite3.connect(SQLiteLockFile.testdb) - - c = self.connection.cursor() - try: - c.execute("create table locks" - "(" - " lock_file varchar(32)," - " unique_name varchar(32)" - ")") - except sqlite3.OperationalError: - pass - else: - self.connection.commit() - import atexit - atexit.register(os.unlink, SQLiteLockFile.testdb) - - def acquire(self, timeout=None): - timeout = timeout if timeout is not None else self.timeout - end_time = time.time() - if timeout is not None and timeout > 0: - end_time += timeout - - if timeout is None: - wait = 0.1 - elif timeout <= 0: - wait = 0 - else: - wait = timeout / 10 - - cursor = self.connection.cursor() - - while True: - if not self.is_locked(): - # Not locked. Try to lock it. - cursor.execute("insert into locks" - " (lock_file, unique_name)" - " values" - " (?, ?)", - (self.lock_file, self.unique_name)) - self.connection.commit() - - # Check to see if we are the only lock holder. - cursor.execute("select * from locks" - " where unique_name = ?", - (self.unique_name,)) - rows = cursor.fetchall() - if len(rows) > 1: - # Nope. Someone else got there. Remove our lock. - cursor.execute("delete from locks" - " where unique_name = ?", - (self.unique_name,)) - self.connection.commit() - else: - # Yup. We're done, so go home. - return - else: - # Check to see if we are the only lock holder. - cursor.execute("select * from locks" - " where unique_name = ?", - (self.unique_name,)) - rows = cursor.fetchall() - if len(rows) == 1: - # We're the locker, so go home. - return - - # Maybe we should wait a bit longer. - if timeout is not None and time.time() > end_time: - if timeout > 0: - # No more waiting. - raise LockTimeout("Timeout waiting to acquire" - " lock for %s" % - self.path) - else: - # Someone else has the lock and we are impatient.. - raise AlreadyLocked("%s is already locked" % self.path) - - # Well, okay. We'll give it a bit longer. - time.sleep(wait) - - def release(self): - if not self.is_locked(): - raise NotLocked("%s is not locked" % self.path) - if not self.i_am_locking(): - raise NotMyLock("%s is locked, but not by me (by %s)" % - (self.unique_name, self._who_is_locking())) - cursor = self.connection.cursor() - cursor.execute("delete from locks" - " where unique_name = ?", - (self.unique_name,)) - self.connection.commit() - - def _who_is_locking(self): - cursor = self.connection.cursor() - cursor.execute("select unique_name from locks" - " where lock_file = ?", - (self.lock_file,)) - return cursor.fetchone()[0] - - def is_locked(self): - cursor = self.connection.cursor() - cursor.execute("select * from locks" - " where lock_file = ?", - (self.lock_file,)) - rows = cursor.fetchall() - return not not rows - - def i_am_locking(self): - cursor = self.connection.cursor() - cursor.execute("select * from locks" - " where lock_file = ?" - " and unique_name = ?", - (self.lock_file, self.unique_name)) - return not not cursor.fetchall() - - def break_lock(self): - cursor = self.connection.cursor() - cursor.execute("delete from locks" - " where lock_file = ?", - (self.lock_file,)) - self.connection.commit() diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/symlinklockfile.py b/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/symlinklockfile.py deleted file mode 100644 index 23b41f5..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/lockfile/symlinklockfile.py +++ /dev/null @@ -1,70 +0,0 @@ -from __future__ import absolute_import - -import os -import time - -from . import (LockBase, NotLocked, NotMyLock, LockTimeout, - AlreadyLocked) - - -class SymlinkLockFile(LockBase): - """Lock access to a file using symlink(2).""" - - def __init__(self, path, threaded=True, timeout=None): - # super(SymlinkLockFile).__init(...) - LockBase.__init__(self, path, threaded, timeout) - # split it back! - self.unique_name = os.path.split(self.unique_name)[1] - - def acquire(self, timeout=None): - # Hopefully unnecessary for symlink. - # try: - # open(self.unique_name, "wb").close() - # except IOError: - # raise LockFailed("failed to create %s" % self.unique_name) - timeout = timeout if timeout is not None else self.timeout - end_time = time.time() - if timeout is not None and timeout > 0: - end_time += timeout - - while True: - # Try and create a symbolic link to it. - try: - os.symlink(self.unique_name, self.lock_file) - except OSError: - # Link creation failed. Maybe we've double-locked? - if self.i_am_locking(): - # Linked to out unique name. Proceed. - return - else: - # Otherwise the lock creation failed. - if timeout is not None and time.time() > end_time: - if timeout > 0: - raise LockTimeout("Timeout waiting to acquire" - " lock for %s" % - self.path) - else: - raise AlreadyLocked("%s is already locked" % - self.path) - time.sleep(timeout / 10 if timeout is not None else 0.1) - else: - # Link creation succeeded. We're good to go. - return - - def release(self): - if not self.is_locked(): - raise NotLocked("%s is not locked" % self.path) - elif not self.i_am_locking(): - raise NotMyLock("%s is locked, but not by me" % self.path) - os.unlink(self.lock_file) - - def is_locked(self): - return os.path.islink(self.lock_file) - - def i_am_locking(self): - return (os.path.islink(self.lock_file) - and os.readlink(self.lock_file) == self.unique_name) - - def break_lock(self): - if os.path.islink(self.lock_file): # exists && link - os.unlink(self.lock_file) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/__init__.py index b326507..d6705e2 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/__init__.py @@ -1,30 +1,19 @@ # coding: utf-8 -from pip._vendor.msgpack._version import version -from pip._vendor.msgpack.exceptions import * - -from collections import namedtuple - - -class ExtType(namedtuple('ExtType', 'code data')): - """ExtType represents ext type in msgpack.""" - def __new__(cls, code, data): - if not isinstance(code, int): - raise TypeError("code must be int") - if not isinstance(data, bytes): - raise TypeError("data must be bytes") - if not 0 <= code <= 127: - raise ValueError("code must be 0~127") - return super(ExtType, cls).__new__(cls, code, data) - +from ._version import version +from .exceptions import * +from .ext import ExtType, Timestamp import os -if os.environ.get('MSGPACK_PUREPYTHON'): - from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker +import sys + + +if os.environ.get("MSGPACK_PUREPYTHON") or sys.version_info[0] == 2: + from .fallback import Packer, unpackb, Unpacker else: try: - from pip._vendor.msgpack._cmsgpack import Packer, unpackb, Unpacker + from ._cmsgpack import Packer, unpackb, Unpacker except ImportError: - from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker + from .fallback import Packer, unpackb, Unpacker def pack(o, stream, **kwargs): diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-38.pyc index edf902819f8641ad11c85a9d3ca0eac6b6776a44..83b4e7f8193456f5900a9a319aa4939bb76c162f 100644 GIT binary patch delta 671 zcmZWn&2G~`5Z-lcujAOxUrAa7NWCB;XnlY~xgY_mK&mJaO$FTp!O3o0C;o|coha$0 zLgEZ6egTlUaDpp+0FE4xxa=F`6?#DIrbq~|<(Y40{LRd_+OOp^+uL<r8_1{i^R)Y1 zKk+WX?<dz+k7ENH5D=Xhk%`TPM;K9aV7)66^F8F-6b)>muK<FE8Y2V{D=Nhfc48O1 zv4=efl6yzXi+uU-{8Nxz(*dmvZT0~I_5R1cE$Mq8(VhWPB=#$StE5C6>1)I#p7eEE z$4k`37ibkXXbm@su>)G=IeZJ3ZfOE-PP5KzL`AU^#*}A4Jen(&+qm{<=Ry1K{jF|$ z_sM2^uk-Nn_FR*d{Bz+8wDN(zw)GLPs?41A{KGV+KAVllgV5)!?~@=2Y1B_yM)~@5 zcH~cJGV!CZ=Z|LDVVc}r-|%^u(X~;~9|i}M=RdU7x+9y_<;QhtfN4YK<fr<Z4NFE$ z6<Zo}6)r2IMxUFSM8Z(5dY2{SYE59Wdj8V*c3hOWRbZZU3!czPkOlv;&2ggmSLI*l z(~$*PLs6H7)tykr!!%*4v9Rg1Pe+-IxhT+S#?-dVP$eyuDL&%@Nx30Q6H&NvKr`X| zZqN;r{Zv@{K@|1mG`0|?7G&yb;bMLVHA_k;Q^&v>`3rQV@<-<a)$-S9#ex;hf>z;T I{s}dI0sM`kAOHXW literal 1990 zcmb7ETW=dh6rR~#uh(lkx0a|Xr7Sm5Bh{e=2~+`sLR3&ih?=CAedv0<Gfv&?#mtOz zv0RWyq`sj32IsMF{1Se^yz+qh7kJ{FSvw>sJTTUtIdf(_=X~dUXSSM6pTPKY_qWH7 zT|)lA#p&U};!F7C?;sdqG$k1gDMj5%txcTm)XtpHq2vx>4yzmyR^c!+_s}}D!wQ_J zrf%qR_i1(FG4Gg)4%ljGE%QS^tB3Wh5jH5vZ;vh+d-JUQ0m-j9gwO5xVnPZ2&inTx zl3Nc6^I83fg!8PynlLZ0IW`aTB3}%bcs;zp=fjJ9A$*NhH%M#Y6<{JQs;j$P$bON7 zN<RSM=W)iF8V*vP;E~hAo-Skn3MV0DB(xX}?dPONnZ@iQFLa(0hlCYy;ppn>zS=w( z@X`BIB@lcdxa7H#0pC}Fg3X|x2btU+#K}%OnR!4*s8^=5ybp>ZW2)$(C6^R<J*2-- zuvp3l%e!E)(8BC7b>Oc%RD8;u9V&0<79|QwV$N5TJ0^$Lq&kMX#@4Y7ak^`xg`{9S z$c9n{T?|N#mRPLf6HE6%aVaRo@aks}qop(FKm6&&%}-jM_WQD*OBLq{*EU?DYY2W- zh(hR!xkCH*<8(MP$>D$tfe>{yigLaeMJ-#~Nh-C24zz<oyrjAoMM)Y<8AUJ2U!Sk2 zY_Kxu53U<$X?p$UlaGh{9~Chg%@^(RoE2han%0#l>gRnGMeV_XXo5SWy_^F<s82of zEyFyTpO&dTi^kO+s6dD)(tZ?W1skTQH=^jrVVq8PAb3_JQDpAc&1tX+PgAg6057Fj zMC~F9gpAE49aN}8jb&6bSw+li;nMdTch<l9`fjwob#Hb3(dM^5tU+$vbzlh>x;o5} zFJ0|z8HJ0)f~#f&uSFks;geTEDAEI_yr9p39TPgXC)Su8(_?I93JkDD5B&fJ-X0X) zr#w+Xr|1N6&VoJBS3n8iY7um#5<Jd2zB#?Yd2q|r<yNPRs}uAJ5flRj{UqDw5JW95 zLj<~FF47Lh4Xr^7?UuJ`cV{ma+fuu@1%&t~V<uS`KYk`z#PzAbRf1%k4aAP!V(>12 zV(`)zh!t=GLOOczp9lq4Ly-r@I|~d?{|CU9W$>AxKz|dwi?>jmg`q2WfA<>fNK-0T zyaW0f7zp7624WwR2{|UuECsFFqhkPMp!{l}l$D1X%_`OtMRro6b_wBL+?QMi9U!)d zzX4`-g1sj^KRFg8MXq9KBz%rUT%s>4ce=bYmYq}JmZcpa1rx7Bz)<V}rZNFoh<|6n zEs1*rw#s@|Ju2RVRcl#af%a`rTem%X5n*kfXMsu6SI;}b_Y+=HPS=wng?HQVPhc06 zuZvYkUFG?1Ulh5vx4AmsS1(S}E>x*3DB=-UK!k6c=QT>EA?o^f*`N^0ymN*Irm_Z= zcG4ndx`GlOH8#u!x`I-kN{k^2mRozDl`qT}2v)ugqCq{YVJ|m4+MvspMK94gdfE1T MujVxz>R1l_8`;+SivR!s diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-38.pyc index 6add40bb21b5f1a0ad5b50302b4dd6a4bb984517..57709994141b49f88ada791f9ab9db2d425b6165 100644 GIT binary patch delta 130 zcmdnYc!QBAl$V!_0SGkz?TVksqo2hHWWNLn6fpq_KTXD4>}9D%#hLkeD;bJdK;j_c zSCW24er~FMQDtdqR;GS&QL=tYVqRuyPI7)xNouiPMP-$KS!!OHeokhRenDkPMt+{L Xo`rsKW=X1UL1J=tVtQ)v#0Fyk9lj`Z delta 93 zcmcb?xS5eBl$V!_0SKO#ZHSx5qwfl0zhnauj6lLqlkpaNS!z*nW`5pEh9Xv=5SaL7 jt6!2^pkI(#pqrUjT#}fRqid95Qd(i0p9m71xYQT`RM#4P diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-38.pyc index f06c8a42444b587c1e1d5e7ae042ca037d76b515..707f3f4467ea40d6a54e3ad2b92c8f42a9a81dde 100644 GIT binary patch delta 94 zcmbQrw~LP_l$V!_0SGkz?TX*X^PJH+ML#1yH&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*kVAQKBK0NgzwMF0Q* delta 57 zcmdnRH<gbkl$V!_0SKO#ZHU{*^PEx6UcV%_K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J*^G&W6#(@55zznu diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-38.pyc index dbc4adc6be9fc124514c98dd03c10a563730dc6a..219d73fb153011850bcf35c5135a089bb6433704 100644 GIT binary patch delta 9356 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 IZTubiUkpC4zW@LL delta 9781 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/_version.py b/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/_version.py index 926c5e7..9f55cf5 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/_version.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/_version.py @@ -1 +1 @@ -version = (0, 6, 1) +version = (1, 0, 0) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/fallback.py b/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/fallback.py index 5b731dd..9f6665b 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/fallback.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/msgpack/fallback.py @@ -1,86 +1,98 @@ """Fallback pure Python implementation of msgpack""" +from datetime import datetime as _DateTime import sys import struct -import warnings -if sys.version_info[0] == 2: - PY2 = True +PY2 = sys.version_info[0] == 2 +if PY2: int_types = (int, long) + def dict_iteritems(d): return d.iteritems() + + else: - PY2 = False int_types = int unicode = str xrange = range + def dict_iteritems(d): return d.items() + if sys.version_info < (3, 5): # Ugly hack... RecursionError = RuntimeError def _is_recursionerror(e): - return len(e.args) == 1 and isinstance(e.args[0], str) and \ - e.args[0].startswith('maximum recursion depth exceeded') + return ( + len(e.args) == 1 + and isinstance(e.args[0], str) + and e.args[0].startswith("maximum recursion depth exceeded") + ) + + else: + def _is_recursionerror(e): return True -if hasattr(sys, 'pypy_version_info'): - # cStringIO is slow on PyPy, StringIO is faster. However: PyPy's own + +if hasattr(sys, "pypy_version_info"): + # StringIO is slow on PyPy, StringIO is faster. However: PyPy's own # StringBuilder is fastest. from __pypy__ import newlist_hint + try: from __pypy__.builders import BytesBuilder as StringBuilder except ImportError: from __pypy__.builders import StringBuilder USING_STRINGBUILDER = True + class StringIO(object): - def __init__(self, s=b''): + def __init__(self, s=b""): if s: self.builder = StringBuilder(len(s)) self.builder.append(s) else: self.builder = StringBuilder() + def write(self, s): if isinstance(s, memoryview): s = s.tobytes() elif isinstance(s, bytearray): s = bytes(s) self.builder.append(s) + def getvalue(self): return self.builder.build() + + else: USING_STRINGBUILDER = False from io import BytesIO as StringIO + newlist_hint = lambda size: [] -from pip._vendor.msgpack.exceptions import ( - BufferFull, - OutOfData, - ExtraData, - FormatError, - StackError, -) +from .exceptions import BufferFull, OutOfData, ExtraData, FormatError, StackError -from pip._vendor.msgpack import ExtType +from .ext import ExtType, Timestamp -EX_SKIP = 0 -EX_CONSTRUCT = 1 -EX_READ_ARRAY_HEADER = 2 -EX_READ_MAP_HEADER = 3 +EX_SKIP = 0 +EX_CONSTRUCT = 1 +EX_READ_ARRAY_HEADER = 2 +EX_READ_MAP_HEADER = 3 -TYPE_IMMEDIATE = 0 -TYPE_ARRAY = 1 -TYPE_MAP = 2 -TYPE_RAW = 3 -TYPE_BIN = 4 -TYPE_EXT = 5 +TYPE_IMMEDIATE = 0 +TYPE_ARRAY = 1 +TYPE_MAP = 2 +TYPE_RAW = 3 +TYPE_BIN = 4 +TYPE_EXT = 5 DEFAULT_RECURSE_LIMIT = 511 @@ -93,31 +105,12 @@ def _check_type_strict(obj, t, type=type, tuple=tuple): def _get_data_from_buffer(obj): - try: - view = memoryview(obj) - except TypeError: - # try to use legacy buffer protocol if 2.7, otherwise re-raise - if PY2: - view = memoryview(buffer(obj)) - warnings.warn("using old buffer interface to unpack %s; " - "this leads to unpacking errors if slicing is used and " - "will be removed in a future version" % type(obj), - RuntimeWarning, stacklevel=3) - else: - raise + view = memoryview(obj) if view.itemsize != 1: raise ValueError("cannot unpack from multi-byte object") return view -def unpack(stream, **kwargs): - warnings.warn( - "Direct calling implementation's unpack() is deprecated, Use msgpack.unpack() or unpackb() instead.", - DeprecationWarning, stacklevel=2) - data = stream.read() - return unpackb(data, **kwargs) - - def unpackb(packed, **kwargs): """ Unpack an object from `packed`. @@ -146,9 +139,12 @@ def unpackb(packed, **kwargs): if sys.version_info < (2, 7, 6): + def _unpack_from(f, b, o=0): - """Explicit typcast for legacy struct.unpack_from""" + """Explicit type cast for legacy struct.unpack_from""" return struct.unpack_from(f, bytes(b), o) + + else: _unpack_from = struct.unpack_from @@ -156,7 +152,7 @@ else: class Unpacker(object): """Streaming unpacker. - arguments: + Arguments: :param file_like: File-like object having `.read(n)` method. @@ -170,19 +166,19 @@ class Unpacker(object): Otherwise, unpack to Python tuple. (default: True) :param bool raw: - If true, unpack msgpack raw to Python bytes (default). - Otherwise, unpack to Python str (or unicode on Python 2) by decoding - with UTF-8 encoding (recommended). - Currently, the default is true, but it will be changed to false in - near future. So you must specify it explicitly for keeping backward - compatibility. + If true, unpack msgpack raw to Python bytes. + Otherwise, unpack to Python str by decoding with UTF-8 encoding (default). - *encoding* option which is deprecated overrides this option. + :param int timestamp: + Control how timestamp type is unpacked: + + 0 - Timestamp + 1 - float (Seconds from the EPOCH) + 2 - int (Nanoseconds from the EPOCH) + 3 - datetime.datetime (UTC). Python 2 is not supported. :param bool strict_map_key: - If true, only str or bytes are accepted for map (dict) keys. - It's False by default for backward-compatibility. - But it will be True from msgpack 1.0. + If true (default), only str or bytes are accepted for map (dict) keys. :param callable object_hook: When specified, it should be callable. @@ -194,48 +190,46 @@ class Unpacker(object): Unpacker calls it with a list of key-value pairs after unpacking msgpack map. (See also simplejson) - :param str encoding: - Encoding used for decoding msgpack raw. - If it is None (default), msgpack raw is deserialized to Python bytes. - :param str unicode_errors: - (deprecated) Used for decoding msgpack raw with *encoding*. - (default: `'strict'`) + The error handler for decoding unicode. (default: 'strict') + This option should be used only when you have msgpack data which + contains invalid UTF-8 string. :param int max_buffer_size: - Limits size of data waiting unpacked. 0 means system's INT_MAX (default). + Limits size of data waiting unpacked. 0 means 2**32-1. + The default value is 100*1024*1024 (100MiB). Raises `BufferFull` exception when it is insufficient. You should set this parameter when unpacking data from untrusted source. :param int max_str_len: Deprecated, use *max_buffer_size* instead. - Limits max length of str. (default: max_buffer_size or 1024*1024) + Limits max length of str. (default: max_buffer_size) :param int max_bin_len: Deprecated, use *max_buffer_size* instead. - Limits max length of bin. (default: max_buffer_size or 1024*1024) + Limits max length of bin. (default: max_buffer_size) :param int max_array_len: Limits max length of array. - (default: max_buffer_size or 128*1024) + (default: max_buffer_size) :param int max_map_len: Limits max length of map. - (default: max_buffer_size//2 or 32*1024) + (default: max_buffer_size//2) :param int max_ext_len: Deprecated, use *max_buffer_size* instead. - Limits max size of ext type. (default: max_buffer_size or 1024*1024) + Limits max size of ext type. (default: max_buffer_size) Example of streaming deserialize from file-like object:: - unpacker = Unpacker(file_like, raw=False, max_buffer_size=10*1024*1024) + unpacker = Unpacker(file_like) for o in unpacker: process(o) Example of streaming deserialize from socket:: - unpacker = Unpacker(raw=False, max_buffer_size=10*1024*1024) + unpacker = Unpacker(max_buffer_size) while True: buf = sock.recv(1024**2) if not buf: @@ -251,22 +245,28 @@ class Unpacker(object): Other exceptions can be raised during unpacking. """ - def __init__(self, file_like=None, read_size=0, use_list=True, raw=True, strict_map_key=False, - object_hook=None, object_pairs_hook=None, list_hook=None, - encoding=None, unicode_errors=None, max_buffer_size=0, - ext_hook=ExtType, - max_str_len=-1, - max_bin_len=-1, - max_array_len=-1, - max_map_len=-1, - max_ext_len=-1): - if encoding is not None: - warnings.warn( - "encoding is deprecated, Use raw=False instead.", - DeprecationWarning, stacklevel=2) - + def __init__( + self, + file_like=None, + read_size=0, + use_list=True, + raw=False, + timestamp=0, + strict_map_key=True, + object_hook=None, + object_pairs_hook=None, + list_hook=None, + unicode_errors=None, + max_buffer_size=100 * 1024 * 1024, + ext_hook=ExtType, + max_str_len=-1, + max_bin_len=-1, + max_array_len=-1, + max_map_len=-1, + max_ext_len=-1, + ): if unicode_errors is None: - unicode_errors = 'strict' + unicode_errors = "strict" if file_like is None: self._feeding = True @@ -290,26 +290,30 @@ class Unpacker(object): # state, which _buf_checkpoint records. self._buf_checkpoint = 0 + if not max_buffer_size: + max_buffer_size = 2 ** 31 - 1 if max_str_len == -1: - max_str_len = max_buffer_size or 1024*1024 + max_str_len = max_buffer_size if max_bin_len == -1: - max_bin_len = max_buffer_size or 1024*1024 + max_bin_len = max_buffer_size if max_array_len == -1: - max_array_len = max_buffer_size or 128*1024 + max_array_len = max_buffer_size if max_map_len == -1: - max_map_len = max_buffer_size//2 or 32*1024 + max_map_len = max_buffer_size // 2 if max_ext_len == -1: - max_ext_len = max_buffer_size or 1024*1024 + max_ext_len = max_buffer_size - self._max_buffer_size = max_buffer_size or 2**31-1 + self._max_buffer_size = max_buffer_size if read_size > self._max_buffer_size: raise ValueError("read_size must be smaller than max_buffer_size") - self._read_size = read_size or min(self._max_buffer_size, 16*1024) + self._read_size = read_size or min(self._max_buffer_size, 16 * 1024) self._raw = bool(raw) self._strict_map_key = bool(strict_map_key) - self._encoding = encoding self._unicode_errors = unicode_errors self._use_list = use_list + if not (0 <= timestamp <= 3): + raise ValueError("timestamp must be 0..3") + self._timestamp = timestamp self._list_hook = list_hook self._object_hook = object_hook self._object_pairs_hook = object_pairs_hook @@ -322,26 +326,27 @@ class Unpacker(object): self._stream_offset = 0 if list_hook is not None and not callable(list_hook): - raise TypeError('`list_hook` is not callable') + raise TypeError("`list_hook` is not callable") if object_hook is not None and not callable(object_hook): - raise TypeError('`object_hook` is not callable') + raise TypeError("`object_hook` is not callable") if object_pairs_hook is not None and not callable(object_pairs_hook): - raise TypeError('`object_pairs_hook` is not callable') + raise TypeError("`object_pairs_hook` is not callable") if object_hook is not None and object_pairs_hook is not None: - raise TypeError("object_pairs_hook and object_hook are mutually " - "exclusive") + raise TypeError( + "object_pairs_hook and object_hook are mutually " "exclusive" + ) if not callable(ext_hook): raise TypeError("`ext_hook` is not callable") def feed(self, next_bytes): assert self._feeding view = _get_data_from_buffer(next_bytes) - if (len(self._buffer) - self._buff_i + len(view) > self._max_buffer_size): + if len(self._buffer) - self._buff_i + len(view) > self._max_buffer_size: raise BufferFull # Strip buffer before checkpoint before reading file. if self._buf_checkpoint > 0: - del self._buffer[:self._buf_checkpoint] + del self._buffer[: self._buf_checkpoint] self._buff_i -= self._buf_checkpoint self._buf_checkpoint = 0 @@ -357,17 +362,19 @@ class Unpacker(object): return self._buff_i < len(self._buffer) def _get_extradata(self): - return self._buffer[self._buff_i:] + return self._buffer[self._buff_i :] def read_bytes(self, n): - return self._read(n) + ret = self._read(n) + self._consume() + return ret def _read(self, n): # (int) -> bytearray self._reserve(n) i = self._buff_i - self._buff_i = i+n - return self._buffer[i:i+n] + self._buff_i = i + n + return self._buffer[i : i + n] def _reserve(self, n): remain_bytes = len(self._buffer) - self._buff_i - n @@ -382,7 +389,7 @@ class Unpacker(object): # Strip buffer before checkpoint before reading file. if self._buf_checkpoint > 0: - del self._buffer[:self._buf_checkpoint] + del self._buffer[: self._buf_checkpoint] self._buff_i -= self._buf_checkpoint self._buf_checkpoint = 0 @@ -411,7 +418,7 @@ class Unpacker(object): if b & 0b10000000 == 0: obj = b elif b & 0b11100000 == 0b11100000: - obj = -1 - (b ^ 0xff) + obj = -1 - (b ^ 0xFF) elif b & 0b11100000 == 0b10100000: n = b & 0b00011111 typ = TYPE_RAW @@ -428,13 +435,13 @@ class Unpacker(object): typ = TYPE_MAP if n > self._max_map_len: raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) - elif b == 0xc0: + elif b == 0xC0: obj = None - elif b == 0xc2: + elif b == 0xC2: obj = False - elif b == 0xc3: + elif b == 0xC3: obj = True - elif b == 0xc4: + elif b == 0xC4: typ = TYPE_BIN self._reserve(1) n = self._buffer[self._buff_i] @@ -442,7 +449,7 @@ class Unpacker(object): if n > self._max_bin_len: raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) obj = self._read(n) - elif b == 0xc5: + elif b == 0xC5: typ = TYPE_BIN self._reserve(2) n = _unpack_from(">H", self._buffer, self._buff_i)[0] @@ -450,7 +457,7 @@ class Unpacker(object): if n > self._max_bin_len: raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) obj = self._read(n) - elif b == 0xc6: + elif b == 0xC6: typ = TYPE_BIN self._reserve(4) n = _unpack_from(">I", self._buffer, self._buff_i)[0] @@ -458,106 +465,106 @@ class Unpacker(object): if n > self._max_bin_len: raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) obj = self._read(n) - elif b == 0xc7: # ext 8 + elif b == 0xC7: # ext 8 typ = TYPE_EXT self._reserve(2) - L, n = _unpack_from('Bb', self._buffer, self._buff_i) + L, n = _unpack_from("Bb", self._buffer, self._buff_i) self._buff_i += 2 if L > self._max_ext_len: raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) obj = self._read(L) - elif b == 0xc8: # ext 16 + elif b == 0xC8: # ext 16 typ = TYPE_EXT self._reserve(3) - L, n = _unpack_from('>Hb', self._buffer, self._buff_i) + L, n = _unpack_from(">Hb", self._buffer, self._buff_i) self._buff_i += 3 if L > self._max_ext_len: raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) obj = self._read(L) - elif b == 0xc9: # ext 32 + elif b == 0xC9: # ext 32 typ = TYPE_EXT self._reserve(5) - L, n = _unpack_from('>Ib', self._buffer, self._buff_i) + L, n = _unpack_from(">Ib", self._buffer, self._buff_i) self._buff_i += 5 if L > self._max_ext_len: raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) obj = self._read(L) - elif b == 0xca: + elif b == 0xCA: self._reserve(4) obj = _unpack_from(">f", self._buffer, self._buff_i)[0] self._buff_i += 4 - elif b == 0xcb: + elif b == 0xCB: self._reserve(8) obj = _unpack_from(">d", self._buffer, self._buff_i)[0] self._buff_i += 8 - elif b == 0xcc: + elif b == 0xCC: self._reserve(1) obj = self._buffer[self._buff_i] self._buff_i += 1 - elif b == 0xcd: + elif b == 0xCD: self._reserve(2) obj = _unpack_from(">H", self._buffer, self._buff_i)[0] self._buff_i += 2 - elif b == 0xce: + elif b == 0xCE: self._reserve(4) obj = _unpack_from(">I", self._buffer, self._buff_i)[0] self._buff_i += 4 - elif b == 0xcf: + elif b == 0xCF: self._reserve(8) obj = _unpack_from(">Q", self._buffer, self._buff_i)[0] self._buff_i += 8 - elif b == 0xd0: + elif b == 0xD0: self._reserve(1) obj = _unpack_from("b", self._buffer, self._buff_i)[0] self._buff_i += 1 - elif b == 0xd1: + elif b == 0xD1: self._reserve(2) obj = _unpack_from(">h", self._buffer, self._buff_i)[0] self._buff_i += 2 - elif b == 0xd2: + elif b == 0xD2: self._reserve(4) obj = _unpack_from(">i", self._buffer, self._buff_i)[0] self._buff_i += 4 - elif b == 0xd3: + elif b == 0xD3: self._reserve(8) obj = _unpack_from(">q", self._buffer, self._buff_i)[0] self._buff_i += 8 - elif b == 0xd4: # fixext 1 + elif b == 0xD4: # fixext 1 typ = TYPE_EXT if self._max_ext_len < 1: raise ValueError("%s exceeds max_ext_len(%s)" % (1, self._max_ext_len)) self._reserve(2) n, obj = _unpack_from("b1s", self._buffer, self._buff_i) self._buff_i += 2 - elif b == 0xd5: # fixext 2 + elif b == 0xD5: # fixext 2 typ = TYPE_EXT if self._max_ext_len < 2: raise ValueError("%s exceeds max_ext_len(%s)" % (2, self._max_ext_len)) self._reserve(3) n, obj = _unpack_from("b2s", self._buffer, self._buff_i) self._buff_i += 3 - elif b == 0xd6: # fixext 4 + elif b == 0xD6: # fixext 4 typ = TYPE_EXT if self._max_ext_len < 4: raise ValueError("%s exceeds max_ext_len(%s)" % (4, self._max_ext_len)) self._reserve(5) n, obj = _unpack_from("b4s", self._buffer, self._buff_i) self._buff_i += 5 - elif b == 0xd7: # fixext 8 + elif b == 0xD7: # fixext 8 typ = TYPE_EXT if self._max_ext_len < 8: raise ValueError("%s exceeds max_ext_len(%s)" % (8, self._max_ext_len)) self._reserve(9) n, obj = _unpack_from("b8s", self._buffer, self._buff_i) self._buff_i += 9 - elif b == 0xd8: # fixext 16 + elif b == 0xD8: # fixext 16 typ = TYPE_EXT if self._max_ext_len < 16: raise ValueError("%s exceeds max_ext_len(%s)" % (16, self._max_ext_len)) self._reserve(17) n, obj = _unpack_from("b16s", self._buffer, self._buff_i) self._buff_i += 17 - elif b == 0xd9: + elif b == 0xD9: typ = TYPE_RAW self._reserve(1) n = self._buffer[self._buff_i] @@ -565,46 +572,46 @@ class Unpacker(object): if n > self._max_str_len: raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) obj = self._read(n) - elif b == 0xda: + elif b == 0xDA: typ = TYPE_RAW self._reserve(2) - n, = _unpack_from(">H", self._buffer, self._buff_i) + (n,) = _unpack_from(">H", self._buffer, self._buff_i) self._buff_i += 2 if n > self._max_str_len: raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) obj = self._read(n) - elif b == 0xdb: + elif b == 0xDB: typ = TYPE_RAW self._reserve(4) - n, = _unpack_from(">I", self._buffer, self._buff_i) + (n,) = _unpack_from(">I", self._buffer, self._buff_i) self._buff_i += 4 if n > self._max_str_len: raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) obj = self._read(n) - elif b == 0xdc: + elif b == 0xDC: typ = TYPE_ARRAY self._reserve(2) - n, = _unpack_from(">H", self._buffer, self._buff_i) + (n,) = _unpack_from(">H", self._buffer, self._buff_i) self._buff_i += 2 if n > self._max_array_len: raise ValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) - elif b == 0xdd: + elif b == 0xDD: typ = TYPE_ARRAY self._reserve(4) - n, = _unpack_from(">I", self._buffer, self._buff_i) + (n,) = _unpack_from(">I", self._buffer, self._buff_i) self._buff_i += 4 if n > self._max_array_len: raise ValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) - elif b == 0xde: + elif b == 0xDE: self._reserve(2) - n, = _unpack_from(">H", self._buffer, self._buff_i) + (n,) = _unpack_from(">H", self._buffer, self._buff_i) self._buff_i += 2 if n > self._max_map_len: raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) typ = TYPE_MAP - elif b == 0xdf: + elif b == 0xDF: self._reserve(4) - n, = _unpack_from(">I", self._buffer, self._buff_i) + (n,) = _unpack_from(">I", self._buffer, self._buff_i) self._buff_i += 4 if n > self._max_map_len: raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) @@ -647,15 +654,19 @@ class Unpacker(object): return if self._object_pairs_hook is not None: ret = self._object_pairs_hook( - (self._unpack(EX_CONSTRUCT), - self._unpack(EX_CONSTRUCT)) - for _ in xrange(n)) + (self._unpack(EX_CONSTRUCT), self._unpack(EX_CONSTRUCT)) + for _ in xrange(n) + ) else: ret = {} for _ in xrange(n): key = self._unpack(EX_CONSTRUCT) if self._strict_map_key and type(key) not in (unicode, bytes): - raise ValueError("%s is not allowed for map key" % str(type(key))) + raise ValueError( + "%s is not allowed for map key" % str(type(key)) + ) + if not PY2 and type(key) is str: + key = sys.intern(key) ret[key] = self._unpack(EX_CONSTRUCT) if self._object_hook is not None: ret = self._object_hook(ret) @@ -663,17 +674,26 @@ class Unpacker(object): if execute == EX_SKIP: return if typ == TYPE_RAW: - if self._encoding is not None: - obj = obj.decode(self._encoding, self._unicode_errors) - elif self._raw: + if self._raw: obj = bytes(obj) else: - obj = obj.decode('utf_8') + obj = obj.decode("utf_8", self._unicode_errors) return obj - if typ == TYPE_EXT: - return self._ext_hook(n, bytes(obj)) if typ == TYPE_BIN: return bytes(obj) + if typ == TYPE_EXT: + if n == -1: # timestamp + ts = Timestamp.from_bytes(bytes(obj)) + if self._timestamp == 1: + return ts.to_unix() + elif self._timestamp == 2: + return ts.to_unix_nano() + elif self._timestamp == 3: + return ts.to_datetime() + else: + return ts + else: + return self._ext_hook(n, bytes(obj)) assert typ == TYPE_IMMEDIATE return obj @@ -723,7 +743,7 @@ class Packer(object): """ MessagePack Packer - usage: + Usage: packer = Packer() astream.write(packer.pack(a)) @@ -744,49 +764,58 @@ class Packer(object): :param bool use_bin_type: Use bin type introduced in msgpack spec 2.0 for bytes. - It also enables str8 type for unicode. + It also enables str8 type for unicode. (default: True) :param bool strict_types: If set to true, types will be checked to be exact. Derived classes - from serializeable types will not be serialized and will be + from serializable types will not be serialized and will be treated as unsupported type and forwarded to default. Additionally tuples will not be serialized as lists. This is useful when trying to implement accurate serialization for python types. - :param str encoding: - (deprecated) Convert unicode to bytes with this encoding. (default: 'utf-8') + :param bool datetime: + If set to true, datetime with tzinfo is packed into Timestamp type. + Note that the tzinfo is stripped in the timestamp. + You can get UTC datetime with `timestamp=3` option of the Unpacker. + (Python 2 is not supported). :param str unicode_errors: - Error handler for encoding unicode. (default: 'strict') + The error handler for encoding unicode. (default: 'strict') + DO NOT USE THIS!! This option is kept for very specific usage. """ - def __init__(self, default=None, encoding=None, unicode_errors=None, - use_single_float=False, autoreset=True, use_bin_type=False, - strict_types=False): - if encoding is None: - encoding = 'utf_8' - else: - warnings.warn( - "encoding is deprecated, Use raw=False instead.", - DeprecationWarning, stacklevel=2) - - if unicode_errors is None: - unicode_errors = 'strict' + def __init__( + self, + default=None, + use_single_float=False, + autoreset=True, + use_bin_type=True, + strict_types=False, + datetime=False, + unicode_errors=None, + ): self._strict_types = strict_types self._use_float = use_single_float self._autoreset = autoreset self._use_bin_type = use_bin_type - self._encoding = encoding - self._unicode_errors = unicode_errors self._buffer = StringIO() + if PY2 and datetime: + raise ValueError("datetime is not supported in Python 2") + self._datetime = bool(datetime) + self._unicode_errors = unicode_errors or "strict" if default is not None: if not callable(default): raise TypeError("default must be callable") self._default = default - def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, - check=isinstance, check_type_strict=_check_type_strict): + def _pack( + self, + obj, + nest_limit=DEFAULT_RECURSE_LIMIT, + check=isinstance, + check_type_strict=_check_type_strict, + ): default_used = False if self._strict_types: check = check_type_strict @@ -807,22 +836,22 @@ class Packer(object): return self._buffer.write(struct.pack("B", obj)) if -0x20 <= obj < 0: return self._buffer.write(struct.pack("b", obj)) - if 0x80 <= obj <= 0xff: - return self._buffer.write(struct.pack("BB", 0xcc, obj)) + if 0x80 <= obj <= 0xFF: + return self._buffer.write(struct.pack("BB", 0xCC, obj)) if -0x80 <= obj < 0: - return self._buffer.write(struct.pack(">Bb", 0xd0, obj)) - if 0xff < obj <= 0xffff: - return self._buffer.write(struct.pack(">BH", 0xcd, obj)) + return self._buffer.write(struct.pack(">Bb", 0xD0, obj)) + if 0xFF < obj <= 0xFFFF: + return self._buffer.write(struct.pack(">BH", 0xCD, obj)) if -0x8000 <= obj < -0x80: - return self._buffer.write(struct.pack(">Bh", 0xd1, obj)) - if 0xffff < obj <= 0xffffffff: - return self._buffer.write(struct.pack(">BI", 0xce, obj)) + return self._buffer.write(struct.pack(">Bh", 0xD1, obj)) + if 0xFFFF < obj <= 0xFFFFFFFF: + return self._buffer.write(struct.pack(">BI", 0xCE, obj)) if -0x80000000 <= obj < -0x8000: - return self._buffer.write(struct.pack(">Bi", 0xd2, obj)) - if 0xffffffff < obj <= 0xffffffffffffffff: - return self._buffer.write(struct.pack(">BQ", 0xcf, obj)) + return self._buffer.write(struct.pack(">Bi", 0xD2, obj)) + if 0xFFFFFFFF < obj <= 0xFFFFFFFFFFFFFFFF: + return self._buffer.write(struct.pack(">BQ", 0xCF, obj)) if -0x8000000000000000 <= obj < -0x80000000: - return self._buffer.write(struct.pack(">Bq", 0xd3, obj)) + return self._buffer.write(struct.pack(">Bq", 0xD3, obj)) if not default_used and self._default is not None: obj = self._default(obj) default_used = True @@ -830,53 +859,53 @@ class Packer(object): raise OverflowError("Integer value out of range") if check(obj, (bytes, bytearray)): n = len(obj) - if n >= 2**32: + if n >= 2 ** 32: raise ValueError("%s is too large" % type(obj).__name__) self._pack_bin_header(n) return self._buffer.write(obj) if check(obj, unicode): - if self._encoding is None: - raise TypeError( - "Can't encode unicode string: " - "no encoding is specified") - obj = obj.encode(self._encoding, self._unicode_errors) + obj = obj.encode("utf-8", self._unicode_errors) n = len(obj) - if n >= 2**32: + if n >= 2 ** 32: raise ValueError("String is too large") self._pack_raw_header(n) return self._buffer.write(obj) if check(obj, memoryview): n = len(obj) * obj.itemsize - if n >= 2**32: + if n >= 2 ** 32: raise ValueError("Memoryview is too large") self._pack_bin_header(n) return self._buffer.write(obj) if check(obj, float): if self._use_float: - return self._buffer.write(struct.pack(">Bf", 0xca, obj)) - return self._buffer.write(struct.pack(">Bd", 0xcb, obj)) - if check(obj, ExtType): - code = obj.code - data = obj.data + return self._buffer.write(struct.pack(">Bf", 0xCA, obj)) + return self._buffer.write(struct.pack(">Bd", 0xCB, obj)) + if check(obj, (ExtType, Timestamp)): + if check(obj, Timestamp): + code = -1 + data = obj.to_bytes() + else: + code = obj.code + data = obj.data assert isinstance(code, int) assert isinstance(data, bytes) L = len(data) if L == 1: - self._buffer.write(b'\xd4') + self._buffer.write(b"\xd4") elif L == 2: - self._buffer.write(b'\xd5') + self._buffer.write(b"\xd5") elif L == 4: - self._buffer.write(b'\xd6') + self._buffer.write(b"\xd6") elif L == 8: - self._buffer.write(b'\xd7') + self._buffer.write(b"\xd7") elif L == 16: - self._buffer.write(b'\xd8') - elif L <= 0xff: - self._buffer.write(struct.pack(">BB", 0xc7, L)) - elif L <= 0xffff: - self._buffer.write(struct.pack(">BH", 0xc8, L)) + self._buffer.write(b"\xd8") + elif L <= 0xFF: + self._buffer.write(struct.pack(">BB", 0xC7, L)) + elif L <= 0xFFFF: + self._buffer.write(struct.pack(">BH", 0xC8, L)) else: - self._buffer.write(struct.pack(">BI", 0xc9, L)) + self._buffer.write(struct.pack(">BI", 0xC9, L)) self._buffer.write(struct.pack("b", code)) self._buffer.write(data) return @@ -887,13 +916,20 @@ class Packer(object): self._pack(obj[i], nest_limit - 1) return if check(obj, dict): - return self._pack_map_pairs(len(obj), dict_iteritems(obj), - nest_limit - 1) + return self._pack_map_pairs( + len(obj), dict_iteritems(obj), nest_limit - 1 + ) + + if self._datetime and check(obj, _DateTime): + obj = Timestamp.from_datetime(obj) + default_used = 1 + continue + if not default_used and self._default is not None: obj = self._default(obj) default_used = 1 continue - raise TypeError("Cannot serialize %r" % (obj, )) + raise TypeError("Cannot serialize %r" % (obj,)) def pack(self, obj): try: @@ -914,7 +950,7 @@ class Packer(object): return ret def pack_array_header(self, n): - if n >= 2**32: + if n >= 2 ** 32: raise ValueError self._pack_array_header(n) if self._autoreset: @@ -923,7 +959,7 @@ class Packer(object): return ret def pack_map_header(self, n): - if n >= 2**32: + if n >= 2 ** 32: raise ValueError self._pack_map_header(n) if self._autoreset: @@ -939,43 +975,43 @@ class Packer(object): if not isinstance(data, bytes): raise TypeError("data must have bytes type") L = len(data) - if L > 0xffffffff: + if L > 0xFFFFFFFF: raise ValueError("Too large data") if L == 1: - self._buffer.write(b'\xd4') + self._buffer.write(b"\xd4") elif L == 2: - self._buffer.write(b'\xd5') + self._buffer.write(b"\xd5") elif L == 4: - self._buffer.write(b'\xd6') + self._buffer.write(b"\xd6") elif L == 8: - self._buffer.write(b'\xd7') + self._buffer.write(b"\xd7") elif L == 16: - self._buffer.write(b'\xd8') - elif L <= 0xff: - self._buffer.write(b'\xc7' + struct.pack('B', L)) - elif L <= 0xffff: - self._buffer.write(b'\xc8' + struct.pack('>H', L)) + self._buffer.write(b"\xd8") + elif L <= 0xFF: + self._buffer.write(b"\xc7" + struct.pack("B", L)) + elif L <= 0xFFFF: + self._buffer.write(b"\xc8" + struct.pack(">H", L)) else: - self._buffer.write(b'\xc9' + struct.pack('>I', L)) - self._buffer.write(struct.pack('B', typecode)) + self._buffer.write(b"\xc9" + struct.pack(">I", L)) + self._buffer.write(struct.pack("B", typecode)) self._buffer.write(data) def _pack_array_header(self, n): - if n <= 0x0f: - return self._buffer.write(struct.pack('B', 0x90 + n)) - if n <= 0xffff: - return self._buffer.write(struct.pack(">BH", 0xdc, n)) - if n <= 0xffffffff: - return self._buffer.write(struct.pack(">BI", 0xdd, n)) + if n <= 0x0F: + return self._buffer.write(struct.pack("B", 0x90 + n)) + if n <= 0xFFFF: + return self._buffer.write(struct.pack(">BH", 0xDC, n)) + if n <= 0xFFFFFFFF: + return self._buffer.write(struct.pack(">BI", 0xDD, n)) raise ValueError("Array is too large") def _pack_map_header(self, n): - if n <= 0x0f: - return self._buffer.write(struct.pack('B', 0x80 + n)) - if n <= 0xffff: - return self._buffer.write(struct.pack(">BH", 0xde, n)) - if n <= 0xffffffff: - return self._buffer.write(struct.pack(">BI", 0xdf, n)) + if n <= 0x0F: + return self._buffer.write(struct.pack("B", 0x80 + n)) + if n <= 0xFFFF: + return self._buffer.write(struct.pack(">BH", 0xDE, n)) + if n <= 0xFFFFFFFF: + return self._buffer.write(struct.pack(">BI", 0xDF, n)) raise ValueError("Dict is too large") def _pack_map_pairs(self, n, pairs, nest_limit=DEFAULT_RECURSE_LIMIT): @@ -985,28 +1021,28 @@ class Packer(object): self._pack(v, nest_limit - 1) def _pack_raw_header(self, n): - if n <= 0x1f: - self._buffer.write(struct.pack('B', 0xa0 + n)) - elif self._use_bin_type and n <= 0xff: - self._buffer.write(struct.pack('>BB', 0xd9, n)) - elif n <= 0xffff: - self._buffer.write(struct.pack(">BH", 0xda, n)) - elif n <= 0xffffffff: - self._buffer.write(struct.pack(">BI", 0xdb, n)) + if n <= 0x1F: + self._buffer.write(struct.pack("B", 0xA0 + n)) + elif self._use_bin_type and n <= 0xFF: + self._buffer.write(struct.pack(">BB", 0xD9, n)) + elif n <= 0xFFFF: + self._buffer.write(struct.pack(">BH", 0xDA, n)) + elif n <= 0xFFFFFFFF: + self._buffer.write(struct.pack(">BI", 0xDB, n)) else: - raise ValueError('Raw is too large') + raise ValueError("Raw is too large") def _pack_bin_header(self, n): if not self._use_bin_type: return self._pack_raw_header(n) - elif n <= 0xff: - return self._buffer.write(struct.pack('>BB', 0xc4, n)) - elif n <= 0xffff: - return self._buffer.write(struct.pack(">BH", 0xc5, n)) - elif n <= 0xffffffff: - return self._buffer.write(struct.pack(">BI", 0xc6, n)) + elif n <= 0xFF: + return self._buffer.write(struct.pack(">BB", 0xC4, n)) + elif n <= 0xFFFF: + return self._buffer.write(struct.pack(">BH", 0xC5, n)) + elif n <= 0xFFFFFFFF: + return self._buffer.write(struct.pack(">BI", 0xC6, n)) else: - raise ValueError('Bin is too large') + raise ValueError("Bin is too large") def bytes(self): """Return internal buffer contents as bytes object""" @@ -1015,7 +1051,7 @@ class Packer(object): def reset(self): """Reset internal buffer. - This method is usaful only when autoreset=False. + This method is useful only when autoreset=False. """ self._buffer = StringIO() diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__about__.py b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__about__.py index 7481c9e..4d99857 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__about__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__about__.py @@ -18,10 +18,10 @@ __title__ = "packaging" __summary__ = "Core utilities for Python packages" __uri__ = "https://github.com/pypa/packaging" -__version__ = "19.0" +__version__ = "20.4" __author__ = "Donald Stufft and individual contributors" __email__ = "donald@stufft.io" -__license__ = "BSD or Apache License, Version 2.0" +__license__ = "BSD-2-Clause or Apache-2.0" __copyright__ = "Copyright 2014-2019 %s" % __author__ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-38.pyc index 87225dfeb991e766d17b153a8c33654f9f189728..03e2865ecc9096b1168f677fa09bd74195e91a22 100644 GIT binary patch delta 132 zcmdnSdYP3sl$V!_0SGkz?TUY}kvEEw#mGR<WO6p6orIKAu#2vdu5(UeX>qDTevyJ> zL1J=7s_x{IjOEU$`WgATsrp5grKMS!`o%@b`YDNdnW;I+`9&qE#d;N$Rr+PAd1d-J inMwKul_eSZdB%Dc`o)<gsk%T@vJ=x&izml1MF0TI=`5T8 delta 103 zcmcc2x{Z}Ll$V!_0SKO#ZHRlZkvEEw#n4jEU~)F2or026u!}-|k%D7EVsb{Rf=_00 zYF=@wjzU;!QE_H|p2FmVjOB6;`X#vq`URN<x|w;!C5bsXx<(l$r4`2ci6Ftr)l3lp DSOy_e diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-38.pyc index ceaa799d38d3b4267d368bdfbc9a25f4888c4810..e81da7091c8554283311f8d3a0140034974d8217 100644 GIT binary patch delta 93 zcmbQjvXg};l$V!_0SGkz?TX*Xvyjm_ML#1yH&wr=va~cSQ@^+<SwAH)FEceKIlrhR vwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*l9X+}=~q1hn9 delta 56 zcmdnVGKGaFl$V!_0SKO#ZHU{*vyf5FUcV%_K))cfKsPh5xFj(rN7pFBq_n~~KM^E2 I`2(XT0M=F#P5=M^ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/_compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/_compat.cpython-38.pyc index 28ad4bcbea37edaf1382ede4d9d25851099427fd..9e2cd1f926e2b42f733ed3e89e0ac6b4578875d3 100644 GIT binary patch delta 546 zcmYjOO>fjN5Vaj|;_Nml^h=Zvp>j(R^#LS`gs4zkQ9wdSU4+Ob3bETw8z+&SErbJH zQ17e#B^==w@Eh_!xNty>Lsj9!n|Ypj^TzT|?-vW-1i=u&iT?aZCUh3w#Ghw(ZwuiF zS`3sMyBJAV?+GLZg{N4|lpp(Q7!TDb9zl(sEC{rYgnLTj;F5X3LK*5pE*|0dO6kh0 zHVP*EuP9y;<Pb%}+4%#Gtu^j~@w?ai$?n1a?#t(|o<+2Co|bJ#_wuai2IFa6$c~QN zT7LWf2p<HX`JM4er6kwwbb69=qcbkjGM7bG=|-BZkL@RZCd)Hk<nMXiHj}EnzqQRx z-pG4(nw_S{(#%)M=I9O#GXwyU`3rLRWeqZI9rV&=whCG2E7_!3ks7lBw3jffuiMgM zBUN4LRJTdr(CZ`8(FRu5c4Fk{6$pCSg4O(I(N7OQ<jo{e^2UY7I`kL{fY{nV-+~w| z&mTG)k(a>Gygb$}+;#2+@qlP%!M9+4bpF=a-m$`eR{fKD=>6DZRf%aKpI8rLcUvKh QED(yXIUx=y#f-SlUrrEwf&c&j delta 380 zcmey$ae|#Ml$V!_0SKO#ZHP-`p2#P|7&cK`-X@hLi#3Hok|BjTn<<J7&SL@c*i+ey zTv9pG7^67z*iyMbbP8(<TMI)JcM4N5gC_gLbtapI7%do;*@5Q%vePfgEzmE>EYQu& zD=taQ$<Z~+Fe$At&QAmhPM*Z1#VZ3;SIh)*1!I-w<a3OQlV33z)C&OlMIa-Jc;GC4 zAnO)qZfZ$la!z7#u{4ki*2uwFBm$D+FG<ZU$S+DPs*DFK0PELey2VmbS&&);GEtMc zh!02=@q!4D9waNkrt_6&mSn`|rb<KY0I4Zv0TK-CVk|}CKw6V$@)l;r$^V(nEkRs} n0bqxM39u;~Ho5sJr8%i~Af3e^8%3BnnE4p_SXdZ2nAn&B&pl8J diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-38.pyc index fae23c6512ae7c44724b3f3d7871dadee319a6bf..37f07a62fcb41b9f64a2ff5fff62195c9bacd8cf 100644 GIT binary patch literal 2895 zcmcImOK;Oa5MJAPIBEI-QUtVx9uOjj)*yrg5}+bp>VZgza>-@odbf#7Vw>G{MXKJ? zKa;<}Pw^EAiNC-BF|(;lAF*o?Y_#v$`DSKkKj*{jY@I-9{rp0|RSEfular+clMSfy zB{YmMqfZ7##~7F$b6|BWgS;WkWY!^J7B7vgPMMcSq*H;_5-Y=MS+7=k6;^Flc~4r^ z@1TjatYqHZmSI0uoce<(6e_WqzvoLo43fD>_<^E3ao{PKdwAkxF=4U+Rc=AUNylKM zV={x8hooaMi<O`Ud{%+J%&N?WzQSs(4t<r)um<!tn`Lv**VsH;fWFQyvCGiUuq$9? zGihuFJAUA+;npzXo&i8<!7<hsP$dS48F0dECw6*dOvXl1lDxkoAgDw)Ke|pY9B@Yr z<9OG1r0^W(20rh5;5(P=pNIR-9uM}MzQ656L)8m|2kVa<=_|e#x!y;&%cT?fkwZa> zg~FLE`a##BQi<48u>dvEFtI5WJQ9@JXduRlnEQ*VZRpN=Dsj#)3xu^_4Hzh*i~}+< zM&RGrXphaL)N^GoDWQ6S+JCzzFpm%#B`C$?S<n*+Pa6heSa5tUq+_%FS_6ztQ3HXb z9I74{XE7_3_7$ZIAdw<oIpZwuUyLU%fr^Rt%f};qf7&<1;gmM>aA5x&&Y6%NKuC9u zk@=no3=#yj4oM$K<pv&4YM`L+N(mQ~VFUj}>9rgia6j9IIXJ0EYD0q@Ss|{%dKO{; zUM=S!;{G|rX}7tR8{95j(rOM2?q3Weme3P@YZ(FTg1NWzaL^qzKP@;u<&H|j)-sZX zHt)L1-{Wb@O??+tN(0`d^e(7MleC$hIC_y<pgnHjBMRIBSdr8z9fT~#v`ZS4eu~}x zWJk<^B7rF{FdxMtHrKJafeqf4Si$BNHpd(^8DTbyGBmg@F-o>!mrnomz6V>U3O>^f zsQ;69n`Z-Bn1A<cYiUR)j!t1H9k~1Gf~FsHe`OlnU+|-T%wiTaPfGxORSyfm7UjnL zG}lS-_ypWihL;72G51aB<a=5K3?G&bI|yUJaXvd{@{&&W=Wsr~$1D&3EgkCT^{N1D zF;2|?;^=3*SpcjcGv<EYG+n$c0`@2LC@P?F>VrUHdUpbDIU_>@q|LTiMLpAa44M2M z>dD|S+;6vPNToY5{zZZ>E9RZR#1r`MEvbatyWCTn@+Jo3A#oF%DUgZ%WJ1c%@U%pd LX<7?+Do}p`w4@&Y literal 2750 zcmcIm&2AGh5Vm)d%_dEo^ar&C3fv$<Z3I+8LVzMbATGJITyntLuAO8{vPr#8M62G? z1Fw=B&$Cw!h*#jmjJI3Tb~gzK9C`dRw!iVr_}hF~Tr3bM--lm6e#sK@4F{7Y1A`jW z;0*{)IPH)wZP2dKFuG>Lq~smp1~<<LH$`S-HnJi+B8@D}W_T86vwGGN7R*}Q+9Q?R z4>*Zb%&_Df1ij8c3FdYCJ*h&QdqXeqdVaXnm!7X!bKtuQ#xCxdECvi}P=kFCf;1>6 z4TDo|oRNmfO`d@k@VNzTmgl$)t;O@a0Bw#h@FKJ}U*t>B=6Q*ip)K%bz5?w6Uj-}I zLi@en^n6bpyA(j;f_<#7p$6z2PGPlCm*6}yCSw|A0?}zo3x-<!d{tH5ezouQw>>{l zPN%c|xV=00{G{jLq^@izeBP7QzT<v!TAtskvOvj!s|Hd8JN@I(W=x8{WXwibygi{O z%dvqwvG$s!CM?vJ7NMhvqNij;M_}=o*2hMeX*)qX%;3>72P=MCE%Pu$SX{x_0*sPi zBdx0qf+bk6f6YN-qyAPOJ~kv?A<XtvTga<;7GoX7*b=OW(Ml7SMBQvGS%&S=$;%f# z9S(gb#1M?3DiH&8*D$WQ@f6&6NJqvVk?0t3WC79^gX_B@%)<d4CkP-YDfr@uv9%O@ z)TQI2XB3I?i{#t_c?0It(0sVjdI}oquAwDGZ-1&oTM(F=DG;ce4Iy#+bPO<cD-8p$ zfo8`A`<JevVpmmYSgwnfqr9PrQ!6p|bBy_-#n?SKDo&JgyaQgGR@TQwd?dcp1q;Fg zW8EGfV0wi`#*PL~C(=mdSXn}`iUNZ#H&AS%xP{_2iaRJSs3YoO)@pXa7aFX9u&Hfc z{%O4ns!Ii*Vh!qlWJ!r3neO^?f;`D@$KH$Xl|VS!PY=*y%_#I_^J=L6g6i}el}La| zan@0JI0JHCnwy@*I`%sgQ0ob|o0H?FJ{O%|k7fbko6&BDg;=mZo#;|&M(6S_?2qG? zbhCfUZ2ILqodG!?y-ojM=-2sd2GE=&H}%V;8Q{e%pg&<c%?gQ0k33VGfZ9mN#E9VJ zU09Y#N%->b;~6QGg!+0VhpgBf;6EAoAYzV5OfrdookFX3a41|A*@^3ufI|Cu#HufG OPk?_P*39yj1@#vMP2wE@ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-38.pyc index aab7a275930fcea235f07949702dbb74469b5908..ad440f71c162e85e824f02c11bf2f756b02a70a3 100644 GIT binary patch delta 3940 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 delta 3494 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-38.pyc index 8fc8c45f9c8fe8b45c11ef3b3db7c9ba560a5b84..53bd01ec63c9e8ff78f82ede582227c73a88f006 100644 GIT binary patch delta 1470 zcmZ`%OHUhD6ux)-1Z?wi@Bro!FqjG8;gu%gjfo5CBW=^PRi~;(gYOB9@z~Ctaa4#R zS8`ZYRfJ}fB~e$Ex~LQ>i>xE{Ka9HVFX%3ns-8Qzv_<Mj_tSUI`Of3sGbbb8jwU{f z$J+^h%Ac?GZ0~6zO`o4mKWR|HBCM^PvSdxR`n7)FZZ8j5gW8~#*3#CHHbe>Z@t+xC z9pzzbL>r-Ghp-rnKP4;<qs@SJ6=D!9jo}$jktWqL(9IG}dN%QbXp_i0TRe-rtHq~~ zcQ+g7A_a|}R^S@)-WH!mo^0_Mh_NeJd=@g$0kcgCnH0$rEeD;xC)cEYa}`w9hq^gX zwRuReRFg6p?FE>Dg%r^iVIK3Z!Msp6(6I!Q5Qim^4%rl8{V2W;2}qaTfl%oNo|}2n zl(bvu8@%LOhFh?_MYI(hV#P1JBFbWw9yY)RzYnl9R$ImTQ?QEl6+Ek0jcRMKcDBwM zLu~jdc|q}s+h7eR9l_8BY+z{gUlF;9DeNl7WRNj7b`hJ_HenNFyv7!6V4E$`T+74a z1>c4_<k$V{Z9_g!Fn${%a2rR7;uC5GD4e~^#>Ei0*9@D$y-vUm?sb<*pAu!#{YiS& zMZNg_FF!8m+q;GB_wU@@agD%sM4?{r1JibY2)y}l2!Adv;O&8WP_;niNA-HiRBc{V znNcyJT&!{j?A$j;$Lb@fJW|W%o?1I{4yu*K+)dRs9hj{d#Y1BsZ1-6(+bv_UK0LOB z5T#spe+hoKIE}`S0gu`qEqm1QTb{!(M!e{1*|7GQvA%-V?|2BGcTYlVGyZ(D!oHZ4 ziwr)Gur9~~f)}<7e(0WtdR-dM(q2~yXNLbTEAMB$JPf~*hQzR5_(7FhhT{dw)uI=$ z?0r5dBw2U8O_is7g<<1^Ib7U}FA7+4PuiBo|2vZx)pfICI=Zf-#9l%mlKX4hAB}Nj z$Dz&9$8%5K($VA4ieP*Oy-NFevsRm04JwSUV!#WQs%FIt+v53|-_#4>2t12HE@~?h zF9>0%W^l*8^gdoh*HNwOk5Lk_#XWJBuRH99D9%4ZP^h1OIT0_xp@x~yP~$I=NXN;0 z@UU)ju%P1P{ubO-BD`Nz8xSxkAT8iM0iOuCC*Yq)5^U^zeK(Mbs2xR!(qJr_jwZSA zDtFw6F`H`cZ?W;OHqe1ragJ(cWuJHZmRL1#oA;o_dxfjru0hd!U<z+ic&`W$%ksjl z)ReFL+$h(fz<HH(`Q>i>IlaFul;WrJ!qvSJ6diwtOEdc;<3DOuS-lMFL6qASgrpRu XQAwt08ly2OM!RTI3euRH>-^#`MZa0t delta 1312 zcmZ`%OK%%h6ux)HkBMVD&-$IjiJgbzy3WISHHnirRIq@8Q~}a}I-2I5QX5Zf-I-LV zP#I~;0wIK|*>ssMyF;o}R;*B^O8f$5(<Nffu538>+DfGeMmnFqbIx}jckcZ*|J_Xd z<5(<0@cZ-r&$mAxe;m)zZyuK)_N=6yq=bdpP&;L%^|Y1IGgem5Qt~cg5jOmYuwlr# zsy+o#2(+frW|G9EdLG7D)TQUMPl-N<JT~A3<naM7A|Dy>dE}!5zJPp8@*dF_(HS2k zmLSR|uz3mcFbpM^LOw|vL|=vx8CiCz9A1Vpn?&7JDC-r7vnwuT3G}bQ5?o6Xy$Thq zUx12GqrU=k5Q7!Lp^zjjiP}|&L#EeSgJ5eNt=1r}qHka@eJQpH8?bpq^etRsOSawW zw`HR&#nL~jEQ9T~aX=Baalky<Hg==>4(yy?XIYkeM4nPgU<h__(J9RA!Y*c}S?_Hs z;bIA!!DIpwn9N_4E$Vx)2MIjKKJ4O{eR-xjR4@1eTt&Vr&vyXz20`s1gy9fZ(U2d( z(RqW-iY4$`=U4%+wE)Mis_E}A<rXOwy;sT$?<ck4{h|K0l*M<#1-v<~I###ZZFVco zQ`<4y?aJD{+Sym@9a99ozXFS63Dk|F*$RS2dBU3w{;*y`=b7qL+ox@xI<i|Ia+vY8 zy|!uHVP<^`y}!{2uX?Y8`vp0=Ec}ZlxTxS&gzJK=cn6_lI_|ll;`ILs>r(jqW$1-6 zCHC_}cRSoN9bavCPJGp}zu-k7nfIOyRZ|O6VcPFEZHHeG@l^q9-s_=Se<8U`e{sWT zo;DrB_zWd>4S`T^GxASw7TJT~VgBothi_>9L2y?vzKqdQq(5vhrrU*6#>G+mK&#U{ z^+R@tJHX^nU&R&pJSO>?C{_5e5C*#@ckD~Q#19(=stw~lO2T#u5qJ4z*sjU{^Z~jh zD(f#7YKFm~i<RG_M&271-i~H&CDG@i5l;)q2zXDxhXOtl@b+3RehS~f#7#6?L(pg- zs%5na87<xLevjJJ_YPu(!+p&9Vaw!S0=M}XdR#mlKVo;`q<Oa~q7x!IDL`C=ANj;= zpTP~zJDew;{~CKjZ*Gg^j!1?&cUo}b$U*<L7rrv9!_L}J51`z>hcKyVR8vwkN24^V MjM7Q(*~q8=0`4CvivR!s diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc index 30f1d84a14c9f107830c5f02d15a26b0e0167ef4..23a40625319ba733837c366c6dfabbadc67852ac 100644 GIT binary patch delta 7845 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 DP;fcy delta 6976 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 LiP1Git={-QtpGq3 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-38.pyc index ba6b0904010343633561767e32ff2aec4b4f12b7..3a8e20aec5611f984790dd0070f8a1de09791bf7 100644 GIT binary patch delta 1012 zcmY*XTTc@~6rP#g?ycKW0TVzX@e;HkYyvMD2``9BNE#FH!Wz@8ok{6sx6SOf(x#*_ zkoa8p!PoZDnD7Jq2|oA(_6PXvGY`fyLm@hwbLQ;%zB!kfGf1D?*_WA&g<$3Xd@oMv zgX}y$8Z0{ns?b#3@J-kBE!V<`Y22lVYW1{lySATkGvKqS&ax-OonY!PM~xA7uThg) zr^ub8X==khMadq@X9nHJ{mlNsi|yjp^X;wOox-z3EqP&-CrNfEXnXYveZ_cKX#|Nr zHUQEK?8APi$&%E|KtS0-gZsekGFtF_*45sw6j$FZm$0aRya?<n$QDRA2P#5COmPn_ zjL49T&@qk_N_zN2)TI>8@d~$rl~?05zE$M9ut}l@5I;#lVJ-F*@hR}0d(L6QXAbYQ zTGfgZ@{&Wnpu*~<29H>{derGUZ5FhhdgZ;->_mr+V14zW6ILR&()3C-ugt>O#cO>L zEEFXoC5QQS*#B!l0f%@H*}!iwx^{$m=ma0**C?1#QG{z2zl)LhdPqYDXb-(XWpoT( zRSCs4g+J|)A#^!Zg=d6E7?|LRQbUdQ6{^zIP^TKzPZ1D|ClDM+ilpJHNsXGxKg$p* z@XRsK9P>mlT(u<YOtLJQ$QmcY)wINZNGvU}^c7|=O7NEiZ3)^JAcbT-s8-BN_hWoU zcH?vMWlmg|d;mTTR$^|HS-_5(eA9`)DYZK@0-hD>#uZT>5o~@F)O!3#y|0<#*NDsN z0-lIJsY~~i#3;5eXYSHSH9a1M7wImd#6Q*9H8DrwZBR%j*v4665mmA9q`C-tURakx z_yb_&r{mewd|#YM^kUR$R)R9u;7`sMUlNufl&C7v#su-|JS~*SC&x0;OAWtSsWYAx pE-@@J!9NvVHJcb4euK8^Y*P$ZIEml}rinpvI7d_vi&%=G{{_N#<Z}Q3 delta 723 zcmY*X%Zd|06s@Z6>UT1O4^WAW;~*MCCNR1X46{)LAGjGDVSEv$8covaG}S#}2oaw@ z5NqMKTU_Wy{0{wt-nr53th4goN(fp|r*GeL>fGvkdlpRn>VrzfBe4FAzCS(U(`t?0 znKoMILNj*+FX)~tEMdPVd!BHF3r}CL9a8tEU#{;~Z^xrf)D^p-OuNIlv=_nHdenTj z`J}N=(Ri^iHeug@ovs38B&UK-NWpSe5b$L8XS7*2)Em0KS*N8LcLw2CA}gSswOiRB zX(ipH*^Sez6GhFf7grAsuM9hwRFrL9tD-RjAWW_R{#PCI_?f!;5d`BPBNOtDz9eeE z)?UFqdQ8y1A#Y7+ZU~l}m?>yMDZxy}b4wV)6g;=*9Rc3C2@aq!w2Jgx;q+bkK|7eB zbFp)va~C@FB0cCNsJ>~Hr|Wq47KKR9*W?dP`kM5YT%ft%nhP`+%sBzYCU6mGVrBeR zJv8ppRDCi&p26Pf21@Ks>9(JTad?=>?Tc#1>~9=H`Z&VLrBEM1wLAsTP`}JemW{8L zTH$NdQ!Re^EGzBNV(2{S$Sj=~nV(g!`Dq_r)AIntQlI&{bpfJ!pnme&;~Io=1HnQ- t^U~fQ4w7yZN*7Z&K8Yv(v0dJ)blQWVIEcb+{GC#q>IvqsRl_qJ{uk1Eom&6^ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-38.pyc index 6f94549cc36625d8287106c11f6f6f35ffff03d7..ca9903901d1fa9e1af6d69a96a4bb138fa60851a 100644 GIT binary patch literal 13333 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 Iq;3uVKOQKO<p2Nx literal 12055 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 KA7*r`|NjBOR!b8A diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/_compat.py b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/_compat.py index 25da473..e54bd4e 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/_compat.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/_compat.py @@ -5,6 +5,11 @@ from __future__ import absolute_import, division, print_function import sys +from ._typing import TYPE_CHECKING + +if TYPE_CHECKING: # pragma: no cover + from typing import Any, Dict, Tuple, Type + PY2 = sys.version_info[0] == 2 PY3 = sys.version_info[0] == 3 @@ -18,14 +23,16 @@ else: def with_metaclass(meta, *bases): + # type: (Type[Any], Tuple[Type[Any], ...]) -> Any """ Create a base class with a metaclass. """ # This requires a bit of explanation: the basic idea is to make a dummy # metaclass for one level of class instantiation that replaces itself with # the actual metaclass. - class metaclass(meta): + class metaclass(meta): # type: ignore def __new__(cls, name, this_bases, d): + # type: (Type[Any], str, Tuple[Any], Dict[Any, Any]) -> Any return meta(name, bases, d) return type.__new__(metaclass, "temporary_class", (), {}) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/_structures.py b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/_structures.py index 68dcca6..800d5c5 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/_structures.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/_structures.py @@ -4,65 +4,83 @@ from __future__ import absolute_import, division, print_function -class Infinity(object): +class InfinityType(object): def __repr__(self): + # type: () -> str return "Infinity" def __hash__(self): + # type: () -> int return hash(repr(self)) def __lt__(self, other): + # type: (object) -> bool return False def __le__(self, other): + # type: (object) -> bool return False def __eq__(self, other): + # type: (object) -> bool return isinstance(other, self.__class__) def __ne__(self, other): + # type: (object) -> bool return not isinstance(other, self.__class__) def __gt__(self, other): + # type: (object) -> bool return True def __ge__(self, other): + # type: (object) -> bool return True def __neg__(self): + # type: (object) -> NegativeInfinityType return NegativeInfinity -Infinity = Infinity() +Infinity = InfinityType() -class NegativeInfinity(object): +class NegativeInfinityType(object): def __repr__(self): + # type: () -> str return "-Infinity" def __hash__(self): + # type: () -> int return hash(repr(self)) def __lt__(self, other): + # type: (object) -> bool return True def __le__(self, other): + # type: (object) -> bool return True def __eq__(self, other): + # type: (object) -> bool return isinstance(other, self.__class__) def __ne__(self, other): + # type: (object) -> bool return not isinstance(other, self.__class__) def __gt__(self, other): + # type: (object) -> bool return False def __ge__(self, other): + # type: (object) -> bool return False def __neg__(self): + # type: (object) -> InfinityType return Infinity -NegativeInfinity = NegativeInfinity() +NegativeInfinity = NegativeInfinityType() diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/markers.py b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/markers.py index 5482476..ed642b0 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/markers.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/markers.py @@ -13,8 +13,14 @@ from pip._vendor.pyparsing import ZeroOrMore, Group, Forward, QuotedString from pip._vendor.pyparsing import Literal as L # noqa from ._compat import string_types +from ._typing import TYPE_CHECKING from .specifiers import Specifier, InvalidSpecifier +if TYPE_CHECKING: # pragma: no cover + from typing import Any, Callable, Dict, List, Optional, Tuple, Union + + Operator = Callable[[str, str], bool] + __all__ = [ "InvalidMarker", @@ -46,30 +52,37 @@ class UndefinedEnvironmentName(ValueError): class Node(object): def __init__(self, value): + # type: (Any) -> None self.value = value def __str__(self): + # type: () -> str return str(self.value) def __repr__(self): + # type: () -> str return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) def serialize(self): + # type: () -> str raise NotImplementedError class Variable(Node): def serialize(self): + # type: () -> str return str(self) class Value(Node): def serialize(self): + # type: () -> str return '"{0}"'.format(self) class Op(Node): def serialize(self): + # type: () -> str return str(self) @@ -85,13 +98,13 @@ VARIABLE = ( | L("python_version") | L("sys_platform") | L("os_name") - | L("os.name") + | L("os.name") # PEP-345 | L("sys.platform") # PEP-345 | L("platform.version") # PEP-345 | L("platform.machine") # PEP-345 | L("platform.python_implementation") # PEP-345 - | L("python_implementation") # PEP-345 - | L("extra") # undocumented setuptools legacy + | L("python_implementation") # undocumented setuptools legacy + | L("extra") # PEP-508 ) ALIASES = { "os.name": "os_name", @@ -131,6 +144,7 @@ MARKER = stringStart + MARKER_EXPR + stringEnd def _coerce_parse_result(results): + # type: (Union[ParseResults, List[Any]]) -> List[Any] if isinstance(results, ParseResults): return [_coerce_parse_result(i) for i in results] else: @@ -138,6 +152,8 @@ def _coerce_parse_result(results): def _format_marker(marker, first=True): + # type: (Union[List[str], Tuple[Node, ...], str], Optional[bool]) -> str + assert isinstance(marker, (list, tuple, string_types)) # Sometimes we have a structure like [[...]] which is a single item list @@ -172,10 +188,11 @@ _operators = { "!=": operator.ne, ">=": operator.ge, ">": operator.gt, -} +} # type: Dict[str, Operator] def _eval_op(lhs, op, rhs): + # type: (str, Op, str) -> bool try: spec = Specifier("".join([op.serialize(), rhs])) except InvalidSpecifier: @@ -183,7 +200,7 @@ def _eval_op(lhs, op, rhs): else: return spec.contains(lhs) - oper = _operators.get(op.serialize()) + oper = _operators.get(op.serialize()) # type: Optional[Operator] if oper is None: raise UndefinedComparison( "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) @@ -192,13 +209,18 @@ def _eval_op(lhs, op, rhs): return oper(lhs, rhs) -_undefined = object() +class Undefined(object): + pass + + +_undefined = Undefined() def _get_env(environment, name): - value = environment.get(name, _undefined) + # type: (Dict[str, str], str) -> str + value = environment.get(name, _undefined) # type: Union[str, Undefined] - if value is _undefined: + if isinstance(value, Undefined): raise UndefinedEnvironmentName( "{0!r} does not exist in evaluation environment.".format(name) ) @@ -207,7 +229,8 @@ def _get_env(environment, name): def _evaluate_markers(markers, environment): - groups = [[]] + # type: (List[Any], Dict[str, str]) -> bool + groups = [[]] # type: List[List[bool]] for marker in markers: assert isinstance(marker, (list, tuple, string_types)) @@ -234,6 +257,7 @@ def _evaluate_markers(markers, environment): def format_full_version(info): + # type: (sys._version_info) -> str version = "{0.major}.{0.minor}.{0.micro}".format(info) kind = info.releaselevel if kind != "final": @@ -242,9 +266,13 @@ def format_full_version(info): def default_environment(): + # type: () -> Dict[str, str] if hasattr(sys, "implementation"): - iver = format_full_version(sys.implementation.version) - implementation_name = sys.implementation.name + # Ignoring the `sys.implementation` reference for type checking due to + # mypy not liking that the attribute doesn't exist in Python 2.7 when + # run with the `--py27` flag. + iver = format_full_version(sys.implementation.version) # type: ignore + implementation_name = sys.implementation.name # type: ignore else: iver = "0" implementation_name = "" @@ -259,13 +287,14 @@ def default_environment(): "platform_version": platform.version(), "python_full_version": platform.python_version(), "platform_python_implementation": platform.python_implementation(), - "python_version": platform.python_version()[:3], + "python_version": ".".join(platform.python_version_tuple()[:2]), "sys_platform": sys.platform, } class Marker(object): def __init__(self, marker): + # type: (str) -> None try: self._markers = _coerce_parse_result(MARKER.parseString(marker)) except ParseException as e: @@ -275,12 +304,15 @@ class Marker(object): raise InvalidMarker(err_str) def __str__(self): + # type: () -> str return _format_marker(self._markers) def __repr__(self): + # type: () -> str return "<Marker({0!r})>".format(str(self)) def evaluate(self, environment=None): + # type: (Optional[Dict[str, str]]) -> bool """Evaluate a marker. Return the boolean from evaluating the given marker against the diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/requirements.py b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/requirements.py index dbc5f11..5e64101 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/requirements.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/requirements.py @@ -11,9 +11,13 @@ from pip._vendor.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine from pip._vendor.pyparsing import Literal as L # noqa from pip._vendor.six.moves.urllib import parse as urlparse +from ._typing import TYPE_CHECKING from .markers import MARKER_EXPR, Marker from .specifiers import LegacySpecifier, Specifier, SpecifierSet +if TYPE_CHECKING: # pragma: no cover + from typing import List + class InvalidRequirement(ValueError): """ @@ -89,6 +93,7 @@ class Requirement(object): # TODO: Can we normalize the name and extra name? def __init__(self, requirement_string): + # type: (str) -> None try: req = REQUIREMENT.parseString(requirement_string) except ParseException as e: @@ -116,7 +121,8 @@ class Requirement(object): self.marker = req.marker if req.marker else None def __str__(self): - parts = [self.name] + # type: () -> str + parts = [self.name] # type: List[str] if self.extras: parts.append("[{0}]".format(",".join(sorted(self.extras)))) @@ -135,4 +141,5 @@ class Requirement(object): return "".join(parts) def __repr__(self): + # type: () -> str return "<Requirement({0!r})>".format(str(self)) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/specifiers.py b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/specifiers.py index 743576a..fe09bb1 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/specifiers.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/specifiers.py @@ -9,8 +9,27 @@ import itertools import re from ._compat import string_types, with_metaclass +from ._typing import TYPE_CHECKING +from .utils import canonicalize_version from .version import Version, LegacyVersion, parse +if TYPE_CHECKING: # pragma: no cover + from typing import ( + List, + Dict, + Union, + Iterable, + Iterator, + Optional, + Callable, + Tuple, + FrozenSet, + ) + + ParsedVersion = Union[Version, LegacyVersion] + UnparsedVersion = Union[Version, LegacyVersion, str] + CallableOperator = Callable[[ParsedVersion, str], bool] + class InvalidSpecifier(ValueError): """ @@ -18,9 +37,10 @@ class InvalidSpecifier(ValueError): """ -class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): +class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): # type: ignore @abc.abstractmethod def __str__(self): + # type: () -> str """ Returns the str representation of this Specifier like object. This should be representative of the Specifier itself. @@ -28,12 +48,14 @@ class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): @abc.abstractmethod def __hash__(self): + # type: () -> int """ Returns a hash value for this Specifier like object. """ @abc.abstractmethod def __eq__(self, other): + # type: (object) -> bool """ Returns a boolean representing whether or not the two Specifier like objects are equal. @@ -41,6 +63,7 @@ class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): @abc.abstractmethod def __ne__(self, other): + # type: (object) -> bool """ Returns a boolean representing whether or not the two Specifier like objects are not equal. @@ -48,6 +71,7 @@ class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): @abc.abstractproperty def prereleases(self): + # type: () -> Optional[bool] """ Returns whether or not pre-releases as a whole are allowed by this specifier. @@ -55,6 +79,7 @@ class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): @prereleases.setter def prereleases(self, value): + # type: (bool) -> None """ Sets whether or not pre-releases as a whole are allowed by this specifier. @@ -62,12 +87,14 @@ class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): @abc.abstractmethod def contains(self, item, prereleases=None): + # type: (str, Optional[bool]) -> bool """ Determines if the given item is contained within this specifier. """ @abc.abstractmethod def filter(self, iterable, prereleases=None): + # type: (Iterable[UnparsedVersion], Optional[bool]) -> Iterable[UnparsedVersion] """ Takes an iterable of items and filters them so that only items which are contained within this specifier are allowed in it. @@ -76,19 +103,24 @@ class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): class _IndividualSpecifier(BaseSpecifier): - _operators = {} + _operators = {} # type: Dict[str, str] def __init__(self, spec="", prereleases=None): + # type: (str, Optional[bool]) -> None match = self._regex.search(spec) if not match: raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec)) - self._spec = (match.group("operator").strip(), match.group("version").strip()) + self._spec = ( + match.group("operator").strip(), + match.group("version").strip(), + ) # type: Tuple[str, str] # Store whether or not this Specifier should accept prereleases self._prereleases = prereleases def __repr__(self): + # type: () -> str pre = ( ", prereleases={0!r}".format(self.prereleases) if self._prereleases is not None @@ -98,26 +130,35 @@ class _IndividualSpecifier(BaseSpecifier): return "<{0}({1!r}{2})>".format(self.__class__.__name__, str(self), pre) def __str__(self): + # type: () -> str return "{0}{1}".format(*self._spec) + @property + def _canonical_spec(self): + # type: () -> Tuple[str, Union[Version, str]] + return self._spec[0], canonicalize_version(self._spec[1]) + def __hash__(self): - return hash(self._spec) + # type: () -> int + return hash(self._canonical_spec) def __eq__(self, other): + # type: (object) -> bool if isinstance(other, string_types): try: - other = self.__class__(other) + other = self.__class__(str(other)) except InvalidSpecifier: return NotImplemented elif not isinstance(other, self.__class__): return NotImplemented - return self._spec == other._spec + return self._canonical_spec == other._canonical_spec def __ne__(self, other): + # type: (object) -> bool if isinstance(other, string_types): try: - other = self.__class__(other) + other = self.__class__(str(other)) except InvalidSpecifier: return NotImplemented elif not isinstance(other, self.__class__): @@ -126,52 +167,67 @@ class _IndividualSpecifier(BaseSpecifier): return self._spec != other._spec def _get_operator(self, op): - return getattr(self, "_compare_{0}".format(self._operators[op])) + # type: (str) -> CallableOperator + operator_callable = getattr( + self, "_compare_{0}".format(self._operators[op]) + ) # type: CallableOperator + return operator_callable def _coerce_version(self, version): + # type: (UnparsedVersion) -> ParsedVersion if not isinstance(version, (LegacyVersion, Version)): version = parse(version) return version @property def operator(self): + # type: () -> str return self._spec[0] @property def version(self): + # type: () -> str return self._spec[1] @property def prereleases(self): + # type: () -> Optional[bool] return self._prereleases @prereleases.setter def prereleases(self, value): + # type: (bool) -> None self._prereleases = value def __contains__(self, item): + # type: (str) -> bool return self.contains(item) def contains(self, item, prereleases=None): + # type: (UnparsedVersion, Optional[bool]) -> bool + # Determine if prereleases are to be allowed or not. if prereleases is None: prereleases = self.prereleases # Normalize item to a Version or LegacyVersion, this allows us to have # a shortcut for ``"2.0" in Specifier(">=2") - item = self._coerce_version(item) + normalized_item = self._coerce_version(item) # Determine if we should be supporting prereleases in this specifier # or not, if we do not support prereleases than we can short circuit # logic if this version is a prereleases. - if item.is_prerelease and not prereleases: + if normalized_item.is_prerelease and not prereleases: return False # Actually do the comparison to determine if this item is contained # within this Specifier or not. - return self._get_operator(self.operator)(item, self.version) + operator_callable = self._get_operator(self.operator) # type: CallableOperator + return operator_callable(normalized_item, self.version) def filter(self, iterable, prereleases=None): + # type: (Iterable[UnparsedVersion], Optional[bool]) -> Iterable[UnparsedVersion] + yielded = False found_prereleases = [] @@ -230,32 +286,43 @@ class LegacySpecifier(_IndividualSpecifier): } def _coerce_version(self, version): + # type: (Union[ParsedVersion, str]) -> LegacyVersion if not isinstance(version, LegacyVersion): version = LegacyVersion(str(version)) return version def _compare_equal(self, prospective, spec): + # type: (LegacyVersion, str) -> bool return prospective == self._coerce_version(spec) def _compare_not_equal(self, prospective, spec): + # type: (LegacyVersion, str) -> bool return prospective != self._coerce_version(spec) def _compare_less_than_equal(self, prospective, spec): + # type: (LegacyVersion, str) -> bool return prospective <= self._coerce_version(spec) def _compare_greater_than_equal(self, prospective, spec): + # type: (LegacyVersion, str) -> bool return prospective >= self._coerce_version(spec) def _compare_less_than(self, prospective, spec): + # type: (LegacyVersion, str) -> bool return prospective < self._coerce_version(spec) def _compare_greater_than(self, prospective, spec): + # type: (LegacyVersion, str) -> bool return prospective > self._coerce_version(spec) -def _require_version_compare(fn): +def _require_version_compare( + fn # type: (Callable[[Specifier, ParsedVersion, str], bool]) +): + # type: (...) -> Callable[[Specifier, ParsedVersion, str], bool] @functools.wraps(fn) def wrapped(self, prospective, spec): + # type: (Specifier, ParsedVersion, str) -> bool if not isinstance(prospective, Version): return False return fn(self, prospective, spec) @@ -373,6 +440,8 @@ class Specifier(_IndividualSpecifier): @_require_version_compare def _compare_compatible(self, prospective, spec): + # type: (ParsedVersion, str) -> bool + # Compatible releases have an equivalent combination of >= and ==. That # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to # implement this in terms of the other specifiers instead of @@ -400,56 +469,75 @@ class Specifier(_IndividualSpecifier): @_require_version_compare def _compare_equal(self, prospective, spec): + # type: (ParsedVersion, str) -> bool + # We need special logic to handle prefix matching if spec.endswith(".*"): # In the case of prefix matching we want to ignore local segment. prospective = Version(prospective.public) # Split the spec out by dots, and pretend that there is an implicit # dot in between a release segment and a pre-release segment. - spec = _version_split(spec[:-2]) # Remove the trailing .* + split_spec = _version_split(spec[:-2]) # Remove the trailing .* # Split the prospective version out by dots, and pretend that there # is an implicit dot in between a release segment and a pre-release # segment. - prospective = _version_split(str(prospective)) + split_prospective = _version_split(str(prospective)) # Shorten the prospective version to be the same length as the spec # so that we can determine if the specifier is a prefix of the # prospective version or not. - prospective = prospective[: len(spec)] + shortened_prospective = split_prospective[: len(split_spec)] # Pad out our two sides with zeros so that they both equal the same # length. - spec, prospective = _pad_version(spec, prospective) + padded_spec, padded_prospective = _pad_version( + split_spec, shortened_prospective + ) + + return padded_prospective == padded_spec else: # Convert our spec string into a Version - spec = Version(spec) + spec_version = Version(spec) # If the specifier does not have a local segment, then we want to # act as if the prospective version also does not have a local # segment. - if not spec.local: + if not spec_version.local: prospective = Version(prospective.public) - return prospective == spec + return prospective == spec_version @_require_version_compare def _compare_not_equal(self, prospective, spec): + # type: (ParsedVersion, str) -> bool return not self._compare_equal(prospective, spec) @_require_version_compare def _compare_less_than_equal(self, prospective, spec): - return prospective <= Version(spec) + # type: (ParsedVersion, str) -> bool + + # NB: Local version identifiers are NOT permitted in the version + # specifier, so local version labels can be universally removed from + # the prospective version. + return Version(prospective.public) <= Version(spec) @_require_version_compare def _compare_greater_than_equal(self, prospective, spec): - return prospective >= Version(spec) + # type: (ParsedVersion, str) -> bool + + # NB: Local version identifiers are NOT permitted in the version + # specifier, so local version labels can be universally removed from + # the prospective version. + return Version(prospective.public) >= Version(spec) @_require_version_compare - def _compare_less_than(self, prospective, spec): + def _compare_less_than(self, prospective, spec_str): + # type: (ParsedVersion, str) -> bool + # Convert our spec to a Version instance, since we'll want to work with # it as a version. - spec = Version(spec) + spec = Version(spec_str) # Check to see if the prospective version is less than the spec # version. If it's not we can short circuit and just return False now @@ -471,10 +559,12 @@ class Specifier(_IndividualSpecifier): return True @_require_version_compare - def _compare_greater_than(self, prospective, spec): + def _compare_greater_than(self, prospective, spec_str): + # type: (ParsedVersion, str) -> bool + # Convert our spec to a Version instance, since we'll want to work with # it as a version. - spec = Version(spec) + spec = Version(spec_str) # Check to see if the prospective version is greater than the spec # version. If it's not we can short circuit and just return False now @@ -502,10 +592,13 @@ class Specifier(_IndividualSpecifier): return True def _compare_arbitrary(self, prospective, spec): + # type: (Version, str) -> bool return str(prospective).lower() == str(spec).lower() @property def prereleases(self): + # type: () -> bool + # If there is an explicit prereleases set for this, then we'll just # blindly use that. if self._prereleases is not None: @@ -530,6 +623,7 @@ class Specifier(_IndividualSpecifier): @prereleases.setter def prereleases(self, value): + # type: (bool) -> None self._prereleases = value @@ -537,7 +631,8 @@ _prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") def _version_split(version): - result = [] + # type: (str) -> List[str] + result = [] # type: List[str] for item in version.split("."): match = _prefix_regex.search(item) if match: @@ -548,6 +643,7 @@ def _version_split(version): def _pad_version(left, right): + # type: (List[str], List[str]) -> Tuple[List[str], List[str]] left_split, right_split = [], [] # Get the release segment of our versions @@ -567,14 +663,16 @@ def _pad_version(left, right): class SpecifierSet(BaseSpecifier): def __init__(self, specifiers="", prereleases=None): - # Split on , to break each indidivual specifier into it's own item, and + # type: (str, Optional[bool]) -> None + + # Split on , to break each individual specifier into it's own item, and # strip each item to remove leading/trailing whitespace. - specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] + split_specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] # Parsed each individual specifier, attempting first to make it a # Specifier and falling back to a LegacySpecifier. parsed = set() - for specifier in specifiers: + for specifier in split_specifiers: try: parsed.add(Specifier(specifier)) except InvalidSpecifier: @@ -588,6 +686,7 @@ class SpecifierSet(BaseSpecifier): self._prereleases = prereleases def __repr__(self): + # type: () -> str pre = ( ", prereleases={0!r}".format(self.prereleases) if self._prereleases is not None @@ -597,12 +696,15 @@ class SpecifierSet(BaseSpecifier): return "<SpecifierSet({0!r}{1})>".format(str(self), pre) def __str__(self): + # type: () -> str return ",".join(sorted(str(s) for s in self._specs)) def __hash__(self): + # type: () -> int return hash(self._specs) def __and__(self, other): + # type: (Union[SpecifierSet, str]) -> SpecifierSet if isinstance(other, string_types): other = SpecifierSet(other) elif not isinstance(other, SpecifierSet): @@ -626,9 +728,8 @@ class SpecifierSet(BaseSpecifier): return specifier def __eq__(self, other): - if isinstance(other, string_types): - other = SpecifierSet(other) - elif isinstance(other, _IndividualSpecifier): + # type: (object) -> bool + if isinstance(other, (string_types, _IndividualSpecifier)): other = SpecifierSet(str(other)) elif not isinstance(other, SpecifierSet): return NotImplemented @@ -636,9 +737,8 @@ class SpecifierSet(BaseSpecifier): return self._specs == other._specs def __ne__(self, other): - if isinstance(other, string_types): - other = SpecifierSet(other) - elif isinstance(other, _IndividualSpecifier): + # type: (object) -> bool + if isinstance(other, (string_types, _IndividualSpecifier)): other = SpecifierSet(str(other)) elif not isinstance(other, SpecifierSet): return NotImplemented @@ -646,13 +746,17 @@ class SpecifierSet(BaseSpecifier): return self._specs != other._specs def __len__(self): + # type: () -> int return len(self._specs) def __iter__(self): + # type: () -> Iterator[FrozenSet[_IndividualSpecifier]] return iter(self._specs) @property def prereleases(self): + # type: () -> Optional[bool] + # If we have been given an explicit prerelease modifier, then we'll # pass that through here. if self._prereleases is not None: @@ -670,12 +774,16 @@ class SpecifierSet(BaseSpecifier): @prereleases.setter def prereleases(self, value): + # type: (bool) -> None self._prereleases = value def __contains__(self, item): + # type: (Union[ParsedVersion, str]) -> bool return self.contains(item) def contains(self, item, prereleases=None): + # type: (Union[ParsedVersion, str], Optional[bool]) -> bool + # Ensure that our item is a Version or LegacyVersion instance. if not isinstance(item, (LegacyVersion, Version)): item = parse(item) @@ -701,7 +809,13 @@ class SpecifierSet(BaseSpecifier): # will always return True, this is an explicit design decision. return all(s.contains(item, prereleases=prereleases) for s in self._specs) - def filter(self, iterable, prereleases=None): + def filter( + self, + iterable, # type: Iterable[Union[ParsedVersion, str]] + prereleases=None, # type: Optional[bool] + ): + # type: (...) -> Iterable[Union[ParsedVersion, str]] + # Determine if we're forcing a prerelease or not, if we're not forcing # one for this particular filter call, then we'll use whatever the # SpecifierSet thinks for whether or not we should support prereleases. @@ -719,8 +833,8 @@ class SpecifierSet(BaseSpecifier): # which will filter out any pre-releases, unless there are no final # releases, and which will filter out LegacyVersion in general. else: - filtered = [] - found_prereleases = [] + filtered = [] # type: List[Union[ParsedVersion, str]] + found_prereleases = [] # type: List[Union[ParsedVersion, str]] for item in iterable: # Ensure that we some kind of Version class for this item. diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/utils.py b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/utils.py index 8841878..19579c1 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/utils.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/utils.py @@ -5,28 +5,36 @@ from __future__ import absolute_import, division, print_function import re +from ._typing import TYPE_CHECKING, cast from .version import InvalidVersion, Version +if TYPE_CHECKING: # pragma: no cover + from typing import NewType, Union + + NormalizedName = NewType("NormalizedName", str) _canonicalize_regex = re.compile(r"[-_.]+") def canonicalize_name(name): + # type: (str) -> NormalizedName # This is taken from PEP 503. - return _canonicalize_regex.sub("-", name).lower() + value = _canonicalize_regex.sub("-", name).lower() + return cast("NormalizedName", value) -def canonicalize_version(version): +def canonicalize_version(_version): + # type: (str) -> Union[Version, str] """ - This is very similar to Version.__str__, but has one subtle differences + This is very similar to Version.__str__, but has one subtle difference with the way it handles the release segment. """ try: - version = Version(version) + version = Version(_version) except InvalidVersion: # Legacy versions cannot be normalized - return version + return _version parts = [] diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/version.py b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/version.py index 95157a1..00371e8 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/packaging/version.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/packaging/version.py @@ -7,8 +7,35 @@ import collections import itertools import re -from ._structures import Infinity +from ._structures import Infinity, NegativeInfinity +from ._typing import TYPE_CHECKING +if TYPE_CHECKING: # pragma: no cover + from typing import Callable, Iterator, List, Optional, SupportsInt, Tuple, Union + + from ._structures import InfinityType, NegativeInfinityType + + InfiniteTypes = Union[InfinityType, NegativeInfinityType] + PrePostDevType = Union[InfiniteTypes, Tuple[str, int]] + SubLocalType = Union[InfiniteTypes, int, str] + LocalType = Union[ + NegativeInfinityType, + Tuple[ + Union[ + SubLocalType, + Tuple[SubLocalType, str], + Tuple[NegativeInfinityType, SubLocalType], + ], + ..., + ], + ] + CmpKey = Tuple[ + int, Tuple[int, ...], PrePostDevType, PrePostDevType, PrePostDevType, LocalType + ] + LegacyCmpKey = Tuple[int, Tuple[str, ...]] + VersionComparisonMethod = Callable[ + [Union[CmpKey, LegacyCmpKey], Union[CmpKey, LegacyCmpKey]], bool + ] __all__ = ["parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"] @@ -19,6 +46,7 @@ _Version = collections.namedtuple( def parse(version): + # type: (str) -> Union[LegacyVersion, Version] """ Parse the given version string and return either a :class:`Version` object or a :class:`LegacyVersion` object depending on if the given version is @@ -37,28 +65,38 @@ class InvalidVersion(ValueError): class _BaseVersion(object): + _key = None # type: Union[CmpKey, LegacyCmpKey] + def __hash__(self): + # type: () -> int return hash(self._key) def __lt__(self, other): + # type: (_BaseVersion) -> bool return self._compare(other, lambda s, o: s < o) def __le__(self, other): + # type: (_BaseVersion) -> bool return self._compare(other, lambda s, o: s <= o) def __eq__(self, other): + # type: (object) -> bool return self._compare(other, lambda s, o: s == o) def __ge__(self, other): + # type: (_BaseVersion) -> bool return self._compare(other, lambda s, o: s >= o) def __gt__(self, other): + # type: (_BaseVersion) -> bool return self._compare(other, lambda s, o: s > o) def __ne__(self, other): + # type: (object) -> bool return self._compare(other, lambda s, o: s != o) def _compare(self, other, method): + # type: (object, VersionComparisonMethod) -> Union[bool, NotImplemented] if not isinstance(other, _BaseVersion): return NotImplemented @@ -67,57 +105,71 @@ class _BaseVersion(object): class LegacyVersion(_BaseVersion): def __init__(self, version): + # type: (str) -> None self._version = str(version) self._key = _legacy_cmpkey(self._version) def __str__(self): + # type: () -> str return self._version def __repr__(self): + # type: () -> str return "<LegacyVersion({0})>".format(repr(str(self))) @property def public(self): + # type: () -> str return self._version @property def base_version(self): + # type: () -> str return self._version @property def epoch(self): + # type: () -> int return -1 @property def release(self): + # type: () -> None return None @property def pre(self): + # type: () -> None return None @property def post(self): + # type: () -> None return None @property def dev(self): + # type: () -> None return None @property def local(self): + # type: () -> None return None @property def is_prerelease(self): + # type: () -> bool return False @property def is_postrelease(self): + # type: () -> bool return False @property def is_devrelease(self): + # type: () -> bool return False @@ -133,6 +185,7 @@ _legacy_version_replacement_map = { def _parse_version_parts(s): + # type: (str) -> Iterator[str] for part in _legacy_version_component_re.split(s): part = _legacy_version_replacement_map.get(part, part) @@ -150,6 +203,8 @@ def _parse_version_parts(s): def _legacy_cmpkey(version): + # type: (str) -> LegacyCmpKey + # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch # greater than or equal to 0. This will effectively put the LegacyVersion, # which uses the defacto standard originally implemented by setuptools, @@ -158,7 +213,7 @@ def _legacy_cmpkey(version): # This scheme is taken from pkg_resources.parse_version setuptools prior to # it's adoption of the packaging library. - parts = [] + parts = [] # type: List[str] for part in _parse_version_parts(version.lower()): if part.startswith("*"): # remove "-" before a prerelease tag @@ -171,9 +226,8 @@ def _legacy_cmpkey(version): parts.pop() parts.append(part) - parts = tuple(parts) - return epoch, parts + return epoch, tuple(parts) # Deliberately not anchored to the start and end of the string, to make it @@ -215,6 +269,8 @@ class Version(_BaseVersion): _regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE) def __init__(self, version): + # type: (str) -> None + # Validate the version and parse it into pieces match = self._regex.search(version) if not match: @@ -243,9 +299,11 @@ class Version(_BaseVersion): ) def __repr__(self): + # type: () -> str return "<Version({0})>".format(repr(str(self))) def __str__(self): + # type: () -> str parts = [] # Epoch @@ -275,26 +333,35 @@ class Version(_BaseVersion): @property def epoch(self): - return self._version.epoch + # type: () -> int + _epoch = self._version.epoch # type: int + return _epoch @property def release(self): - return self._version.release + # type: () -> Tuple[int, ...] + _release = self._version.release # type: Tuple[int, ...] + return _release @property def pre(self): - return self._version.pre + # type: () -> Optional[Tuple[str, int]] + _pre = self._version.pre # type: Optional[Tuple[str, int]] + return _pre @property def post(self): + # type: () -> Optional[Tuple[str, int]] return self._version.post[1] if self._version.post else None @property def dev(self): + # type: () -> Optional[Tuple[str, int]] return self._version.dev[1] if self._version.dev else None @property def local(self): + # type: () -> Optional[str] if self._version.local: return ".".join(str(x) for x in self._version.local) else: @@ -302,10 +369,12 @@ class Version(_BaseVersion): @property def public(self): + # type: () -> str return str(self).split("+", 1)[0] @property def base_version(self): + # type: () -> str parts = [] # Epoch @@ -319,18 +388,41 @@ class Version(_BaseVersion): @property def is_prerelease(self): + # type: () -> bool return self.dev is not None or self.pre is not None @property def is_postrelease(self): + # type: () -> bool return self.post is not None @property def is_devrelease(self): + # type: () -> bool return self.dev is not None + @property + def major(self): + # type: () -> int + return self.release[0] if len(self.release) >= 1 else 0 + + @property + def minor(self): + # type: () -> int + return self.release[1] if len(self.release) >= 2 else 0 + + @property + def micro(self): + # type: () -> int + return self.release[2] if len(self.release) >= 3 else 0 + + +def _parse_letter_version( + letter, # type: str + number, # type: Union[str, bytes, SupportsInt] +): + # type: (...) -> Optional[Tuple[str, int]] -def _parse_letter_version(letter, number): if letter: # We consider there to be an implicit 0 in a pre-release if there is # not a numeral associated with it. @@ -360,11 +452,14 @@ def _parse_letter_version(letter, number): return letter, int(number) + return None + _local_version_separators = re.compile(r"[\._-]") def _parse_local_version(local): + # type: (str) -> Optional[LocalType] """ Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). """ @@ -373,15 +468,25 @@ def _parse_local_version(local): part.lower() if not part.isdigit() else int(part) for part in _local_version_separators.split(local) ) + return None -def _cmpkey(epoch, release, pre, post, dev, local): +def _cmpkey( + epoch, # type: int + release, # type: Tuple[int, ...] + pre, # type: Optional[Tuple[str, int]] + post, # type: Optional[Tuple[str, int]] + dev, # type: Optional[Tuple[str, int]] + local, # type: Optional[Tuple[SubLocalType]] +): + # type: (...) -> CmpKey + # When we compare a release version, we want to compare it with all of the # trailing zeros removed. So we'll use a reverse the list, drop all the now # leading zeros until we come to something non zero, then take the rest # re-reverse it back into the correct order and make it a tuple and use # that for our sorting key. - release = tuple( + _release = tuple( reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release)))) ) @@ -390,23 +495,31 @@ def _cmpkey(epoch, release, pre, post, dev, local): # if there is not a pre or a post segment. If we have one of those then # the normal sorting rules will handle this case correctly. if pre is None and post is None and dev is not None: - pre = -Infinity + _pre = NegativeInfinity # type: PrePostDevType # Versions without a pre-release (except as noted above) should sort after # those with one. elif pre is None: - pre = Infinity + _pre = Infinity + else: + _pre = pre # Versions without a post segment should sort before those with one. if post is None: - post = -Infinity + _post = NegativeInfinity # type: PrePostDevType + + else: + _post = post # Versions without a development segment should sort after those with one. if dev is None: - dev = Infinity + _dev = Infinity # type: PrePostDevType + + else: + _dev = dev if local is None: # Versions without a local segment should sort before those with one. - local = -Infinity + _local = NegativeInfinity # type: LocalType else: # Versions with a local segment need that segment parsed to implement # the sorting rules in PEP440. @@ -415,6 +528,8 @@ def _cmpkey(epoch, release, pre, post, dev, local): # - Numeric segments sort numerically # - Shorter versions sort before longer versions when the prefixes # match exactly - local = tuple((i, "") if isinstance(i, int) else (-Infinity, i) for i in local) + _local = tuple( + (i, "") if isinstance(i, int) else (NegativeInfinity, i) for i in local + ) - return epoch, release, pre, post, dev, local + return epoch, _release, _pre, _post, _dev, _local diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__init__.py index 9c1a098..7355b68 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__init__.py @@ -1,4 +1,4 @@ """Wrappers to build Python packages using PEP 517 hooks """ -__version__ = '0.5.0' +__version__ = '0.8.2' diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-38.pyc index 10ef5b9890f8c65387c1a2a9bc3e84dd14419066..fa2ae9b0ccc1b2c72b5775f86c68ea7d003d4a79 100644 GIT binary patch delta 98 zcmey&ID?5Nl$V!_0SGkz?TVkslf!JGXEd=|%{fs&BR@A)zo@dbG%HiTxF}gaB{45E zH77a0s3f&mucER_zbrMcOg|?xNxz`7BqKl1SkFSgII|>Gw;(Y&J25@Ac;bE&03uc* AO8@`> delta 61 zcmbQi^qG+-l$V!_0SKO#ZHSx5lf!JPXE3o^P0mKYB)34nAhSR>Gq1QLF(*gYD8r<* N!Z<$>BslSj2>>RB6Vd<x diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/_in_process.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/_in_process.cpython-38.pyc index e38782234477ce3e6cb4f69e859282054b7d8ed5..f220f9fca992062e0455914e52af32a1e9a4ecbc 100644 GIT binary patch literal 8143 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 delta 2200 zcmZ`)OKjXk81{_4Ua$9=*LGh?^C(iBS4#**w54fNPz6XUPzr5V(A8$gZJg}d%h+j} zuuBl>71S~pPF2eRsX|Do<-m;-C!})YFc-uD0mpIxsTGv}cR~^cVQYTR{EwOWzyIOy zXa5>Yy^&0s3Ov7D{qoWm2X3ZH^bh6cgw+*kM4EafN)$$z)-Wo@O*gl3R$)4eURPMu zPHd``Br{m-x>89olf~hiW(k&rZ-%8RT`bKqFz;qvtQ)>PtcUf&x0emGK9;>sDt+t# z%K;|~yXIK|b}fXv9)NX`m0(>8*E!bD20$;*#^Wr>vMk3279*7cJIDrsU9?MVXqocg z?c$~a*VX0~YovBad`tvAHYiTTd&L~>7B{F6@8+HsllpPBd{+|>^~v$O3Xg;9A$c@= zIB2#Gx183b<N86Z(U_cGoLRZ{j8{XZ(6r$V9s%t<44(oqNVu-Ubm!4wX23WD!(RXr zC`*KqywXwH%5BQ%9rBjiAsyOL*As!-CYz+AombqPrUcru$xjk+fha-b19DMu=>?^& z@=I;?w$9W$B=@57cB&HzqHV1m*`yuqopKw!)dY<Xi`jUtTaqcukks>K)ON2r+;hc+ z#6T9WEhB!b;RG^z#SUsgz%5;TlPH#?>Mbl)Vy#-RSZ&pKunP!Jh=+-ugZ=19FA#;A zBts}kkQ6bA1~fr<UOb!pmgL3b<hhL<D0u?3c@fAs3?ElYL<dt7O=&2pBZB`v8ccRj zI|YkC*;G1o-E7k((oq4QLBNLsK1a6kQQNew0D7vfTvX;2#3>Up=sYAWU_#e7#ILEf z^prUWPubEq#!ZR`*&)hH;-~bXc};dV0Si_OYE|ZNyB>IajSqktKZs-y$v&rsfcHEM zKLcdfDRAzIsq&%w&CCoLmm0z;NpqjI%)mK*P<7nPUiGrmu>DuXcU^fhasTJ8v*fg- zs|yz8W3aJ|Htptu&HYE@uoailb*F{;d=h2xg%zj4s;i5(-H@8svR#h1;bWrN(?2?a zDyDrc;I%qtF~`_h#+FMXs26%TDem=59@*#JFo@5?@VkL1(F8;|3jxD;8ze{g@cneJ zP4w;4*855WGoZ&YlpJFyBQ5T@fm9o|YpHxheAPD?-*blev2TDZiNE_s^b??7SH(w} zoS4l%+Q6mM{l%5QX~;<3YpqRhJB0#cq2}9et!alr<kP^jG?@+&*dID{v65(U8&L`X zrN+J}gy!#qmY)KmL=DJg6I_M#rcd}ZB=q?hFMtF*z{D<zlR15+1PqR~uz$DHz`FtC zziED2T+6k_up{iT3DF4aV-5tj&=BE+UNQ&jGoqZIpD6SHHNw8~=^mpq;%uRx920h7 zG&Zwc8=AOPC>J7I3BR2zJ|-UT14}q3Q!G8Vo927sgW{Kfe1<24e+7zVn}RF|`E^CS zm&(xxis%$yi{Fk0Mw>8wlim?O6c4?56lydEHTuccJy^W0vBU|ePqzdT6D0TcNRpuh zI$WSHfo8Z>YLhaJr9V`mjYCyineuO{cu*Q8N5!9|xjCsXuh#e#pT7e4J10%ot1i^) z%eKq-%fMNWdn-X}C74?BJ=Y>qcU)$>ftBFLK`K>$%@?2d4;_(u-D^UH${4q6tcuzk zYdY-a91)i0Dt7`q6j>4RxIe!!2<(cv=y}UfzHmszK)WiOxF@(6SE)5?j{7yte6&%* zZfS-Ugv~F5X$E*=_e_x#<yddhs8-RcTD3^o>gNc3SXDCSG+Q1I8XL|6SCNagC!?M} zg)Js5x~;oEg~At*l#$FM8AXD<f2(Y;A#-eCJgi!56nq#77GGEu9Fv)2Vumn;G3T%2 zvVqs+Q6#(hvXjfwIMMXjO2dZV7x<0)X$kBeMmP*&sD_%+j1;_SO*IlmkC8PqMk=EL Q*Q9_*_&(NRM%Ezz0B_93s{jB1 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/build.cpython-38.pyc index 6ca2abb9a76a17e071c2835b73f9bf2fa62852d2..d03423c98a923fefb663c32a21b42331925f1208 100644 GIT binary patch literal 3394 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 delta 1601 zcmZ8h&2Jk;6rY*>^!g)-^XYsv4p6|McKB!|kSZ>a0}@Kq21vUSb=ICqv-Wy-nH{%@ zwZ?+vhDsH!#MwS_L+Y6WNc<Cf<$%OrfDi}XY!X2_*1Wg-X5PpC-tYO><=^H@pBIZ3 zg7wFfpB{Z@otIY0Kj{3{#)x>Ttx`-CPwVNnjuAW)&#;Y5o3@$hoSma8)jX@0xASmE zrMg$>740HMjEqZcYJ%-)rgmniLCrICitRGZQR@uZvouc&py%j1Ez;5%w&xihFHDfV z$QC<G2Xu-~)0t-k0>LXS(^)!4=jp;T_0qCPmtL||=rUaa9|a0orE3tp!lvkrF5!Q% z3R@g6PoMxeBYUV;O>X126+Jvj7=CBemIz!e3=cWj(ipu4LZC68pdlJqG5P{ww2$r} zLB>jqCJ^ocq6h-wotm1Og7v~f*JG*C>r(lW>d{eOxL&IBp5Tnta7qOI5%D|({`-S1 z(F?c2MK`Rwek2^vtG|16yMO#%;B19%m@Fx4D~1e1U0#;um>>`_F~Jt$#TVb`Ut%-W z4+GwFMDn|_St-JKN`fd=Lq{B?YA0}gF1?aB&3hV`txksK>&r5IRs%0ck6e=m%~s#_ z=t}al`ReEuFkS;i0fThjg&lniVo(yOgJTrq@9{nWpaLXai+_mG5PCK!$E2eOrK5Hg z-uO0yjN&2rnmj-ckq?q$0F4axKXtpTdH`s-{NPr#)fZJ7uu)X?15xFU8?mb6SJ`o! zg~AQ|s(V-!N6f0i0uR;}0Y9la9%l|cfopCgqDFSQQ`7hy)R}5o?9|xZ+vYsrsm3_> zgH+$%e(=fOXEh~N9sW2<_3qP5E0BwiUV=w<)8);uF26n-7nR@=p2h{tH^J7H@LVnF zEBW&g?C1v&5~wkW;gct1s9e3pBwVEgEJP?Vk;D{gteoQK(?fM6w6Pwm6Fk%;+3unH zK(kn*N(Bw|Sf?sz1GEO(6b5v`JSD@NFi+9*8$&C$#<|##<P=t%i>(+#0+^fsVr7)o zcLt^KB;-K{aBPU6=kXONcTi}JBope<Nd(+WP0qgR1J==?m@%Z@a@t+y(^@_Qn9qX` zUywpVk*Yz+d`_}QFK{T=<dG`HtQ3-3wR~ztL7%r-6L8J4@>Q^>xr=&|U3KA+ZD#49 z3jUTnGcNP;iVU+X#q~Dvb+Ek;J6ZyPph0D95)044z`&1Kpe>x;;*A$|>kd9hwWmjn zc{L+dJ>U+ElIsZ|$OibQddu}4esbvm7TXB=LRMT;_#5(uMkV1c>c3t~s`eb$KS+Mb z&(GeKSIuTqTAEGyPqC8xnO|#U^t9T6FW9m0+*X>0nQt_o0JZ_o5X>f*-vocIC+mfc z#3?M?oRQ&5mu@}BcOFB*a_%!|vnKHM<h-!?FiUKO4v$z<lKX#nWz}Y*Z{F<%wC^#P kTtMzV2=xLlz^ou~1LO+0KrBVYmT8vFyfvGYiw(H+FXUc!761SM diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-38.pyc index e50911ecddb8f5caa29819a0dfc4a7f20afc4a9d..9f1ffb2a38d207a777f82d67df86adc5040f53f0 100644 GIT binary patch delta 610 zcmXw0&ubGw6rMNPWM_ZoM@0n@)G9QEW(yX{rBtn?2-ONvv>sfxnKjuo*-dAs#mEK^ z)syIDE?$K6=uz5(c=6D?cy$kg{t;djady#pe2@2i@6DSxGe0kWzGUCCEFH;J|MStk zdFs8r14j97G#uRUI}!B{pF_X6`pD@;L*HTJ-Q9lR#H`~`FAV%aCt}=>8&AehojpI? za|XedGaB<=6kcvLojBnB!pQ4vdtE<1G}TXvZODT(iB*aChxlqN!n)ASrDusURVg`u ziOTV`K(zw^bRUIt3gU!okMXw7rhqczxUW#18q|D+0c|3xw9x~^^#moQMBOh;2saXv z6!-B&<L19ePqg@p>}*jh>zwHEx18BI)7k}8FN-6yXPH}aUO%LAZr&4TEC#lCZOs?c zLf7ZwgEa?+_-<Xd)BlBTUN~znU0IZOLZAZy6YHR0EaMs`k`o!(P?I1y%jsB=iUelM z;-&opnxa~MTUwU;SyLR9TkuZ&Dxa56bGEWjx|+!=;!ee@-I8HlO>q>bO6U!JwkD1% zD?v-j#}aW#Is_-+G-jEW64xDiLFl@5xLu!3RoA6a$937YEU6BnZZ`<KY$In;+{muN zuw<-|xpUGztc-$D!<D~FBi0bZ>O8E8H`TC`54)a~wKLZeCu<wk3;GO(+<un`Q3?D7 DC5@L$ delta 460 zcmX@7`b~u|l$V!_0SKO#ZHW6Twvn%pk(DzfKR0J{7h@KyoTYwAZh?M5W`S;IUU5lc zPL8fohDm9Kaeg95aI-o4eilBEc1|F62IAstlUaBS7@a1Y@|e_@FfCwC;aJGX$Pmtu zr@_Kd!d}9W#+1!fG>wq~1WTB*SW-AsxKg-#nHU)&8B$n+86p@;IBOVc*qWJY*-N-; z*lSpUERGUxD2ua(qxcBWT%HsjkhwLS#h1W5UNDa%m_d`zuZpjrvY;qGYw{PK_{oX9 zg^awDFY{_mX5!Oe<eIF_=QO#R&xBEL@&-O>2|h+4Mm|OkCN3r}MlL26MlMDmW-79t z{FJYi(R^|?|6Dd}ps$L|C-VuoF|L>#Dxk>dHMv|sm(30&Y&&_CK%$U0kg3Ujiz&bO z7E4}YZfcS1WLZIbQ5T@_As{Yh0}>33B8(DDMJ|&I1!ef{f&5$SIr-`7nR)3&zLVzw z#e{&tsTW_CnwOGaq*qWm`KX{4qwC}kf_Va92Y3Os6a|6^m&tiT{(_2J!c2@{_=k;y IgPnsB0N!?Qz5oCK diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-38.pyc index 1600f0136a34be68465b2be98de0e315e2146b6d..541180348f413871a70da4c72f0561e4704a3336 100644 GIT binary patch delta 94 zcmaDT)+Wvq%FD~e00f%<cExYxIm+mqsGpIao2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5*5J!26k0Oc1Um;e9( delta 57 zcmZn@e<;Qi%FD~e00hs=HpFe@Im#$!qhFF+pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JEW%X82>|#-5+wit diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-38.pyc index 17eea0372b13fd3fe98fd594671e8218d9b898bf..b6bc587cf0cf3420bbc2d9738bcc6912f5e413db 100644 GIT binary patch delta 302 zcmX@gKAl55l$V!_0SGkz?TY7NW?*;>;vfSKAjbiSi?b$byE|2Jq_Rb^g)`(yurQ>u zXLA*$FfxE(Dn}GsBtsrk1Vai_FoPynl|(>gNk)F2f|0(lLUMj?L1IZ}Qf5wON#(?C zOPu5NGxBp&^@}P?OS3Zdi;I%=QxfwsQ*)B@i%L?9^(rc>^vhE7%Jg$Glk^L~<{0Z) z=oe>}r0NzVCTAz6rxs7HVAN#fn!Jc{IV0a>FQy5MB9m`3Rr5=LT*?9@7#MjNH904z zGHa{f5_HSVN%hMwamz2wOK~kK$}hUb>6e(B3SqK)`hyvhCon5Zi2-%8Fmf<*u<|i+ QuyC<)uyC+50r`B40CQnYr2qf` delta 219 zcmbQvag<#<l$V!_0SKO#ZHOypVqka-;vfT{7=r^47kf<9c6Ui(3TDvcs<QD&%uC5h zRVYeLOv%hkR{-)9%8N2fKy0sIe?NuHJcZB@H(d)Ih5S5)fXb2#AY}|zW~4W9%Mv*& z{gT`Q{esK_-ORk=lEj=GU84+>(hB4JM3CU**^HWu?30f&E@$MPoXa$UQE>7<rfPms pkTY0-1Op=vqbA$r4rcAix0scM_<$lTj2w&{OnginEL?0HEC5o&H8KDI diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-38.pyc index 67ade92c8ae09ef02ceb4b7664314093cc2fb2a7..25e4aafa180ae1038f11aab15991c0e053572ba8 100644 GIT binary patch delta 1515 zcmbtUTTdiK6z;0->Dycv21Z<rK)h^goN=>RWdoaySrv!~3L2A%NoVLPh8~9Qrn=Yw z>2YF)S7S)6@$z7X-@uy>KJBmQnCuVm#b=Wxp6Xe2HRy{~eZD?*JEzXAzM1`HuJmcK zXe-d1i=W)@Yp11Y^yBI4t;M}^vy2pqhZTD53^m7yMeGx$IliQjJSm(gq(G|!wK+kq zks>LbpynhQBV|$nu6FvUi8L{b-n@&`%11Q1ee><*Fx<W0>UJqhi>qO~P1$Fx6-AVJ zNGgBYH27OU_krSN(MR`6i8|Ct?hI|Kn~I~0M`*rsT-a)PyEGtgL@mDK7~%rW=2Epy zxp)!Rm&f4n@2$p8xJMi8=-{B^H)7^BNGtGZ*9#e^asBY<xbc7n4;o#6s}UXXoiMmn zpKruIry$hZZMA7EB7D1A0$~cOLN~FFbYwnZ)$?<F4^2rmEQ4|2Qqy()z~`=e=RB`H zMso!@sdmG5s`<fo$ntV*fJ&c*0V~5u6!b+@6D#_hGnYw#yST(>@kr`lqAk~@0jJD$ z7sW%p)mLG+0hD>^6JQb)n*?ntTp1#Q6Lf}=!f{6>D$z)e=)_2rj@CAKE<poSQ+k-| z3FZb@xY@A=mz+Jo#QaJ{ij?J8$M38JF^8DV5E_BEY2f)Zp7BM~ID8(bddx|9z_UMP z%*nHt;VSGE@z|K?XVz<7Kjuu{mYD#l0p4i)0eEC(?fvyM_uj_F`i7&jnq1Tv-H%h% z+av!pKOgxK_%^%B=dd+?2|&Rb(og|w3LbTY73~6J{X$bQ(lN4;{Y0#qKi96qW;PAr z*lber@@_0IX07YB8<Kq$AXTF<Vh(Ulj@87bRlg#>^iamPBYv==?M%p&JYJWuAVJ3C znalqfKsEsjF95~zl!>${4cn?YW0tZNPkQLG$?TWqn8h{_kv+Mf_SBx%%W;$_iI(IB zYES2QpnN^wGZJH{Ch8eNN}><71fQXvna!D_Ik8`?pZ{uiP^AhonM|5YC0h_v<!SL{ zVO+IXMSNSB=}X0_@wBkg%L;R4g{8S2s9p#TWG}lTW&Az&*$T{k0Tj!5#Rdye31VZ) zAVAO7|HDc+lL&5){U1xu_lw_MX=S4i7J`PR6%$BDSzzn~7&B=wTb1ykgf$8460WlF zV_0|y^lui*bqB4<?>V+4rO0|`ZvniP$^@>v@Z6A)F)Zir0;G0)uobb;qj5Ycl3U`p z^3A1Dtyu7yjowN2t~`;|mJDL5hg%)$@lhP5=b2RgOh`s~C%noHyCU-}UuoHse*ofh BN!$Pc delta 1307 zcmcIjPj4GV6rVS{-d(T%#QAHb%^^*w=z`*;G-)Fg)GDPdRRJMYNXSAgwrAt6>w34d z>nKHQ_2ArkpwXxj;^ce-gijo~ao`iIK!_8EeglLe-dh)fL^v|z`T6a<H*e<s-g`f- zytq*QxKy$kj^Fmb`E0mwR9=FwkKSx-1M~Q3%BvhheOly&eaPxFcbF)M;vo}7Z+58F z=ft!qiSi-T=f#Ye5*3sdj((_XM)*Xn!bT0!%12(fb@|$RLGbWqqucdl3+S#_L&yI- zuA8``8|pb+H}?2_=H%4Ru+1GqUE~+kJziU_puz7u>+z#-J@mshzZb>mZSAcGoBe|; zL4!8c_k62tp&f%coEFHLv8`Q)MLH`pm_{kJT-WdUvFmP)oBA)XQlL$(8?;m1@9hPW zxJXT}x9`iKmuhV<RxM)(=GDkpah5X=UBBrHUq%zJr>^s^>-Az!y6(1mX*53IXiYE5 z!h0Kq1R_hoeHOD32%f+(2Nv^K>*zugy2uGbm<j9T+GcDdFoY@_0x&w^SZZuOe`?BA zbR%CQ&=68BdJ?6!ci^@9aifX+X5r{vKZ+eL=gCBu-s68gwSbHv4;hW0pjEVlz_<=N z6oG@z_+$cS`U&U8$rnqzeP8`yeOFyXLwOFtvE>}ebfvV_kNNY}*GasHkZNHN%1bCY zIXSOR^0hPa;2lsN8tRrE?qyD@bbO6qlVFG7G<|;)EoV_d&xnc$7U+vQw>4|o%4eDu zG4t0T{wbwd4m#@B(!w=9&<1)82}|@LALL>_WM6I%jKmmeiFS;HC%KWH@M9R5*`7Js z8+Qv|L1hMgNt1vcAvaYzwWKymvzjH#>UL@Q5nY&?%|`2?*Ar>(0akvLYFJP53LQ8N zhpJKTBJ^=Z<d@kP3-WJs3+!xW`u`~&)h*P<pO-sl#<czv<G~lz^O3+>qH>q-;<u#m z<Sl~R1a}C|3hXW_p5gkhz)0`FhxDt;8~E|6@vsrwey^Q6RG~F@A4v?Pq)w7o5mGzq zH$xe;yeP^#KyIjSE0=fEJT~h4c-E8h9Wu`Pgh)+|pxN<S@g!fwx1_uOk%&oMsW+xC N*+r@&v+}9E@F#om3|#;K diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-38.pyc index a6feb1109ae3b7a767f36b35c40e82d92fe4f69a..a5134dcf637773a3465a27d2d68ec5d66f33f169 100644 GIT binary patch literal 10546 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 delta 2351 zcmb7F&2QX96rZuZUa$8v$tKw}wB3GCv9wL-M~a{oP1C03ORLhVPz<W&>`WV{UVAn6 zhBR!oYBz!ds*3Q91Ek{A0|=1|LgL0Bz}Z)%A};&^NVL2+n>1<E3zp}3-iP13nfH5d ze!6t$VE0NsZxVR^T>SA`Wt5OVklFfZz)Zske+I$`qaJBei&C5`o?<ERRXw$-Sz0q? zrJA~xUe_6x0XoggG)>D~mu0Oi$WmUenYZ#F>*_4+6`Dn>NC{7Kji-32M|+eRJ;fT} zlx3K?LVDC1yg*o%<yHvG@u8k-m4VN*0`LXN53?awWTh2qjeur=4T5HnkAh`|DVIsD z{1=2zYBVV{0zcwQQPc6A8(b0fxI@SDG%*|Vym8ZRIGz{(LU)vw3%2XqEfF+$7*4cq z#WU*p=`{FA^l-i%xn81+W+XTVpGw3Y5>Wu<Kc^<6W^1zLwhp^~7=g3HN9T{XmyQJv z3gbIUwVsZ6v&CF#9~u~zqEm&MiYURnfr70M1!fvXh+0l8$_N}fwN$w;H8!-5)cQj$ z{#%>4iXlk9eNser00<<OgbEOYO8$Q@a@P3xP+bh7zvr!i{>QhhF&fWg)(+LQL~S&g zsDLKP!<h@m=Ki890$+?h>#7*<F?S8^Mi>1PF{y?pQjNdSE8S_7Ujy>&_L;guEPxEt zSW1FK2N0y00U$`TvV;x=3=T`+P%FbmBxI;%ve9+0WcyIDa!d!1RFcv~-kLh{>YG7u z^DHEfi{(dWs_|!quj2#7srdWiu+vZ>j*SQBc&uk(ggbylqyy;f5Sw-sph~0y)fl-< z1eRGXC9s|nGYs0I!EHc6lAmk49<%41#!c=s*zxY6%1JfRLhfA`d%;@lL$Z17nAOCv z0iJGT+Y`WrIuJrls?+7M`1irFcy(x?i-9#z`vQ;-Ss=HS4u%Gm`#zyW1_<+w(5ToC zb~RPJ2p<4<+xNLhw3gtD+ZP`Q+jHxcVfXE(aGeb->lnx0I4<v{^>}ss$l9aw7jzf8 z6$g<#yA|;=$WF!gM^49I?L4747uGVP(=<0>R@a}T8n<>-m6{Sis0^P+4-XY_7#-nR zt_Lh$LBaFfPlDoY82#`}3{H8xRvxP;)6yJ&tSQo$^jg#835a7)9ZJ{Rf<6k`57)f$ z-{?N+<q%q9F1GLPILMl?yVuw5?WA;48Xp1KM%*XxpXbGmNBU{}>#mbU%r2rwqU;9} zr+4q~Mp}>D@7&g+)Pl~mj^ffN-GMsjDNJGdJr(jx7L152WFix?uHDdp&$4t!b)mVU zK1!|T<Ug67@_^n>byBN&W<H?eZdABSC6@*6%czJP%Z-r_0P9oaJ#vYBR|MGL<f;Tv zEgw78q4?YC&Tdk^IC~K)$ey|K*1PBInKNhKnXR9L^Tj40u)vqIK|5--qltwu@RMxY z58JI)AR^8Z(+@W4ATb4x+QPRN9j{hO)bLiA<QBOI-M|OrUk_weBs%vS0pqfBiVPuL zsI5<g8*y8DPqh{T*O$OfOuob$?Z}z)cv9Tx?RMA@ZYz>?mShBXSpP@$29E@GHQ6p} zdcP<#^UxP;-)VC38tP<W=3$m-%!wRGeHWw>DYEq<NI!=WVr7wZfff{9G3X#wp6HrJ zbI{}Te|5bCl?&Yt#`5^~{xczOBpVm5(K^0LU4CGe7enAyl#vW08IkKBz$q5Ls3F1f z5?BNRF)I*{0<qOEp-otChP?;0FTs!<&7fM!NW=A{n?>@(EJ5dZY?jS}nG<Ly!x@9y zvwy30J$J6ZHg>}#9l+J;MDs!gu3us)oFS4$7A?%pRw5AR;xtMPydtl=(0}EPOE9&v z=b_BD#VlHuP?nipYVcMBsF0bm`bn#zN)P51cq5WwZmG(r`%H{e&49H%{svyLvP<Tu WLCY}kn^SVipb8r|N?J)XGyefkOXURs diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py index d6524b6..a536b03 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/_in_process.py @@ -2,7 +2,9 @@ It expects: - Command line args: hook_name, control_dir -- Environment variable: PEP517_BUILD_BACKEND=entry.point:spec +- Environment variables: + PEP517_BUILD_BACKEND=entry.point:spec + PEP517_BACKEND_PATH=paths (separated with os.pathsep) - control_dir/input.json: - {"kwargs": {...}} @@ -12,28 +14,86 @@ Results: """ from glob import glob from importlib import import_module +import json import os +import os.path from os.path import join as pjoin import re import shutil import sys +import traceback -# This is run as a script, not a module, so it can't do a relative import -import compat +# This file is run as a script, and `import compat` is not zip-safe, so we +# include write_json() and read_json() from compat.py. +# +# Handle reading and writing JSON in UTF-8, on Python 3 and 2. + +if sys.version_info[0] >= 3: + # Python 3 + def write_json(obj, path, **kwargs): + with open(path, 'w', encoding='utf-8') as f: + json.dump(obj, f, **kwargs) + + def read_json(path): + with open(path, 'r', encoding='utf-8') as f: + return json.load(f) + +else: + # Python 2 + def write_json(obj, path, **kwargs): + with open(path, 'wb') as f: + json.dump(obj, f, encoding='utf-8', **kwargs) + + def read_json(path): + with open(path, 'rb') as f: + return json.load(f) class BackendUnavailable(Exception): """Raised if we cannot import the backend""" + def __init__(self, traceback): + self.traceback = traceback + + +class BackendInvalid(Exception): + """Raised if the backend is invalid""" + def __init__(self, message): + self.message = message + + +class HookMissing(Exception): + """Raised if a hook is missing and we are not executing the fallback""" + + +def contained_in(filename, directory): + """Test if a file is located within the given directory.""" + filename = os.path.normcase(os.path.abspath(filename)) + directory = os.path.normcase(os.path.abspath(directory)) + return os.path.commonprefix([filename, directory]) == directory def _build_backend(): """Find and load the build backend""" + # Add in-tree backend directories to the front of sys.path. + backend_path = os.environ.get('PEP517_BACKEND_PATH') + if backend_path: + extra_pathitems = backend_path.split(os.pathsep) + sys.path[:0] = extra_pathitems + ep = os.environ['PEP517_BUILD_BACKEND'] mod_path, _, obj_path = ep.partition(':') try: obj = import_module(mod_path) except ImportError: - raise BackendUnavailable + raise BackendUnavailable(traceback.format_exc()) + + if backend_path: + if not any( + contained_in(obj.__file__, path) + for path in extra_pathitems + ): + raise BackendInvalid("Backend was not loaded from backend-path") + if obj_path: for path_part in obj_path.split('.'): obj = getattr(obj, path_part) @@ -54,15 +114,19 @@ def get_requires_for_build_wheel(config_settings): return hook(config_settings) -def prepare_metadata_for_build_wheel(metadata_directory, config_settings): +def prepare_metadata_for_build_wheel( + metadata_directory, config_settings, _allow_fallback): """Invoke optional prepare_metadata_for_build_wheel - Implements a fallback by building a wheel if the hook isn't defined. + Implements a fallback by building a wheel if the hook isn't defined, + unless _allow_fallback is False in which case HookMissing is raised. """ backend = _build_backend() try: hook = backend.prepare_metadata_for_build_wheel except AttributeError: + if not _allow_fallback: + raise HookMissing() return _get_wheel_metadata_from_wheel(backend, metadata_directory, config_settings) else: @@ -161,6 +225,8 @@ class _DummyException(Exception): class GotUnsupportedOperation(Exception): """For internal use when backend raises UnsupportedOperation""" + def __init__(self, traceback): + self.traceback = traceback def build_sdist(sdist_directory, config_settings): @@ -169,7 +235,7 @@ def build_sdist(sdist_directory, config_settings): try: return backend.build_sdist(sdist_directory, config_settings) except getattr(backend, 'UnsupportedOperation', _DummyException): - raise GotUnsupportedOperation + raise GotUnsupportedOperation(traceback.format_exc()) HOOK_NAMES = { @@ -190,17 +256,24 @@ def main(): sys.exit("Unknown hook: %s" % hook_name) hook = globals()[hook_name] - hook_input = compat.read_json(pjoin(control_dir, 'input.json')) + hook_input = read_json(pjoin(control_dir, 'input.json')) json_out = {'unsupported': False, 'return_val': None} try: json_out['return_val'] = hook(**hook_input['kwargs']) - except BackendUnavailable: + except BackendUnavailable as e: json_out['no_backend'] = True - except GotUnsupportedOperation: + json_out['traceback'] = e.traceback + except BackendInvalid as e: + json_out['backend_invalid'] = True + json_out['backend_error'] = e.message + except GotUnsupportedOperation as e: json_out['unsupported'] = True + json_out['traceback'] = e.traceback + except HookMissing: + json_out['hook_missing'] = True - compat.write_json(json_out, pjoin(control_dir, 'output.json'), indent=2) + write_json(json_out, pjoin(control_dir, 'output.json'), indent=2) if __name__ == '__main__': diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/build.py b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/build.py index ac6c949..2643014 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/build.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/build.py @@ -3,25 +3,56 @@ import argparse import logging import os -import contextlib -from pip._vendor import pytoml +from pip._vendor import toml import shutil -import errno -import tempfile from .envbuild import BuildEnvironment from .wrappers import Pep517HookCaller +from .dirtools import tempdir, mkdir_p +from .compat import FileNotFoundError log = logging.getLogger(__name__) -@contextlib.contextmanager -def tempdir(): - td = tempfile.mkdtemp() +def validate_system(system): + """ + Ensure build system has the requisite fields. + """ + required = {'requires', 'build-backend'} + if not (required <= set(system)): + message = "Missing required fields: {missing}".format( + missing=required-set(system), + ) + raise ValueError(message) + + +def load_system(source_dir): + """ + Load the build system from a source dir (pyproject.toml). + """ + pyproject = os.path.join(source_dir, 'pyproject.toml') + with open(pyproject) as f: + pyproject_data = toml.load(f) + return pyproject_data['build-system'] + + +def compat_system(source_dir): + """ + Given a source dir, attempt to get a build system backend + and requirements from pyproject.toml. Fallback to + setuptools but only if the file was not found or a build + system was not indicated. + """ try: - yield td - finally: - shutil.rmtree(td) + system = load_system(source_dir) + except (FileNotFoundError, KeyError): + system = {} + system.setdefault( + 'build-backend', + 'setuptools.build_meta:__legacy__', + ) + system.setdefault('requires', ['setuptools', 'wheel']) + return system def _do_build(hooks, env, dist, dest): @@ -42,33 +73,18 @@ def _do_build(hooks, env, dist, dest): shutil.move(source, os.path.join(dest, os.path.basename(filename))) -def mkdir_p(*args, **kwargs): - """Like `mkdir`, but does not raise an exception if the - directory already exists. - """ - try: - return os.mkdir(*args, **kwargs) - except OSError as exc: - if exc.errno != errno.EEXIST: - raise - - -def build(source_dir, dist, dest=None): - pyproject = os.path.join(source_dir, 'pyproject.toml') +def build(source_dir, dist, dest=None, system=None): + system = system or load_system(source_dir) dest = os.path.join(source_dir, dest or 'dist') mkdir_p(dest) - with open(pyproject) as f: - pyproject_data = pytoml.load(f) - # Ensure the mandatory data can be loaded - buildsys = pyproject_data['build-system'] - requires = buildsys['requires'] - backend = buildsys['build-backend'] - - hooks = Pep517HookCaller(source_dir, backend) + validate_system(system) + hooks = Pep517HookCaller( + source_dir, system['build-backend'], system.get('backend-path') + ) with BuildEnvironment() as env: - env.pip_install(requires) + env.pip_install(system['requires']) _do_build(hooks, env, dist, dest) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/check.py b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/check.py index f4cdc6b..13e722a 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/check.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/check.py @@ -4,7 +4,7 @@ import argparse import logging import os from os.path import isfile, join as pjoin -from pip._vendor.pytoml import TomlError, load as toml_load +from pip._vendor.toml import TomlDecodeError, load as toml_load import shutil from subprocess import CalledProcessError import sys @@ -147,12 +147,13 @@ def check(source_dir): buildsys = pyproject_data['build-system'] requires = buildsys['requires'] backend = buildsys['build-backend'] + backend_path = buildsys.get('backend-path') log.info('Loaded pyproject.toml') - except (TomlError, KeyError): + except (TomlDecodeError, KeyError): log.error("Invalid pyproject.toml", exc_info=True) return False - hooks = Pep517HookCaller(source_dir, backend) + hooks = Pep517HookCaller(source_dir, backend, backend_path) sdist_ok = check_build_sdist(hooks, requires) wheel_ok = check_build_wheel(hooks, requires) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/compat.py b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/compat.py index 01c66fc..8432acb 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/compat.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/compat.py @@ -1,7 +1,10 @@ -"""Handle reading and writing JSON in UTF-8, on Python 3 and 2.""" +"""Python 2/3 compatibility""" import json import sys + +# Handle reading and writing JSON in UTF-8, on Python 3 and 2. + if sys.version_info[0] >= 3: # Python 3 def write_json(obj, path, **kwargs): @@ -21,3 +24,11 @@ else: def read_json(path): with open(path, 'rb') as f: return json.load(f) + + +# FileNotFoundError + +try: + FileNotFoundError = FileNotFoundError +except NameError: + FileNotFoundError = IOError diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/envbuild.py b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/envbuild.py index f7ac5f4..4088dcd 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/envbuild.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/envbuild.py @@ -3,23 +3,27 @@ import os import logging -from pip._vendor import pytoml +from pip._vendor import toml import shutil from subprocess import check_call import sys from sysconfig import get_paths from tempfile import mkdtemp -from .wrappers import Pep517HookCaller +from .wrappers import Pep517HookCaller, LoggerWrapper log = logging.getLogger(__name__) def _load_pyproject(source_dir): with open(os.path.join(source_dir, 'pyproject.toml')) as f: - pyproject_data = pytoml.load(f) + pyproject_data = toml.load(f) buildsys = pyproject_data['build-system'] - return buildsys['requires'], buildsys['build-backend'] + return ( + buildsys['requires'], + buildsys['build-backend'], + buildsys.get('backend-path'), + ) class BuildEnvironment(object): @@ -90,9 +94,14 @@ class BuildEnvironment(object): if not reqs: return log.info('Calling pip to install %s', reqs) - check_call([ + cmd = [ sys.executable, '-m', 'pip', 'install', '--ignore-installed', - '--prefix', self.path] + list(reqs)) + '--prefix', self.path] + list(reqs) + check_call( + cmd, + stdout=LoggerWrapper(log, logging.INFO), + stderr=LoggerWrapper(log, logging.ERROR), + ) def __exit__(self, exc_type, exc_val, exc_tb): needs_cleanup = ( @@ -126,8 +135,8 @@ def build_wheel(source_dir, wheel_dir, config_settings=None): """ if config_settings is None: config_settings = {} - requires, backend = _load_pyproject(source_dir) - hooks = Pep517HookCaller(source_dir, backend) + requires, backend, backend_path = _load_pyproject(source_dir) + hooks = Pep517HookCaller(source_dir, backend, backend_path) with BuildEnvironment() as env: env.pip_install(requires) @@ -148,8 +157,8 @@ def build_sdist(source_dir, sdist_dir, config_settings=None): """ if config_settings is None: config_settings = {} - requires, backend = _load_pyproject(source_dir) - hooks = Pep517HookCaller(source_dir, backend) + requires, backend, backend_path = _load_pyproject(source_dir) + hooks = Pep517HookCaller(source_dir, backend, backend_path) with BuildEnvironment() as env: env.pip_install(requires) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/wrappers.py b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/wrappers.py index b14b899..00a3d1a 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pep517/wrappers.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/pep517/wrappers.py @@ -1,14 +1,24 @@ +import threading from contextlib import contextmanager import os from os.path import dirname, abspath, join as pjoin import shutil -from subprocess import check_call +from subprocess import check_call, check_output, STDOUT import sys from tempfile import mkdtemp from . import compat -_in_proc_script = pjoin(dirname(abspath(__file__)), '_in_process.py') + +try: + import importlib.resources as resources + + def _in_proc_script_path(): + return resources.path(__package__, '_in_process.py') +except ImportError: + @contextmanager + def _in_proc_script_path(): + yield pjoin(dirname(abspath(__file__)), '_in_process.py') @contextmanager @@ -22,10 +32,29 @@ def tempdir(): class BackendUnavailable(Exception): """Will be raised if the backend cannot be imported in the hook process.""" + def __init__(self, traceback): + self.traceback = traceback + + +class BackendInvalid(Exception): + """Will be raised if the backend is invalid.""" + def __init__(self, backend_name, backend_path, message): + self.backend_name = backend_name + self.backend_path = backend_path + self.message = message + + +class HookMissing(Exception): + """Will be raised on missing hooks.""" + def __init__(self, hook_name): + super(HookMissing, self).__init__(hook_name) + self.hook_name = hook_name class UnsupportedOperation(Exception): """May be raised by build_sdist if the backend indicates that it can't.""" + def __init__(self, traceback): + self.traceback = traceback def default_subprocess_runner(cmd, cwd=None, extra_environ=None): @@ -37,25 +66,86 @@ def default_subprocess_runner(cmd, cwd=None, extra_environ=None): check_call(cmd, cwd=cwd, env=env) +def quiet_subprocess_runner(cmd, cwd=None, extra_environ=None): + """A method of calling the wrapper subprocess while suppressing output.""" + env = os.environ.copy() + if extra_environ: + env.update(extra_environ) + + check_output(cmd, cwd=cwd, env=env, stderr=STDOUT) + + +def norm_and_check(source_tree, requested): + """Normalise and check a backend path. + + Ensure that the requested backend path is specified as a relative path, + and resolves to a location under the given source tree. + + Return an absolute version of the requested path. + """ + if os.path.isabs(requested): + raise ValueError("paths must be relative") + + abs_source = os.path.abspath(source_tree) + abs_requested = os.path.normpath(os.path.join(abs_source, requested)) + # We have to use commonprefix for Python 2.7 compatibility. So we + # normalise case to avoid problems because commonprefix is a character + # based comparison :-( + norm_source = os.path.normcase(abs_source) + norm_requested = os.path.normcase(abs_requested) + if os.path.commonprefix([norm_source, norm_requested]) != norm_source: + raise ValueError("paths must be inside source tree") + + return abs_requested + + class Pep517HookCaller(object): """A wrapper around a source directory to be built with a PEP 517 backend. source_dir : The path to the source directory, containing pyproject.toml. - backend : The build backend spec, as per PEP 517, from pyproject.toml. + build_backend : The build backend spec, as per PEP 517, from + pyproject.toml. + backend_path : The backend path, as per PEP 517, from pyproject.toml. + runner : A callable that invokes the wrapper subprocess. + + The 'runner', if provided, must expect the following: + cmd : a list of strings representing the command and arguments to + execute, as would be passed to e.g. 'subprocess.check_call'. + cwd : a string representing the working directory that must be + used for the subprocess. Corresponds to the provided source_dir. + extra_environ : a dict mapping environment variable names to values + which must be set for the subprocess execution. """ - def __init__(self, source_dir, build_backend): + def __init__( + self, + source_dir, + build_backend, + backend_path=None, + runner=None, + ): + if runner is None: + runner = default_subprocess_runner + self.source_dir = abspath(source_dir) self.build_backend = build_backend - self._subprocess_runner = default_subprocess_runner + if backend_path: + backend_path = [ + norm_and_check(self.source_dir, p) for p in backend_path + ] + self.backend_path = backend_path + self._subprocess_runner = runner - # TODO: Is this over-engineered? Maybe frontends only need to - # set this when creating the wrapper, not on every call. @contextmanager def subprocess_runner(self, runner): + """A context manager for temporarily overriding the default subprocess + runner. + """ prev = self._subprocess_runner self._subprocess_runner = runner - yield - self._subprocess_runner = prev + try: + yield + finally: + self._subprocess_runner = prev def get_requires_for_build_wheel(self, config_settings=None): """Identify packages required for building a wheel @@ -72,18 +162,21 @@ class Pep517HookCaller(object): }) def prepare_metadata_for_build_wheel( - self, metadata_directory, config_settings=None): + self, metadata_directory, config_settings=None, + _allow_fallback=True): """Prepare a *.dist-info folder with metadata for this project. Returns the name of the newly created folder. If the build backend defines a hook with this name, it will be called in a subprocess. If not, the backend will be asked to build a wheel, - and the dist-info extracted from that. + and the dist-info extracted from that (unless _allow_fallback is + False). """ return self._call_hook('prepare_metadata_for_build_wheel', { 'metadata_directory': abspath(metadata_directory), 'config_settings': config_settings, + '_allow_fallback': _allow_fallback, }) def build_wheel( @@ -139,25 +232,77 @@ class Pep517HookCaller(object): # letters, digits and _, . and : characters, and will be used as a # Python identifier, so non-ASCII content is wrong on Python 2 in # any case). + # For backend_path, we use sys.getfilesystemencoding. if sys.version_info[0] == 2: build_backend = self.build_backend.encode('ASCII') else: build_backend = self.build_backend + extra_environ = {'PEP517_BUILD_BACKEND': build_backend} + + if self.backend_path: + backend_path = os.pathsep.join(self.backend_path) + if sys.version_info[0] == 2: + backend_path = backend_path.encode(sys.getfilesystemencoding()) + extra_environ['PEP517_BACKEND_PATH'] = backend_path with tempdir() as td: - compat.write_json({'kwargs': kwargs}, pjoin(td, 'input.json'), + hook_input = {'kwargs': kwargs} + compat.write_json(hook_input, pjoin(td, 'input.json'), indent=2) # Run the hook in a subprocess - self._subprocess_runner( - [sys.executable, _in_proc_script, hook_name, td], - cwd=self.source_dir, - extra_environ={'PEP517_BUILD_BACKEND': build_backend} - ) + with _in_proc_script_path() as script: + self._subprocess_runner( + [sys.executable, str(script), hook_name, td], + cwd=self.source_dir, + extra_environ=extra_environ + ) data = compat.read_json(pjoin(td, 'output.json')) if data.get('unsupported'): - raise UnsupportedOperation + raise UnsupportedOperation(data.get('traceback', '')) if data.get('no_backend'): - raise BackendUnavailable + raise BackendUnavailable(data.get('traceback', '')) + if data.get('backend_invalid'): + raise BackendInvalid( + backend_name=self.build_backend, + backend_path=self.backend_path, + message=data.get('backend_error', '') + ) + if data.get('hook_missing'): + raise HookMissing(hook_name) return data['return_val'] + + +class LoggerWrapper(threading.Thread): + """ + Read messages from a pipe and redirect them + to a logger (see python's logging module). + """ + + def __init__(self, logger, level): + threading.Thread.__init__(self) + self.daemon = True + + self.logger = logger + self.level = level + + # create the pipe and reader + self.fd_read, self.fd_write = os.pipe() + self.reader = os.fdopen(self.fd_read) + + self.start() + + def fileno(self): + return self.fd_write + + @staticmethod + def remove_newline(msg): + return msg[:-1] if msg.endswith(os.linesep) else msg + + def run(self): + for line in self.reader: + self._write(self.remove_newline(line)) + + def _write(self, message): + self.logger.log(self.level, message) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__init__.py index fdd40de..a457ff2 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__init__.py @@ -88,8 +88,8 @@ __import__('pip._vendor.packaging.markers') __metaclass__ = type -if (3, 0) < sys.version_info < (3, 4): - raise RuntimeError("Python 3.4 or later is required") +if (3, 0) < sys.version_info < (3, 5): + raise RuntimeError("Python 3.5 or later is required") if six.PY2: # Those builtin exceptions are only defined in Python 3 @@ -333,7 +333,7 @@ class UnknownExtra(ResolutionError): _provider_factories = {} -PY_MAJOR = sys.version[:3] +PY_MAJOR = '{}.{}'.format(*sys.version_info) EGG_DIST = 3 BINARY_DIST = 2 SOURCE_DIST = 1 @@ -1416,8 +1416,17 @@ class NullProvider: def get_metadata(self, name): if not self.egg_info: return "" - value = self._get(self._fn(self.egg_info, name)) - return value.decode('utf-8') if six.PY3 else value + path = self._get_metadata_path(name) + value = self._get(path) + if six.PY2: + return value + try: + return value.decode('utf-8') + except UnicodeDecodeError as exc: + # Include the path in the error message to simplify + # troubleshooting, and without changing the exception type. + exc.reason += ' in {} file at path: {}'.format(name, path) + raise def get_metadata_lines(self, name): return yield_lines(self.get_metadata(name)) @@ -3100,6 +3109,7 @@ class Requirement(packaging.requirements.Requirement): self.extras = tuple(map(safe_extra, self.extras)) self.hashCmp = ( self.key, + self.url, self.specifier, frozenset(self.extras), str(self.marker) if self.marker else None, diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-38.pyc index 1e9839284ef787c393d514a517b2f75c750f893b..097cf44310bdffc9f7e3f84ce6c5115f4b87b158 100644 GIT binary patch delta 13593 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 M4lBgDF)>O1KSE_1asU7T delta 13238 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 WKN;gnan*^lyYLD#&W(vc`u_l-Knr64 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-38.pyc index 74cff63ac2d56d724786c764c6e7fbf5154485d4..9f2d5f34ebe7c3e2c58764a15ab6006a1b64eca9 100644 GIT binary patch delta 93 zcmaFJ(#FaY%FD~e00f%<cExYxabk4N($C1xP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS vE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc5FD!}t{dk<K8| delta 56 zcmZo;eaONS%FD~e00hs=HpFe@ablEn)i22{&@ad=(9O&%E=kPE(KX62DXlQhPXq~0 Ip2+wW0M0`aT>t<8 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-38.pyc index 5d9cf81ae6da64d5f97865d56cf3ad4d4603988b..1956a2b6b51dbcb973fb12499e515b9a99e45385 100644 GIT binary patch delta 94 zcmX@5{a%|Vl$V!_0SGkz?TX*XvxnI^SwAB`H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lAGv+6P01$j4fdBvi delta 57 zcmaE_eM*}rl$V!_0SKO#ZHU{*vxiyEPQN6#K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj JnVaQ_AOI7Z6Al0X diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-38.pyc index 2b50ee5d0492f991028f8560472db571c34466ca..b1f436b907f77c4d3ba3d08c32009cdd4772147a 100644 GIT binary patch delta 94 zcmZ1_a$bZdl$V!_0SGkz?TX*XGl|JLPCp|*H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lA9;Q5Y0NDf~H~;_u delta 57 zcmX>vvPy&}l$V!_0SKO#ZHU{*Gl@ygQokg(K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J`5{vtI{^0e62t%i diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-38.pyc index 15bc9cfd91875da5612e533e2dd5c510d4ec8a07..af018cd41914bca2ce597c1427244c97fe516903 100644 GIT binary patch delta 94 zcmbQmy`P&Wl$V!_0SGkz?TX*X<Im`vq@R(Wo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5)Ql2MTb0J3!;G5`Po delta 57 zcmdnbJ&T(sl$V!_0SKO#ZHU{*<IgB(t6!2^pkI(#pqrUjT#}fRqid95Qd(i0p9m7% JJdaV41pwgS5xxKb diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-38.pyc index 975363c5460346586250ad18788811d12620193d..b0ffcaf62fa2b53a746e1c1f64898ec8bc5c7e5f 100644 GIT binary patch delta 94 zcmcb}^^J=sl$V!_0SGkz?TX*X)6D3cq@R(Wo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5(lE#neq0P4gchyVZp delta 57 zcmeyyb&-oFl$V!_0SKO#ZHU{*)66Jmt6!2^pkI(#pqrUjT#}fRqid95Qd(i0p9m7% Je2H-hGXMe}6BGad diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pyparsing.py b/venv/lib/python3.8/site-packages/pip/_vendor/pyparsing.py index 9d6a01d..7ebc7eb 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pyparsing.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/pyparsing.py @@ -1,4 +1,4 @@ -#-*- coding: utf-8 -*- +# -*- coding: utf-8 -*- # module pyparsing.py # # Copyright (c) 2003-2019 Paul T. McGuire @@ -87,14 +87,16 @@ classes inherit from. Use the docstrings for examples of how to: more complex ones - associate names with your parsed results using :class:`ParserElement.setResultsName` + - access the parsed data, which is returned as a :class:`ParseResults` + object - find some helpful expression short-cuts like :class:`delimitedList` and :class:`oneOf` - find more useful common expressions in the :class:`pyparsing_common` namespace class """ -__version__ = "2.4.0" -__versionTime__ = "07 Apr 2019 18:28 UTC" +__version__ = "2.4.7" +__versionTime__ = "30 Mar 2020 00:43 UTC" __author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" import string @@ -109,6 +111,10 @@ import pprint import traceback import types from datetime import datetime +from operator import itemgetter +import itertools +from functools import wraps +from contextlib import contextmanager try: # Python 3 @@ -124,11 +130,11 @@ except ImportError: try: # Python 3 from collections.abc import Iterable - from collections.abc import MutableMapping + from collections.abc import MutableMapping, Mapping except ImportError: # Python 2.7 from collections import Iterable - from collections import MutableMapping + from collections import MutableMapping, Mapping try: from collections import OrderedDict as _OrderedDict @@ -146,40 +152,70 @@ except ImportError: # version compatibility configuration __compat__ = SimpleNamespace() __compat__.__doc__ = """ - A cross-version compatibility configuration for pyparsing features that will be - released in a future version. By setting values in this configuration to True, - those features can be enabled in prior versions for compatibility development + A cross-version compatibility configuration for pyparsing features that will be + released in a future version. By setting values in this configuration to True, + those features can be enabled in prior versions for compatibility development and testing. - + - collect_all_And_tokens - flag to enable fix for Issue #63 that fixes erroneous grouping - of results names when an And expression is nested within an Or or MatchFirst; set to - True to enable bugfix to be released in pyparsing 2.4 + of results names when an And expression is nested within an Or or MatchFirst; set to + True to enable bugfix released in pyparsing 2.3.0, or False to preserve + pre-2.3.0 handling of named results """ __compat__.collect_all_And_tokens = True +__diag__ = SimpleNamespace() +__diag__.__doc__ = """ +Diagnostic configuration (all default to False) + - warn_multiple_tokens_in_named_alternation - flag to enable warnings when a results + name is defined on a MatchFirst or Or expression with one or more And subexpressions + (only warns if __compat__.collect_all_And_tokens is False) + - warn_ungrouped_named_tokens_in_collection - flag to enable warnings when a results + name is defined on a containing expression with ungrouped subexpressions that also + have results names + - warn_name_set_on_empty_Forward - flag to enable warnings whan a Forward is defined + with a results name, but has no contents defined + - warn_on_multiple_string_args_to_oneof - flag to enable warnings whan oneOf is + incorrectly called with multiple str arguments + - enable_debug_on_named_expressions - flag to auto-enable debug on all subsequent + calls to ParserElement.setName() +""" +__diag__.warn_multiple_tokens_in_named_alternation = False +__diag__.warn_ungrouped_named_tokens_in_collection = False +__diag__.warn_name_set_on_empty_Forward = False +__diag__.warn_on_multiple_string_args_to_oneof = False +__diag__.enable_debug_on_named_expressions = False +__diag__._all_names = [nm for nm in vars(__diag__) if nm.startswith("enable_") or nm.startswith("warn_")] -#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) +def _enable_all_warnings(): + __diag__.warn_multiple_tokens_in_named_alternation = True + __diag__.warn_ungrouped_named_tokens_in_collection = True + __diag__.warn_name_set_on_empty_Forward = True + __diag__.warn_on_multiple_string_args_to_oneof = True +__diag__.enable_all_warnings = _enable_all_warnings -__all__ = [ '__version__', '__versionTime__', '__author__', '__compat__', -'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', -'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', -'PrecededBy', 'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', -'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', -'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', -'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', -'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', 'Char', -'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', -'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', -'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums', -'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno', -'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', -'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', -'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', -'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', -'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', -'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass', -'CloseMatch', 'tokenMap', 'pyparsing_common', 'pyparsing_unicode', 'unicode_set', -] + +__all__ = ['__version__', '__versionTime__', '__author__', '__compat__', '__diag__', + 'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', + 'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', + 'PrecededBy', 'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', + 'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', + 'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', + 'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', + 'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', 'Char', + 'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', + 'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', + 'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums', + 'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno', + 'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', + 'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', + 'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', + 'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', + 'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', + 'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation', 'locatedExpr', 'withClass', + 'CloseMatch', 'tokenMap', 'pyparsing_common', 'pyparsing_unicode', 'unicode_set', + 'conditionAsParseAction', 're', + ] system_version = tuple(sys.version_info)[:3] PY_3 = system_version[0] == 3 @@ -204,7 +240,7 @@ else: < returns the unicode object | encodes it with the default encoding | ... >. """ - if isinstance(obj,unicode): + if isinstance(obj, unicode): return obj try: @@ -222,9 +258,10 @@ else: # build list of single arg builtins, tolerant of Python version, that can be used as parse actions singleArgBuiltins = [] import __builtin__ + for fname in "sum len sorted reversed list tuple set any all min max".split(): try: - singleArgBuiltins.append(getattr(__builtin__,fname)) + singleArgBuiltins.append(getattr(__builtin__, fname)) except AttributeError: continue @@ -235,23 +272,36 @@ def _xml_escape(data): # ampersand must be replaced first from_symbols = '&><"\'' - to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split()) - for from_,to_ in zip(from_symbols, to_symbols): + to_symbols = ('&' + s + ';' for s in "amp gt lt quot apos".split()) + for from_, to_ in zip(from_symbols, to_symbols): data = data.replace(from_, to_) return data -alphas = string.ascii_uppercase + string.ascii_lowercase -nums = "0123456789" -hexnums = nums + "ABCDEFabcdef" -alphanums = alphas + nums -_bslash = chr(92) +alphas = string.ascii_uppercase + string.ascii_lowercase +nums = "0123456789" +hexnums = nums + "ABCDEFabcdef" +alphanums = alphas + nums +_bslash = chr(92) printables = "".join(c for c in string.printable if c not in string.whitespace) + +def conditionAsParseAction(fn, message=None, fatal=False): + msg = message if message is not None else "failed user-defined condition" + exc_type = ParseFatalException if fatal else ParseException + fn = _trim_arity(fn) + + @wraps(fn) + def pa(s, l, t): + if not bool(fn(s, l, t)): + raise exc_type(s, l, msg) + + return pa + class ParseBaseException(Exception): """base exception class for all parsing runtime exceptions""" # Performance tuning: we construct a *lot* of these, so keep this # constructor as small and fast as possible - def __init__( self, pstr, loc=0, msg=None, elem=None ): + def __init__(self, pstr, loc=0, msg=None, elem=None): self.loc = loc if msg is None: self.msg = pstr @@ -270,27 +320,34 @@ class ParseBaseException(Exception): """ return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) - def __getattr__( self, aname ): + def __getattr__(self, aname): """supported attributes by name are: - lineno - returns the line number of the exception text - col - returns the column number of the exception text - line - returns the line containing the exception text """ - if( aname == "lineno" ): - return lineno( self.loc, self.pstr ) - elif( aname in ("col", "column") ): - return col( self.loc, self.pstr ) - elif( aname == "line" ): - return line( self.loc, self.pstr ) + if aname == "lineno": + return lineno(self.loc, self.pstr) + elif aname in ("col", "column"): + return col(self.loc, self.pstr) + elif aname == "line": + return line(self.loc, self.pstr) else: raise AttributeError(aname) - def __str__( self ): - return "%s (at char %d), (line:%d, col:%d)" % \ - ( self.msg, self.loc, self.lineno, self.column ) - def __repr__( self ): + def __str__(self): + if self.pstr: + if self.loc >= len(self.pstr): + foundstr = ', found end of text' + else: + foundstr = (', found %r' % self.pstr[self.loc:self.loc + 1]).replace(r'\\', '\\') + else: + foundstr = '' + return ("%s%s (at char %d), (line:%d, col:%d)" % + (self.msg, foundstr, self.loc, self.lineno, self.column)) + def __repr__(self): return _ustr(self) - def markInputline( self, markerString = ">!<" ): + def markInputline(self, markerString=">!<"): """Extracts the exception line from the input string, and marks the location of the exception with a special symbol. """ @@ -426,21 +483,21 @@ class RecursiveGrammarException(Exception): """exception thrown by :class:`ParserElement.validate` if the grammar could be improperly recursive """ - def __init__( self, parseElementList ): + def __init__(self, parseElementList): self.parseElementTrace = parseElementList - def __str__( self ): + def __str__(self): return "RecursiveGrammarException: %s" % self.parseElementTrace class _ParseResultsWithOffset(object): - def __init__(self,p1,p2): - self.tup = (p1,p2) - def __getitem__(self,i): + def __init__(self, p1, p2): + self.tup = (p1, p2) + def __getitem__(self, i): return self.tup[i] def __repr__(self): return repr(self.tup[0]) - def setOffset(self,i): - self.tup = (self.tup[0],i) + def setOffset(self, i): + self.tup = (self.tup[0], i) class ParseResults(object): """Structured parse results, to provide multiple means of access to @@ -485,7 +542,7 @@ class ParseResults(object): - month: 12 - year: 1999 """ - def __new__(cls, toklist=None, name=None, asList=True, modal=True ): + def __new__(cls, toklist=None, name=None, asList=True, modal=True): if isinstance(toklist, cls): return toklist retobj = object.__new__(cls) @@ -494,7 +551,7 @@ class ParseResults(object): # Performance tuning: we construct a *lot* of these, so keep this # constructor as small and fast as possible - def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ): + def __init__(self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance): if self.__doinit: self.__doinit = False self.__name = None @@ -515,85 +572,93 @@ class ParseResults(object): if name is not None and name: if not modal: self.__accumNames[name] = 0 - if isinstance(name,int): - name = _ustr(name) # will always return a str, but use _ustr for consistency + if isinstance(name, int): + name = _ustr(name) # will always return a str, but use _ustr for consistency self.__name = name - if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): - if isinstance(toklist,basestring): - toklist = [ toklist ] + if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None, '', [])): + if isinstance(toklist, basestring): + toklist = [toklist] if asList: - if isinstance(toklist,ParseResults): + if isinstance(toklist, ParseResults): self[name] = _ParseResultsWithOffset(ParseResults(toklist.__toklist), 0) else: - self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]), 0) self[name].__name = name else: try: self[name] = toklist[0] - except (KeyError,TypeError,IndexError): + except (KeyError, TypeError, IndexError): self[name] = toklist - def __getitem__( self, i ): - if isinstance( i, (int,slice) ): + def __getitem__(self, i): + if isinstance(i, (int, slice)): return self.__toklist[i] else: if i not in self.__accumNames: return self.__tokdict[i][-1][0] else: - return ParseResults([ v[0] for v in self.__tokdict[i] ]) + return ParseResults([v[0] for v in self.__tokdict[i]]) - def __setitem__( self, k, v, isinstance=isinstance ): - if isinstance(v,_ParseResultsWithOffset): - self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] + def __setitem__(self, k, v, isinstance=isinstance): + if isinstance(v, _ParseResultsWithOffset): + self.__tokdict[k] = self.__tokdict.get(k, list()) + [v] sub = v[0] - elif isinstance(k,(int,slice)): + elif isinstance(k, (int, slice)): self.__toklist[k] = v sub = v else: - self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + self.__tokdict[k] = self.__tokdict.get(k, list()) + [_ParseResultsWithOffset(v, 0)] sub = v - if isinstance(sub,ParseResults): + if isinstance(sub, ParseResults): sub.__parent = wkref(self) - def __delitem__( self, i ): - if isinstance(i,(int,slice)): - mylen = len( self.__toklist ) + def __delitem__(self, i): + if isinstance(i, (int, slice)): + mylen = len(self.__toklist) del self.__toklist[i] # convert int to slice if isinstance(i, int): if i < 0: i += mylen - i = slice(i, i+1) + i = slice(i, i + 1) # get removed indices removed = list(range(*i.indices(mylen))) removed.reverse() # fixup indices in token dictionary - for name,occurrences in self.__tokdict.items(): + for name, occurrences in self.__tokdict.items(): for j in removed: for k, (value, position) in enumerate(occurrences): occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) else: del self.__tokdict[i] - def __contains__( self, k ): + def __contains__(self, k): return k in self.__tokdict - def __len__( self ): return len( self.__toklist ) - def __bool__(self): return ( not not self.__toklist ) + def __len__(self): + return len(self.__toklist) + + def __bool__(self): + return (not not self.__toklist) __nonzero__ = __bool__ - def __iter__( self ): return iter( self.__toklist ) - def __reversed__( self ): return iter( self.__toklist[::-1] ) - def _iterkeys( self ): + + def __iter__(self): + return iter(self.__toklist) + + def __reversed__(self): + return iter(self.__toklist[::-1]) + + def _iterkeys(self): if hasattr(self.__tokdict, "iterkeys"): return self.__tokdict.iterkeys() else: return iter(self.__tokdict) - def _itervalues( self ): + def _itervalues(self): return (self[k] for k in self._iterkeys()) - def _iteritems( self ): + def _iteritems(self): return ((k, self[k]) for k in self._iterkeys()) if PY_3: @@ -616,24 +681,24 @@ class ParseResults(object): iteritems = _iteritems """Returns an iterator of all named result key-value tuples (Python 2.x only).""" - def keys( self ): + def keys(self): """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x).""" return list(self.iterkeys()) - def values( self ): + def values(self): """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x).""" return list(self.itervalues()) - def items( self ): + def items(self): """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x).""" return list(self.iteritems()) - def haskeys( self ): + def haskeys(self): """Since keys() returns an iterator, this method is helpful in bypassing code that looks for the existence of any defined results names.""" return bool(self.__tokdict) - def pop( self, *args, **kwargs): + def pop(self, *args, **kwargs): """ Removes and returns item at specified index (default= ``last``). Supports both ``list`` and ``dict`` semantics for ``pop()``. If @@ -672,14 +737,14 @@ class ParseResults(object): """ if not args: args = [-1] - for k,v in kwargs.items(): + for k, v in kwargs.items(): if k == 'default': args = (args[0], v) else: raise TypeError("pop() got an unexpected keyword argument '%s'" % k) - if (isinstance(args[0], int) or - len(args) == 1 or - args[0] in self): + if (isinstance(args[0], int) + or len(args) == 1 + or args[0] in self): index = args[0] ret = self[index] del self[index] @@ -711,7 +776,7 @@ class ParseResults(object): else: return defaultValue - def insert( self, index, insStr ): + def insert(self, index, insStr): """ Inserts new element at location index in the list of parsed tokens. @@ -728,11 +793,11 @@ class ParseResults(object): """ self.__toklist.insert(index, insStr) # fixup indices in token dictionary - for name,occurrences in self.__tokdict.items(): + for name, occurrences in self.__tokdict.items(): for k, (value, position) in enumerate(occurrences): occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) - def append( self, item ): + def append(self, item): """ Add single element to end of ParseResults list of elements. @@ -747,7 +812,7 @@ class ParseResults(object): """ self.__toklist.append(item) - def extend( self, itemseq ): + def extend(self, itemseq): """ Add sequence of elements to end of ParseResults list of elements. @@ -766,74 +831,66 @@ class ParseResults(object): else: self.__toklist.extend(itemseq) - def clear( self ): + def clear(self): """ Clear all elements and results names. """ del self.__toklist[:] self.__tokdict.clear() - def __getattr__( self, name ): + def __getattr__(self, name): try: return self[name] except KeyError: return "" - if name in self.__tokdict: - if name not in self.__accumNames: - return self.__tokdict[name][-1][0] - else: - return ParseResults([ v[0] for v in self.__tokdict[name] ]) - else: - return "" - - def __add__( self, other ): + def __add__(self, other): ret = self.copy() ret += other return ret - def __iadd__( self, other ): + def __iadd__(self, other): if other.__tokdict: offset = len(self.__toklist) - addoffset = lambda a: offset if a<0 else a+offset + addoffset = lambda a: offset if a < 0 else a + offset otheritems = other.__tokdict.items() - otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) - for (k,vlist) in otheritems for v in vlist] - for k,v in otherdictitems: + otherdictitems = [(k, _ParseResultsWithOffset(v[0], addoffset(v[1]))) + for k, vlist in otheritems for v in vlist] + for k, v in otherdictitems: self[k] = v - if isinstance(v[0],ParseResults): + if isinstance(v[0], ParseResults): v[0].__parent = wkref(self) self.__toklist += other.__toklist - self.__accumNames.update( other.__accumNames ) + self.__accumNames.update(other.__accumNames) return self def __radd__(self, other): - if isinstance(other,int) and other == 0: + if isinstance(other, int) and other == 0: # useful for merging many ParseResults using sum() builtin return self.copy() else: # this may raise a TypeError - so be it return other + self - def __repr__( self ): - return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) + def __repr__(self): + return "(%s, %s)" % (repr(self.__toklist), repr(self.__tokdict)) - def __str__( self ): + def __str__(self): return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' - def _asStringList( self, sep='' ): + def _asStringList(self, sep=''): out = [] for item in self.__toklist: if out and sep: out.append(sep) - if isinstance( item, ParseResults ): + if isinstance(item, ParseResults): out += item._asStringList() else: - out.append( _ustr(item) ) + out.append(_ustr(item)) return out - def asList( self ): + def asList(self): """ Returns the parse results as a nested list of matching tokens, all converted to strings. @@ -848,9 +905,9 @@ class ParseResults(object): result_list = result.asList() print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj'] """ - return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist] + return [res.asList() if isinstance(res, ParseResults) else res for res in self.__toklist] - def asDict( self ): + def asDict(self): """ Returns the named parse results as a nested dictionary. @@ -884,27 +941,27 @@ class ParseResults(object): else: return obj - return dict((k,toItem(v)) for k,v in item_fn()) + return dict((k, toItem(v)) for k, v in item_fn()) - def copy( self ): + def copy(self): """ Returns a new copy of a :class:`ParseResults` object. """ - ret = ParseResults( self.__toklist ) + ret = ParseResults(self.__toklist) ret.__tokdict = dict(self.__tokdict.items()) ret.__parent = self.__parent - ret.__accumNames.update( self.__accumNames ) + ret.__accumNames.update(self.__accumNames) ret.__name = self.__name return ret - def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): + def asXML(self, doctag=None, namedItemsOnly=False, indent="", formatted=True): """ (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names. """ nl = "\n" out = [] - namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items() - for v in vlist) + namedItems = dict((v[1], k) for (k, vlist) in self.__tokdict.items() + for v in vlist) nextLevelIndent = indent + " " # collapse out indents if formatting is not desired @@ -926,20 +983,20 @@ class ParseResults(object): else: selfTag = "ITEM" - out += [ nl, indent, "<", selfTag, ">" ] + out += [nl, indent, "<", selfTag, ">"] - for i,res in enumerate(self.__toklist): - if isinstance(res,ParseResults): + for i, res in enumerate(self.__toklist): + if isinstance(res, ParseResults): if i in namedItems: - out += [ res.asXML(namedItems[i], - namedItemsOnly and doctag is None, - nextLevelIndent, - formatted)] + out += [res.asXML(namedItems[i], + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] else: - out += [ res.asXML(None, - namedItemsOnly and doctag is None, - nextLevelIndent, - formatted)] + out += [res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] else: # individual token, see if there is a name for it resTag = None @@ -951,16 +1008,16 @@ class ParseResults(object): else: resTag = "ITEM" xmlBodyText = _xml_escape(_ustr(res)) - out += [ nl, nextLevelIndent, "<", resTag, ">", - xmlBodyText, - "</", resTag, ">" ] + out += [nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "</", resTag, ">"] - out += [ nl, indent, "</", selfTag, ">" ] + out += [nl, indent, "</", selfTag, ">"] return "".join(out) - def __lookup(self,sub): - for k,vlist in self.__tokdict.items(): - for v,loc in vlist: + def __lookup(self, sub): + for k, vlist in self.__tokdict.items(): + for v, loc in vlist: if sub is v: return k return None @@ -998,14 +1055,14 @@ class ParseResults(object): return par.__lookup(self) else: return None - elif (len(self) == 1 and - len(self.__tokdict) == 1 and - next(iter(self.__tokdict.values()))[0][1] in (0,-1)): + elif (len(self) == 1 + and len(self.__tokdict) == 1 + and next(iter(self.__tokdict.values()))[0][1] in (0, -1)): return next(iter(self.__tokdict.keys())) else: return None - def dump(self, indent='', depth=0, full=True): + def dump(self, indent='', full=True, include_list=True, _depth=0): """ Diagnostic method for listing out the contents of a :class:`ParseResults`. Accepts an optional ``indent`` argument so @@ -1028,28 +1085,45 @@ class ParseResults(object): """ out = [] NL = '\n' - out.append( indent+_ustr(self.asList()) ) + if include_list: + out.append(indent + _ustr(self.asList())) + else: + out.append('') + if full: if self.haskeys(): - items = sorted((str(k), v) for k,v in self.items()) - for k,v in items: + items = sorted((str(k), v) for k, v in self.items()) + for k, v in items: if out: out.append(NL) - out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) - if isinstance(v,ParseResults): + out.append("%s%s- %s: " % (indent, (' ' * _depth), k)) + if isinstance(v, ParseResults): if v: - out.append( v.dump(indent,depth+1) ) + out.append(v.dump(indent=indent, full=full, include_list=include_list, _depth=_depth + 1)) else: out.append(_ustr(v)) else: out.append(repr(v)) - elif any(isinstance(vv,ParseResults) for vv in self): + elif any(isinstance(vv, ParseResults) for vv in self): v = self - for i,vv in enumerate(v): - if isinstance(vv,ParseResults): - out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),vv.dump(indent,depth+1) )) + for i, vv in enumerate(v): + if isinstance(vv, ParseResults): + out.append("\n%s%s[%d]:\n%s%s%s" % (indent, + (' ' * (_depth)), + i, + indent, + (' ' * (_depth + 1)), + vv.dump(indent=indent, + full=full, + include_list=include_list, + _depth=_depth + 1))) else: - out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) + out.append("\n%s%s[%d]:\n%s%s%s" % (indent, + (' ' * (_depth)), + i, + indent, + (' ' * (_depth + 1)), + _ustr(vv))) return "".join(out) @@ -1082,18 +1156,15 @@ class ParseResults(object): # add support for pickle protocol def __getstate__(self): - return ( self.__toklist, - ( self.__tokdict.copy(), - self.__parent is not None and self.__parent() or None, - self.__accumNames, - self.__name ) ) + return (self.__toklist, + (self.__tokdict.copy(), + self.__parent is not None and self.__parent() or None, + self.__accumNames, + self.__name)) - def __setstate__(self,state): + def __setstate__(self, state): self.__toklist = state[0] - (self.__tokdict, - par, - inAccumNames, - self.__name) = state[1] + self.__tokdict, par, inAccumNames, self.__name = state[1] self.__accumNames = {} self.__accumNames.update(inAccumNames) if par is not None: @@ -1105,11 +1176,39 @@ class ParseResults(object): return self.__toklist, self.__name, self.__asList, self.__modal def __dir__(self): - return (dir(type(self)) + list(self.keys())) + return dir(type(self)) + list(self.keys()) + + @classmethod + def from_dict(cls, other, name=None): + """ + Helper classmethod to construct a ParseResults from a dict, preserving the + name-value relations as results names. If an optional 'name' argument is + given, a nested ParseResults will be returned + """ + def is_iterable(obj): + try: + iter(obj) + except Exception: + return False + else: + if PY_3: + return not isinstance(obj, (str, bytes)) + else: + return not isinstance(obj, basestring) + + ret = cls([]) + for k, v in other.items(): + if isinstance(v, Mapping): + ret += cls.from_dict(v, name=k) + else: + ret += cls([v], name=k, asList=is_iterable(v)) + if name is not None: + ret = cls([ret], name=name) + return ret MutableMapping.register(ParseResults) -def col (loc,strg): +def col (loc, strg): """Returns current column within a string, counting newlines as line separators. The first column is number 1. @@ -1121,9 +1220,9 @@ def col (loc,strg): location, and line and column positions within the parsed string. """ s = strg - return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc) + return 1 if 0 < loc < len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc) -def lineno(loc,strg): +def lineno(loc, strg): """Returns current line number within a string, counting newlines as line separators. The first line is number 1. @@ -1133,26 +1232,26 @@ def lineno(loc,strg): suggested methods to maintain a consistent view of the parsed string, the parse location, and line and column positions within the parsed string. """ - return strg.count("\n",0,loc) + 1 + return strg.count("\n", 0, loc) + 1 -def line( loc, strg ): +def line(loc, strg): """Returns the line of text containing loc within a string, counting newlines as line separators. """ lastCR = strg.rfind("\n", 0, loc) nextCR = strg.find("\n", loc) if nextCR >= 0: - return strg[lastCR+1:nextCR] + return strg[lastCR + 1:nextCR] else: - return strg[lastCR+1:] + return strg[lastCR + 1:] -def _defaultStartDebugAction( instring, loc, expr ): - print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))) +def _defaultStartDebugAction(instring, loc, expr): + print(("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % (lineno(loc, instring), col(loc, instring)))) -def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): - print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) +def _defaultSuccessDebugAction(instring, startloc, endloc, expr, toks): + print("Matched " + _ustr(expr) + " -> " + str(toks.asList())) -def _defaultExceptionDebugAction( instring, loc, expr, exc ): - print ("Exception raised:" + _ustr(exc)) +def _defaultExceptionDebugAction(instring, loc, expr, exc): + print("Exception raised:" + _ustr(exc)) def nullDebugAction(*args): """'Do-nothing' debug action, to suppress debugging output during parsing.""" @@ -1183,16 +1282,16 @@ def nullDebugAction(*args): 'decorator to trim function calls to match the arity of the target' def _trim_arity(func, maxargs=2): if func in singleArgBuiltins: - return lambda s,l,t: func(t) + return lambda s, l, t: func(t) limit = [0] foundArity = [False] # traceback return data structure changed in Py3.5 - normalize back to plain tuples - if system_version[:2] >= (3,5): + if system_version[:2] >= (3, 5): def extract_stack(limit=0): # special handling for Python 3.5.0 - extra deep call stack by 1 - offset = -3 if system_version == (3,5,0) else -2 - frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset] + offset = -3 if system_version == (3, 5, 0) else -2 + frame_summary = traceback.extract_stack(limit=-offset + limit - 1)[offset] return [frame_summary[:2]] def extract_tb(tb, limit=0): frames = traceback.extract_tb(tb, limit=limit) @@ -1209,7 +1308,7 @@ def _trim_arity(func, maxargs=2): # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!! this_line = extract_stack(limit=2)[-1] - pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF) + pa_call_line_synth = (this_line[0], this_line[1] + LINE_DIFF) def wrapper(*args): while 1: @@ -1227,7 +1326,10 @@ def _trim_arity(func, maxargs=2): if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: raise finally: - del tb + try: + del tb + except NameError: + pass if limit[0] <= maxargs: limit[0] += 1 @@ -1245,13 +1347,14 @@ def _trim_arity(func, maxargs=2): return wrapper + class ParserElement(object): """Abstract base level parser element class.""" DEFAULT_WHITE_CHARS = " \n\t\r" verbose_stacktrace = False @staticmethod - def setDefaultWhitespaceChars( chars ): + def setDefaultWhitespaceChars(chars): r""" Overrides the default whitespace chars @@ -1288,10 +1391,16 @@ class ParserElement(object): """ ParserElement._literalStringClass = cls - def __init__( self, savelist=False ): + @classmethod + def _trim_traceback(cls, tb): + while tb.tb_next: + tb = tb.tb_next + return tb + + def __init__(self, savelist=False): self.parseAction = list() self.failAction = None - #~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall + # ~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall self.strRepr = None self.resultsName = None self.saveAsList = savelist @@ -1306,12 +1415,12 @@ class ParserElement(object): self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index self.errmsg = "" self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) - self.debugActions = ( None, None, None ) #custom debug actions + self.debugActions = (None, None, None) # custom debug actions self.re = None self.callPreparse = True # used to avoid redundant calls to preParse self.callDuringTry = False - def copy( self ): + def copy(self): """ Make a copy of this :class:`ParserElement`. Useful for defining different parse actions for the same parsing pattern, using copies of @@ -1320,8 +1429,8 @@ class ParserElement(object): Example:: integer = Word(nums).setParseAction(lambda toks: int(toks[0])) - integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K") - integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + integerK = integer.copy().addParseAction(lambda toks: toks[0] * 1024) + Suppress("K") + integerM = integer.copy().addParseAction(lambda toks: toks[0] * 1024 * 1024) + Suppress("M") print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) @@ -1331,16 +1440,16 @@ class ParserElement(object): Equivalent form of ``expr.copy()`` is just ``expr()``:: - integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + integerM = integer().addParseAction(lambda toks: toks[0] * 1024 * 1024) + Suppress("M") """ - cpy = copy.copy( self ) + cpy = copy.copy(self) cpy.parseAction = self.parseAction[:] cpy.ignoreExprs = self.ignoreExprs[:] if self.copyDefaultWhiteChars: cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS return cpy - def setName( self, name ): + def setName(self, name): """ Define name for this expression, makes debugging and exception messages clearer. @@ -1351,11 +1460,11 @@ class ParserElement(object): """ self.name = name self.errmsg = "Expected " + self.name - if hasattr(self,"exception"): - self.exception.msg = self.errmsg + if __diag__.enable_debug_on_named_expressions: + self.setDebug() return self - def setResultsName( self, name, listAllMatches=False ): + def setResultsName(self, name, listAllMatches=False): """ Define name for referencing matching tokens as a nested attribute of the returned parse results. @@ -1376,15 +1485,18 @@ class ParserElement(object): # equivalent form: date_str = integer("year") + '/' + integer("month") + '/' + integer("day") """ + return self._setResultsName(name, listAllMatches) + + def _setResultsName(self, name, listAllMatches=False): newself = self.copy() if name.endswith("*"): name = name[:-1] - listAllMatches=True + listAllMatches = True newself.resultsName = name newself.modalResults = not listAllMatches return newself - def setBreak(self,breakFlag = True): + def setBreak(self, breakFlag=True): """Method to invoke the Python pdb debugger when this element is about to be parsed. Set ``breakFlag`` to True to enable, False to disable. @@ -1393,20 +1505,21 @@ class ParserElement(object): _parseMethod = self._parse def breaker(instring, loc, doActions=True, callPreParse=True): import pdb + # this call to pdb.set_trace() is intentional, not a checkin error pdb.set_trace() - return _parseMethod( instring, loc, doActions, callPreParse ) + return _parseMethod(instring, loc, doActions, callPreParse) breaker._originalParseMethod = _parseMethod self._parse = breaker else: - if hasattr(self._parse,"_originalParseMethod"): + if hasattr(self._parse, "_originalParseMethod"): self._parse = self._parse._originalParseMethod return self - def setParseAction( self, *fns, **kwargs ): + def setParseAction(self, *fns, **kwargs): """ Define one or more actions to perform when successfully matching parse element definition. - Parse action fn is a callable method with 0-3 arguments, called as ``fn(s,loc,toks)`` , - ``fn(loc,toks)`` , ``fn(toks)`` , or just ``fn()`` , where: + Parse action fn is a callable method with 0-3 arguments, called as ``fn(s, loc, toks)`` , + ``fn(loc, toks)`` , ``fn(toks)`` , or just ``fn()`` , where: - s = the original string being parsed (see note below) - loc = the location of the matching substring @@ -1416,8 +1529,11 @@ class ParserElement(object): value from fn, and the modified list of tokens will replace the original. Otherwise, fn does not need to return any value. + If None is passed as the parse action, all previously added parse actions for this + expression are cleared. + Optional keyword arguments: - - callDuringTry = (default= ``False`` ) indicate if parse action should be run during lookaheads and alternate testing + - callDuringTry = (default= ``False``) indicate if parse action should be run during lookaheads and alternate testing Note: the default parsing behavior is to expand tabs in the input string before starting the parsing process. See :class:`parseString for more @@ -1439,11 +1555,16 @@ class ParserElement(object): # note that integer fields are now ints, not strings date_str.parseString("1999/12/31") # -> [1999, '/', 12, '/', 31] """ - self.parseAction = list(map(_trim_arity, list(fns))) - self.callDuringTry = kwargs.get("callDuringTry", False) + if list(fns) == [None,]: + self.parseAction = [] + else: + if not all(callable(fn) for fn in fns): + raise TypeError("parse actions must be callable") + self.parseAction = list(map(_trim_arity, list(fns))) + self.callDuringTry = kwargs.get("callDuringTry", False) return self - def addParseAction( self, *fns, **kwargs ): + def addParseAction(self, *fns, **kwargs): """ Add one or more parse actions to expression's list of parse actions. See :class:`setParseAction`. @@ -1471,21 +1592,17 @@ class ParserElement(object): result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1) """ - msg = kwargs.get("message", "failed user-defined condition") - exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException for fn in fns: - fn = _trim_arity(fn) - def pa(s,l,t): - if not bool(fn(s,l,t)): - raise exc_type(s,l,msg) - self.parseAction.append(pa) + self.parseAction.append(conditionAsParseAction(fn, message=kwargs.get('message'), + fatal=kwargs.get('fatal', False))) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) return self - def setFailAction( self, fn ): + def setFailAction(self, fn): """Define action to perform if parsing fails at this expression. Fail acton fn is a callable function that takes the arguments - ``fn(s,loc,expr,err)`` where: + ``fn(s, loc, expr, err)`` where: - s = string being parsed - loc = location where expression match was attempted and failed - expr = the parse expression that failed @@ -1495,22 +1612,22 @@ class ParserElement(object): self.failAction = fn return self - def _skipIgnorables( self, instring, loc ): + def _skipIgnorables(self, instring, loc): exprsFound = True while exprsFound: exprsFound = False for e in self.ignoreExprs: try: while 1: - loc,dummy = e._parse( instring, loc ) + loc, dummy = e._parse(instring, loc) exprsFound = True except ParseException: pass return loc - def preParse( self, instring, loc ): + def preParse(self, instring, loc): if self.ignoreExprs: - loc = self._skipIgnorables( instring, loc ) + loc = self._skipIgnorables(instring, loc) if self.skipWhitespace: wt = self.whiteChars @@ -1520,101 +1637,105 @@ class ParserElement(object): return loc - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): return loc, [] - def postParse( self, instring, loc, tokenlist ): + def postParse(self, instring, loc, tokenlist): return tokenlist - #~ @profile - def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): - debugging = ( self.debug ) #and doActions ) + # ~ @profile + def _parseNoCache(self, instring, loc, doActions=True, callPreParse=True): + TRY, MATCH, FAIL = 0, 1, 2 + debugging = (self.debug) # and doActions) if debugging or self.failAction: - #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) - if (self.debugActions[0] ): - self.debugActions[0]( instring, loc, self ) - if callPreParse and self.callPreparse: - preloc = self.preParse( instring, loc ) - else: - preloc = loc - tokensStart = preloc + # ~ print ("Match", self, "at loc", loc, "(%d, %d)" % (lineno(loc, instring), col(loc, instring))) + if self.debugActions[TRY]: + self.debugActions[TRY](instring, loc, self) try: - try: - loc,tokens = self.parseImpl( instring, preloc, doActions ) - except IndexError: - raise ParseException( instring, len(instring), self.errmsg, self ) - except ParseBaseException as err: - #~ print ("Exception raised:", err) - if self.debugActions[2]: - self.debugActions[2]( instring, tokensStart, self, err ) + if callPreParse and self.callPreparse: + preloc = self.preParse(instring, loc) + else: + preloc = loc + tokensStart = preloc + if self.mayIndexError or preloc >= len(instring): + try: + loc, tokens = self.parseImpl(instring, preloc, doActions) + except IndexError: + raise ParseException(instring, len(instring), self.errmsg, self) + else: + loc, tokens = self.parseImpl(instring, preloc, doActions) + except Exception as err: + # ~ print ("Exception raised:", err) + if self.debugActions[FAIL]: + self.debugActions[FAIL](instring, tokensStart, self, err) if self.failAction: - self.failAction( instring, tokensStart, self, err ) + self.failAction(instring, tokensStart, self, err) raise else: if callPreParse and self.callPreparse: - preloc = self.preParse( instring, loc ) + preloc = self.preParse(instring, loc) else: preloc = loc tokensStart = preloc if self.mayIndexError or preloc >= len(instring): try: - loc,tokens = self.parseImpl( instring, preloc, doActions ) + loc, tokens = self.parseImpl(instring, preloc, doActions) except IndexError: - raise ParseException( instring, len(instring), self.errmsg, self ) + raise ParseException(instring, len(instring), self.errmsg, self) else: - loc,tokens = self.parseImpl( instring, preloc, doActions ) + loc, tokens = self.parseImpl(instring, preloc, doActions) - tokens = self.postParse( instring, loc, tokens ) + tokens = self.postParse(instring, loc, tokens) - retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) + retTokens = ParseResults(tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults) if self.parseAction and (doActions or self.callDuringTry): if debugging: try: for fn in self.parseAction: try: - tokens = fn( instring, tokensStart, retTokens ) + tokens = fn(instring, tokensStart, retTokens) except IndexError as parse_action_exc: exc = ParseException("exception raised in parse action") exc.__cause__ = parse_action_exc raise exc if tokens is not None and tokens is not retTokens: - retTokens = ParseResults( tokens, + retTokens = ParseResults(tokens, self.resultsName, - asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), - modal=self.modalResults ) - except ParseBaseException as err: - #~ print "Exception raised in user parse action:", err - if (self.debugActions[2] ): - self.debugActions[2]( instring, tokensStart, self, err ) + asList=self.saveAsList and isinstance(tokens, (ParseResults, list)), + modal=self.modalResults) + except Exception as err: + # ~ print "Exception raised in user parse action:", err + if self.debugActions[FAIL]: + self.debugActions[FAIL](instring, tokensStart, self, err) raise else: for fn in self.parseAction: try: - tokens = fn( instring, tokensStart, retTokens ) + tokens = fn(instring, tokensStart, retTokens) except IndexError as parse_action_exc: exc = ParseException("exception raised in parse action") exc.__cause__ = parse_action_exc raise exc if tokens is not None and tokens is not retTokens: - retTokens = ParseResults( tokens, + retTokens = ParseResults(tokens, self.resultsName, - asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), - modal=self.modalResults ) + asList=self.saveAsList and isinstance(tokens, (ParseResults, list)), + modal=self.modalResults) if debugging: - #~ print ("Matched",self,"->",retTokens.asList()) - if (self.debugActions[1] ): - self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) + # ~ print ("Matched", self, "->", retTokens.asList()) + if self.debugActions[MATCH]: + self.debugActions[MATCH](instring, tokensStart, loc, self, retTokens) return loc, retTokens - def tryParse( self, instring, loc ): + def tryParse(self, instring, loc): try: - return self._parse( instring, loc, doActions=False )[0] + return self._parse(instring, loc, doActions=False)[0] except ParseFatalException: - raise ParseException( instring, loc, self.errmsg, self) + raise ParseException(instring, loc, self.errmsg, self) def canParseNext(self, instring, loc): try: @@ -1711,7 +1832,7 @@ class ParserElement(object): # this method gets repeatedly called during backtracking with the same arguments - # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression - def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): + def _parseCache(self, instring, loc, doActions=True, callPreParse=True): HIT, MISS = 0, 1 lookup = (self, instring, loc, callPreParse, doActions) with ParserElement.packrat_cache_lock: @@ -1732,7 +1853,7 @@ class ParserElement(object): ParserElement.packrat_cache_stats[HIT] += 1 if isinstance(value, Exception): raise value - return (value[0], value[1].copy()) + return value[0], value[1].copy() _parse = _parseNoCache @@ -1777,12 +1898,16 @@ class ParserElement(object): ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) ParserElement._parse = ParserElement._parseCache - def parseString( self, instring, parseAll=False ): + def parseString(self, instring, parseAll=False): """ Execute the parse expression with the given string. This is the main interface to the client code, once the complete expression has been built. + Returns the parsed data as a :class:`ParseResults` object, which may be + accessed as a list, or as a dict or object with attributes if the given parser + includes results names. + If you want the grammar to require that the entire input string be successfully parsed, then set ``parseAll`` to True (equivalent to ending the grammar with ``StringEnd()``). @@ -1796,7 +1921,7 @@ class ParserElement(object): - calling ``parseWithTabs`` on your grammar before calling ``parseString`` (see :class:`parseWithTabs`) - - define your parse action using the full ``(s,loc,toks)`` signature, and + - define your parse action using the full ``(s, loc, toks)`` signature, and reference the input string using the parse action's ``s`` argument - explictly expand the tabs in your input string before calling ``parseString`` @@ -1809,27 +1934,29 @@ class ParserElement(object): ParserElement.resetCache() if not self.streamlined: self.streamline() - #~ self.saveAsList = True + # ~ self.saveAsList = True for e in self.ignoreExprs: e.streamline() if not self.keepTabs: instring = instring.expandtabs() try: - loc, tokens = self._parse( instring, 0 ) + loc, tokens = self._parse(instring, 0) if parseAll: - loc = self.preParse( instring, loc ) + loc = self.preParse(instring, loc) se = Empty() + StringEnd() - se._parse( instring, loc ) + se._parse(instring, loc) except ParseBaseException as exc: if ParserElement.verbose_stacktrace: raise else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace + # catch and re-raise exception from here, clearing out pyparsing internal stack trace + if getattr(exc, '__traceback__', None) is not None: + exc.__traceback__ = self._trim_traceback(exc.__traceback__) raise exc else: return tokens - def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ): + def scanString(self, instring, maxMatches=_MAX_INT, overlap=False): """ Scan the input string for expression matches. Each match will return the matching tokens, start location, and end location. May be called with optional @@ -1844,7 +1971,7 @@ class ParserElement(object): source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" print(source) - for tokens,start,end in Word(alphas).scanString(source): + for tokens, start, end in Word(alphas).scanString(source): print(' '*start + '^'*(end-start)) print(' '*start + tokens[0]) @@ -1876,16 +2003,16 @@ class ParserElement(object): try: while loc <= instrlen and matches < maxMatches: try: - preloc = preparseFn( instring, loc ) - nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + preloc = preparseFn(instring, loc) + nextLoc, tokens = parseFn(instring, preloc, callPreParse=False) except ParseException: - loc = preloc+1 + loc = preloc + 1 else: if nextLoc > loc: matches += 1 yield tokens, preloc, nextLoc if overlap: - nextloc = preparseFn( instring, loc ) + nextloc = preparseFn(instring, loc) if nextloc > loc: loc = nextLoc else: @@ -1893,15 +2020,17 @@ class ParserElement(object): else: loc = nextLoc else: - loc = preloc+1 + loc = preloc + 1 except ParseBaseException as exc: if ParserElement.verbose_stacktrace: raise else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace + # catch and re-raise exception from here, clearing out pyparsing internal stack trace + if getattr(exc, '__traceback__', None) is not None: + exc.__traceback__ = self._trim_traceback(exc.__traceback__) raise exc - def transformString( self, instring ): + def transformString(self, instring): """ Extension to :class:`scanString`, to modify matching text with modified tokens that may be returned from a parse action. To use ``transformString``, define a grammar and @@ -1927,27 +2056,29 @@ class ParserElement(object): # keep string locs straight between transformString and scanString self.keepTabs = True try: - for t,s,e in self.scanString( instring ): - out.append( instring[lastE:s] ) + for t, s, e in self.scanString(instring): + out.append(instring[lastE:s]) if t: - if isinstance(t,ParseResults): + if isinstance(t, ParseResults): out += t.asList() - elif isinstance(t,list): + elif isinstance(t, list): out += t else: out.append(t) lastE = e out.append(instring[lastE:]) out = [o for o in out if o] - return "".join(map(_ustr,_flatten(out))) + return "".join(map(_ustr, _flatten(out))) except ParseBaseException as exc: if ParserElement.verbose_stacktrace: raise else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace + # catch and re-raise exception from here, clearing out pyparsing internal stack trace + if getattr(exc, '__traceback__', None) is not None: + exc.__traceback__ = self._trim_traceback(exc.__traceback__) raise exc - def searchString( self, instring, maxMatches=_MAX_INT ): + def searchString(self, instring, maxMatches=_MAX_INT): """ Another extension to :class:`scanString`, simplifying the access to the tokens found to match the given parse expression. May be called with optional @@ -1969,12 +2100,14 @@ class ParserElement(object): ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] """ try: - return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) + return ParseResults([t for t, s, e in self.scanString(instring, maxMatches)]) except ParseBaseException as exc: if ParserElement.verbose_stacktrace: raise else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace + # catch and re-raise exception from here, clearing out pyparsing internal stack trace + if getattr(exc, '__traceback__', None) is not None: + exc.__traceback__ = self._trim_traceback(exc.__traceback__) raise exc def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): @@ -1995,14 +2128,14 @@ class ParserElement(object): """ splits = 0 last = 0 - for t,s,e in self.scanString(instring, maxMatches=maxsplit): + for t, s, e in self.scanString(instring, maxMatches=maxsplit): yield instring[last:s] if includeSeparators: yield t[0] last = e yield instring[last:] - def __add__(self, other ): + def __add__(self, other): """ Implementation of + operator - returns :class:`And`. Adding strings to a ParserElement converts them to :class:`Literal`s by default. @@ -2016,24 +2149,42 @@ class ParserElement(object): prints:: Hello, World! -> ['Hello', ',', 'World', '!'] - """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return And( [ self, other ] ) - def __radd__(self, other ): + ``...`` may be used as a parse expression as a short form of :class:`SkipTo`. + + Literal('start') + ... + Literal('end') + + is equivalent to: + + Literal('start') + SkipTo('end')("_skipped*") + Literal('end') + + Note that the skipped text is returned with '_skipped' as a results name, + and to support having multiple skips in the same parser, the value returned is + a list of all skipped text. + """ + if other is Ellipsis: + return _PendingSkip(self) + + if isinstance(other, basestring): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And([self, other]) + + def __radd__(self, other): """ Implementation of + operator when left operand is not a :class:`ParserElement` """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): + if other is Ellipsis: + return SkipTo(self)("_skipped*") + self + + if isinstance(other, basestring): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) return None return other + self @@ -2041,64 +2192,70 @@ class ParserElement(object): """ Implementation of - operator, returns :class:`And` with error stop """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): + if isinstance(other, basestring): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) return None return self + And._ErrorStop() + other - def __rsub__(self, other ): + def __rsub__(self, other): """ Implementation of - operator when left operand is not a :class:`ParserElement` """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): + if isinstance(other, basestring): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) return None return other - self - def __mul__(self,other): + def __mul__(self, other): """ Implementation of * operator, allows use of ``expr * 3`` in place of ``expr + expr + expr``. Expressions may also me multiplied by a 2-integer - tuple, similar to ``{min,max}`` multipliers in regular expressions. Tuples + tuple, similar to ``{min, max}`` multipliers in regular expressions. Tuples may also include ``None`` as in: - - ``expr*(n,None)`` or ``expr*(n,)`` is equivalent + - ``expr*(n, None)`` or ``expr*(n, )`` is equivalent to ``expr*n + ZeroOrMore(expr)`` (read as "at least n instances of ``expr``") - - ``expr*(None,n)`` is equivalent to ``expr*(0,n)`` + - ``expr*(None, n)`` is equivalent to ``expr*(0, n)`` (read as "0 to n instances of ``expr``") - - ``expr*(None,None)`` is equivalent to ``ZeroOrMore(expr)`` - - ``expr*(1,None)`` is equivalent to ``OneOrMore(expr)`` + - ``expr*(None, None)`` is equivalent to ``ZeroOrMore(expr)`` + - ``expr*(1, None)`` is equivalent to ``OneOrMore(expr)`` - Note that ``expr*(None,n)`` does not raise an exception if + Note that ``expr*(None, n)`` does not raise an exception if more than n exprs exist in the input stream; that is, - ``expr*(None,n)`` does not enforce a maximum number of expr + ``expr*(None, n)`` does not enforce a maximum number of expr occurrences. If this behavior is desired, then write - ``expr*(None,n) + ~expr`` + ``expr*(None, n) + ~expr`` """ - if isinstance(other,int): - minElements, optElements = other,0 - elif isinstance(other,tuple): + if other is Ellipsis: + other = (0, None) + elif isinstance(other, tuple) and other[:1] == (Ellipsis,): + other = ((0, ) + other[1:] + (None,))[:2] + + if isinstance(other, int): + minElements, optElements = other, 0 + elif isinstance(other, tuple): + other = tuple(o if o is not Ellipsis else None for o in other) other = (other + (None, None))[:2] if other[0] is None: other = (0, other[1]) - if isinstance(other[0],int) and other[1] is None: + if isinstance(other[0], int) and other[1] is None: if other[0] == 0: return ZeroOrMore(self) if other[0] == 1: return OneOrMore(self) else: - return self*other[0] + ZeroOrMore(self) - elif isinstance(other[0],int) and isinstance(other[1],int): + return self * other[0] + ZeroOrMore(self) + elif isinstance(other[0], int) and isinstance(other[1], int): minElements, optElements = other optElements -= minElements else: - raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) + raise TypeError("cannot multiply 'ParserElement' and ('%s', '%s') objects", type(other[0]), type(other[1])) else: raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) @@ -2107,108 +2264,152 @@ class ParserElement(object): if optElements < 0: raise ValueError("second tuple value must be greater or equal to first tuple value") if minElements == optElements == 0: - raise ValueError("cannot multiply ParserElement by 0 or (0,0)") + raise ValueError("cannot multiply ParserElement by 0 or (0, 0)") - if (optElements): + if optElements: def makeOptionalList(n): - if n>1: - return Optional(self + makeOptionalList(n-1)) + if n > 1: + return Optional(self + makeOptionalList(n - 1)) else: return Optional(self) if minElements: if minElements == 1: ret = self + makeOptionalList(optElements) else: - ret = And([self]*minElements) + makeOptionalList(optElements) + ret = And([self] * minElements) + makeOptionalList(optElements) else: ret = makeOptionalList(optElements) else: if minElements == 1: ret = self else: - ret = And([self]*minElements) + ret = And([self] * minElements) return ret def __rmul__(self, other): return self.__mul__(other) - def __or__(self, other ): + def __or__(self, other): """ Implementation of | operator - returns :class:`MatchFirst` """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): - warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) - return None - return MatchFirst( [ self, other ] ) + if other is Ellipsis: + return _PendingSkip(self, must_skip=True) - def __ror__(self, other ): + if isinstance(other, basestring): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return MatchFirst([self, other]) + + def __ror__(self, other): """ Implementation of | operator when left operand is not a :class:`ParserElement` """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): + if isinstance(other, basestring): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) return None return other | self - def __xor__(self, other ): + def __xor__(self, other): """ Implementation of ^ operator - returns :class:`Or` """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): + if isinstance(other, basestring): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) return None - return Or( [ self, other ] ) + return Or([self, other]) - def __rxor__(self, other ): + def __rxor__(self, other): """ Implementation of ^ operator when left operand is not a :class:`ParserElement` """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): + if isinstance(other, basestring): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) return None return other ^ self - def __and__(self, other ): + def __and__(self, other): """ Implementation of & operator - returns :class:`Each` """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): + if isinstance(other, basestring): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) return None - return Each( [ self, other ] ) + return Each([self, other]) - def __rand__(self, other ): + def __rand__(self, other): """ Implementation of & operator when left operand is not a :class:`ParserElement` """ - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - if not isinstance( other, ParserElement ): + if isinstance(other, basestring): + other = self._literalStringClass(other) + if not isinstance(other, ParserElement): warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) return None return other & self - def __invert__( self ): + def __invert__(self): """ Implementation of ~ operator - returns :class:`NotAny` """ - return NotAny( self ) + return NotAny(self) + + def __iter__(self): + # must implement __iter__ to override legacy use of sequential access to __getitem__ to + # iterate over a sequence + raise TypeError('%r object is not iterable' % self.__class__.__name__) + + def __getitem__(self, key): + """ + use ``[]`` indexing notation as a short form for expression repetition: + - ``expr[n]`` is equivalent to ``expr*n`` + - ``expr[m, n]`` is equivalent to ``expr*(m, n)`` + - ``expr[n, ...]`` or ``expr[n,]`` is equivalent + to ``expr*n + ZeroOrMore(expr)`` + (read as "at least n instances of ``expr``") + - ``expr[..., n]`` is equivalent to ``expr*(0, n)`` + (read as "0 to n instances of ``expr``") + - ``expr[...]`` and ``expr[0, ...]`` are equivalent to ``ZeroOrMore(expr)`` + - ``expr[1, ...]`` is equivalent to ``OneOrMore(expr)`` + ``None`` may be used in place of ``...``. + + Note that ``expr[..., n]`` and ``expr[m, n]``do not raise an exception + if more than ``n`` ``expr``s exist in the input stream. If this behavior is + desired, then write ``expr[..., n] + ~expr``. + """ + + # convert single arg keys to tuples + try: + if isinstance(key, str): + key = (key,) + iter(key) + except TypeError: + key = (key, key) + + if len(key) > 2: + warnings.warn("only 1 or 2 index arguments supported ({0}{1})".format(key[:5], + '... [{0}]'.format(len(key)) + if len(key) > 5 else '')) + + # clip to 2 elements + ret = self * tuple(key[:2]) + return ret def __call__(self, name=None): """ @@ -2222,22 +2423,22 @@ class ParserElement(object): Example:: # these are equivalent - userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") - userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") + userdata = Word(alphas).setResultsName("name") + Word(nums + "-").setResultsName("socsecno") + userdata = Word(alphas)("name") + Word(nums + "-")("socsecno") """ if name is not None: - return self.setResultsName(name) + return self._setResultsName(name) else: return self.copy() - def suppress( self ): + def suppress(self): """ Suppresses the output of this :class:`ParserElement`; useful to keep punctuation from cluttering up returned output. """ - return Suppress( self ) + return Suppress(self) - def leaveWhitespace( self ): + def leaveWhitespace(self): """ Disables the skipping of whitespace before matching the characters in the :class:`ParserElement`'s defined pattern. This is normally only used internally by @@ -2246,7 +2447,7 @@ class ParserElement(object): self.skipWhitespace = False return self - def setWhitespaceChars( self, chars ): + def setWhitespaceChars(self, chars): """ Overrides the default whitespace chars """ @@ -2255,7 +2456,7 @@ class ParserElement(object): self.copyDefaultWhiteChars = False return self - def parseWithTabs( self ): + def parseWithTabs(self): """ Overrides default behavior to expand ``<TAB>``s to spaces before parsing the input string. Must be called before ``parseString`` when the input grammar contains elements that @@ -2264,7 +2465,7 @@ class ParserElement(object): self.keepTabs = True return self - def ignore( self, other ): + def ignore(self, other): """ Define expression to be ignored (e.g., comments) while doing pattern matching; may be called repeatedly, to define multiple comment or other @@ -2281,14 +2482,14 @@ class ParserElement(object): if isinstance(other, basestring): other = Suppress(other) - if isinstance( other, Suppress ): + if isinstance(other, Suppress): if other not in self.ignoreExprs: self.ignoreExprs.append(other) else: - self.ignoreExprs.append( Suppress( other.copy() ) ) + self.ignoreExprs.append(Suppress(other.copy())) return self - def setDebugActions( self, startAction, successAction, exceptionAction ): + def setDebugActions(self, startAction, successAction, exceptionAction): """ Enable display of debugging messages while doing pattern matching. """ @@ -2298,7 +2499,7 @@ class ParserElement(object): self.debug = True return self - def setDebug( self, flag=True ): + def setDebug(self, flag=True): """ Enable display of debugging messages while doing pattern matching. Set ``flag`` to True to enable, False to disable. @@ -2336,32 +2537,32 @@ class ParserElement(object): name created for the :class:`Word` expression without calling ``setName`` is ``"W:(ABCD...)"``. """ if flag: - self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + self.setDebugActions(_defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction) else: self.debug = False return self - def __str__( self ): + def __str__(self): return self.name - def __repr__( self ): + def __repr__(self): return _ustr(self) - def streamline( self ): + def streamline(self): self.streamlined = True self.strRepr = None return self - def checkRecursion( self, parseElementList ): + def checkRecursion(self, parseElementList): pass - def validate( self, validateTrace=[] ): + def validate(self, validateTrace=None): """ Check defined expressions for valid structure, check for infinite recursive definitions. """ - self.checkRecursion( [] ) + self.checkRecursion([]) - def parseFile( self, file_or_filename, parseAll=False ): + def parseFile(self, file_or_filename, parseAll=False): """ Execute the parse expression on the given file or filename. If a filename is specified (instead of a file object), @@ -2378,27 +2579,30 @@ class ParserElement(object): if ParserElement.verbose_stacktrace: raise else: - # catch and re-raise exception from here, clears out pyparsing internal stack trace + # catch and re-raise exception from here, clearing out pyparsing internal stack trace + if getattr(exc, '__traceback__', None) is not None: + exc.__traceback__ = self._trim_traceback(exc.__traceback__) raise exc - def __eq__(self,other): - if isinstance(other, ParserElement): - return self is other or vars(self) == vars(other) + def __eq__(self, other): + if self is other: + return True elif isinstance(other, basestring): return self.matches(other) - else: - return super(ParserElement,self)==other + elif isinstance(other, ParserElement): + return vars(self) == vars(other) + return False - def __ne__(self,other): + def __ne__(self, other): return not (self == other) def __hash__(self): - return hash(id(self)) + return id(self) - def __req__(self,other): + def __req__(self, other): return self == other - def __rne__(self,other): + def __rne__(self, other): return not (self == other) def matches(self, testString, parseAll=True): @@ -2422,7 +2626,8 @@ class ParserElement(object): return False def runTests(self, tests, parseAll=True, comment='#', - fullDump=True, printResults=True, failureTests=False, postParse=None): + fullDump=True, printResults=True, failureTests=False, postParse=None, + file=None): """ Execute the parse expression on a series of test strings, showing each test, the parsed results or where the parse failed. Quick and easy way to @@ -2439,6 +2644,8 @@ class ParserElement(object): - failureTests - (default= ``False``) indicates if these tests are expected to fail parsing - postParse - (default= ``None``) optional callback for successful parse results; called as `fn(test_string, parse_results)` and returns a string to be added to the test output + - file - (default=``None``) optional file-like object to which test output will be written; + if None, will default to ``sys.stdout`` Returns: a (success, results) tuple, where success indicates that all tests succeeded (or failed if ``failureTests`` is True), and the results contain a list of lines of each @@ -2518,39 +2725,34 @@ class ParserElement(object): tests = list(map(str.strip, tests.rstrip().splitlines())) if isinstance(comment, basestring): comment = Literal(comment) + if file is None: + file = sys.stdout + print_ = file.write + allResults = [] comments = [] success = True + NL = Literal(r'\n').addParseAction(replaceWith('\n')).ignore(quotedString) + BOM = u'\ufeff' for t in tests: if comment is not None and comment.matches(t, False) or comments and not t: comments.append(t) continue if not t: continue - out = ['\n'.join(comments), t] + out = ['\n' + '\n'.join(comments) if comments else '', t] comments = [] try: # convert newline marks to actual newlines, and strip leading BOM if present - NL = Literal(r'\n').addParseAction(replaceWith('\n')).ignore(quotedString) - BOM = '\ufeff' t = NL.transformString(t.lstrip(BOM)) result = self.parseString(t, parseAll=parseAll) - out.append(result.dump(full=fullDump)) - success = success and not failureTests - if postParse is not None: - try: - pp_value = postParse(t, result) - if pp_value is not None: - out.append(str(pp_value)) - except Exception as e: - out.append("{0} failed: {1}: {2}".format(postParse.__name__, type(e).__name__, e)) except ParseBaseException as pe: fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else "" if '\n' in t: out.append(line(pe.loc, t)) - out.append(' '*(col(pe.loc,t)-1) + '^' + fatal) + out.append(' ' * (col(pe.loc, t) - 1) + '^' + fatal) else: - out.append(' '*pe.loc + '^' + fatal) + out.append(' ' * pe.loc + '^' + fatal) out.append("FAIL: " + str(pe)) success = success and failureTests result = pe @@ -2558,30 +2760,80 @@ class ParserElement(object): out.append("FAIL-EXCEPTION: " + str(exc)) success = success and failureTests result = exc + else: + success = success and not failureTests + if postParse is not None: + try: + pp_value = postParse(t, result) + if pp_value is not None: + if isinstance(pp_value, ParseResults): + out.append(pp_value.dump()) + else: + out.append(str(pp_value)) + else: + out.append(result.dump()) + except Exception as e: + out.append(result.dump(full=fullDump)) + out.append("{0} failed: {1}: {2}".format(postParse.__name__, type(e).__name__, e)) + else: + out.append(result.dump(full=fullDump)) if printResults: if fullDump: out.append('') - print('\n'.join(out)) + print_('\n'.join(out)) allResults.append((t, result)) return success, allResults +class _PendingSkip(ParserElement): + # internal placeholder class to hold a place were '...' is added to a parser element, + # once another ParserElement is added, this placeholder will be replaced with a SkipTo + def __init__(self, expr, must_skip=False): + super(_PendingSkip, self).__init__() + self.strRepr = str(expr + Empty()).replace('Empty', '...') + self.name = self.strRepr + self.anchor = expr + self.must_skip = must_skip + + def __add__(self, other): + skipper = SkipTo(other).setName("...")("_skipped*") + if self.must_skip: + def must_skip(t): + if not t._skipped or t._skipped.asList() == ['']: + del t[0] + t.pop("_skipped", None) + def show_skip(t): + if t._skipped.asList()[-1:] == ['']: + skipped = t.pop('_skipped') + t['_skipped'] = 'missing <' + repr(self.anchor) + '>' + return (self.anchor + skipper().addParseAction(must_skip) + | skipper().addParseAction(show_skip)) + other + + return self.anchor + skipper + other + + def __repr__(self): + return self.strRepr + + def parseImpl(self, *args): + raise Exception("use of `...` expression without following SkipTo target expression") + + class Token(ParserElement): """Abstract :class:`ParserElement` subclass, for defining atomic matching patterns. """ - def __init__( self ): - super(Token,self).__init__( savelist=False ) + def __init__(self): + super(Token, self).__init__(savelist=False) class Empty(Token): """An empty token, will always match. """ - def __init__( self ): - super(Empty,self).__init__() + def __init__(self): + super(Empty, self).__init__() self.name = "Empty" self.mayReturnEmpty = True self.mayIndexError = False @@ -2590,14 +2842,14 @@ class Empty(Token): class NoMatch(Token): """A token that will never match. """ - def __init__( self ): - super(NoMatch,self).__init__() + def __init__(self): + super(NoMatch, self).__init__() self.name = "NoMatch" self.mayReturnEmpty = True self.mayIndexError = False self.errmsg = "Unmatchable token" - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): raise ParseException(instring, loc, self.errmsg, self) @@ -2615,8 +2867,8 @@ class Literal(Token): For keyword matching (force word break before and after the matched string), use :class:`Keyword` or :class:`CaselessKeyword`. """ - def __init__( self, matchString ): - super(Literal,self).__init__() + def __init__(self, matchString): + super(Literal, self).__init__() self.match = matchString self.matchLen = len(matchString) try: @@ -2630,15 +2882,22 @@ class Literal(Token): self.mayReturnEmpty = False self.mayIndexError = False - # Performance tuning: this routine gets called a *lot* - # if this is a single character match string and the first character matches, - # short-circuit as quickly as possible, and avoid calling startswith - #~ @profile - def parseImpl( self, instring, loc, doActions=True ): - if (instring[loc] == self.firstMatchChar and - (self.matchLen==1 or instring.startswith(self.match,loc)) ): - return loc+self.matchLen, self.match + # Performance tuning: modify __class__ to select + # a parseImpl optimized for single-character check + if self.matchLen == 1 and type(self) is Literal: + self.__class__ = _SingleCharLiteral + + def parseImpl(self, instring, loc, doActions=True): + if instring[loc] == self.firstMatchChar and instring.startswith(self.match, loc): + return loc + self.matchLen, self.match raise ParseException(instring, loc, self.errmsg, self) + +class _SingleCharLiteral(Literal): + def parseImpl(self, instring, loc, doActions=True): + if instring[loc] == self.firstMatchChar: + return loc + 1, self.match + raise ParseException(instring, loc, self.errmsg, self) + _L = Literal ParserElement._literalStringClass = Literal @@ -2667,10 +2926,10 @@ class Keyword(Token): For case-insensitive matching, use :class:`CaselessKeyword`. """ - DEFAULT_KEYWORD_CHARS = alphanums+"_$" + DEFAULT_KEYWORD_CHARS = alphanums + "_$" - def __init__( self, matchString, identChars=None, caseless=False ): - super(Keyword,self).__init__() + def __init__(self, matchString, identChars=None, caseless=False): + super(Keyword, self).__init__() if identChars is None: identChars = Keyword.DEFAULT_KEYWORD_CHARS self.match = matchString @@ -2679,7 +2938,7 @@ class Keyword(Token): self.firstMatchChar = matchString[0] except IndexError: warnings.warn("null string passed to Keyword; use Empty() instead", - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) self.name = '"%s"' % self.match self.errmsg = "Expected " + self.name self.mayReturnEmpty = False @@ -2690,27 +2949,32 @@ class Keyword(Token): identChars = identChars.upper() self.identChars = set(identChars) - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): if self.caseless: - if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and - (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and - (loc == 0 or instring[loc-1].upper() not in self.identChars) ): - return loc+self.matchLen, self.match + if ((instring[loc:loc + self.matchLen].upper() == self.caselessmatch) + and (loc >= len(instring) - self.matchLen + or instring[loc + self.matchLen].upper() not in self.identChars) + and (loc == 0 + or instring[loc - 1].upper() not in self.identChars)): + return loc + self.matchLen, self.match + else: - if (instring[loc] == self.firstMatchChar and - (self.matchLen==1 or instring.startswith(self.match,loc)) and - (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and - (loc == 0 or instring[loc-1] not in self.identChars) ): - return loc+self.matchLen, self.match + if instring[loc] == self.firstMatchChar: + if ((self.matchLen == 1 or instring.startswith(self.match, loc)) + and (loc >= len(instring) - self.matchLen + or instring[loc + self.matchLen] not in self.identChars) + and (loc == 0 or instring[loc - 1] not in self.identChars)): + return loc + self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) def copy(self): - c = super(Keyword,self).copy() + c = super(Keyword, self).copy() c.identChars = Keyword.DEFAULT_KEYWORD_CHARS return c @staticmethod - def setDefaultKeywordChars( chars ): + def setDefaultKeywordChars(chars): """Overrides the default Keyword chars """ Keyword.DEFAULT_KEYWORD_CHARS = chars @@ -2726,16 +2990,16 @@ class CaselessLiteral(Literal): (Contrast with example for :class:`CaselessKeyword`.) """ - def __init__( self, matchString ): - super(CaselessLiteral,self).__init__( matchString.upper() ) + def __init__(self, matchString): + super(CaselessLiteral, self).__init__(matchString.upper()) # Preserve the defining literal. self.returnString = matchString self.name = "'%s'" % self.returnString self.errmsg = "Expected " + self.name - def parseImpl( self, instring, loc, doActions=True ): - if instring[ loc:loc+self.matchLen ].upper() == self.match: - return loc+self.matchLen, self.returnString + def parseImpl(self, instring, loc, doActions=True): + if instring[loc:loc + self.matchLen].upper() == self.match: + return loc + self.matchLen, self.returnString raise ParseException(instring, loc, self.errmsg, self) class CaselessKeyword(Keyword): @@ -2748,8 +3012,8 @@ class CaselessKeyword(Keyword): (Contrast with example for :class:`CaselessLiteral`.) """ - def __init__( self, matchString, identChars=None ): - super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + def __init__(self, matchString, identChars=None): + super(CaselessKeyword, self).__init__(matchString, identChars, caseless=True) class CloseMatch(Token): """A variation on :class:`Literal` which matches "close" matches, @@ -2785,7 +3049,7 @@ class CloseMatch(Token): patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) """ def __init__(self, match_string, maxMismatches=1): - super(CloseMatch,self).__init__() + super(CloseMatch, self).__init__() self.name = match_string self.match_string = match_string self.maxMismatches = maxMismatches @@ -2793,7 +3057,7 @@ class CloseMatch(Token): self.mayIndexError = False self.mayReturnEmpty = False - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): start = loc instrlen = len(instring) maxloc = start + len(self.match_string) @@ -2804,8 +3068,8 @@ class CloseMatch(Token): mismatches = [] maxMismatches = self.maxMismatches - for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): - src,mat = s_m + for match_stringloc, s_m in enumerate(zip(instring[loc:maxloc], match_string)): + src, mat = s_m if src != mat: mismatches.append(match_stringloc) if len(mismatches) > maxMismatches: @@ -2813,7 +3077,7 @@ class CloseMatch(Token): else: loc = match_stringloc + 1 results = ParseResults([instring[start:loc]]) - results['original'] = self.match_string + results['original'] = match_string results['mismatches'] = mismatches return loc, results @@ -2865,7 +3129,7 @@ class Word(Token): capital_word = Word(alphas.upper(), alphas.lower()) # hostnames are alphanumeric, with leading alpha, and '-' - hostname = Word(alphas, alphanums+'-') + hostname = Word(alphas, alphanums + '-') # roman numeral (not a strict parser, accepts invalid mix of characters) roman = Word("IVXLCDM") @@ -2873,8 +3137,8 @@ class Word(Token): # any string of non-whitespace characters, except for ',' csv_value = Word(printables, excludeChars=",") """ - def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ): - super(Word,self).__init__() + def __init__(self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None): + super(Word, self).__init__() if excludeChars: excludeChars = set(excludeChars) initChars = ''.join(c for c in initChars if c not in excludeChars) @@ -2882,7 +3146,7 @@ class Word(Token): bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) self.initCharsOrig = initChars self.initChars = set(initChars) - if bodyChars : + if bodyChars: self.bodyCharsOrig = bodyChars self.bodyChars = set(bodyChars) else: @@ -2910,33 +3174,27 @@ class Word(Token): self.mayIndexError = False self.asKeyword = asKeyword - if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): + if ' ' not in self.initCharsOrig + self.bodyCharsOrig and (min == 1 and max == 0 and exact == 0): if self.bodyCharsOrig == self.initCharsOrig: self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) elif len(self.initCharsOrig) == 1: - self.reString = "%s[%s]*" % \ - (re.escape(self.initCharsOrig), - _escapeRegexRangeChars(self.bodyCharsOrig),) + self.reString = "%s[%s]*" % (re.escape(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) else: - self.reString = "[%s][%s]*" % \ - (_escapeRegexRangeChars(self.initCharsOrig), - _escapeRegexRangeChars(self.bodyCharsOrig),) + self.reString = "[%s][%s]*" % (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) if self.asKeyword: - self.reString = r"\b"+self.reString+r"\b" + self.reString = r"\b" + self.reString + r"\b" + try: - self.re = re.compile( self.reString ) + self.re = re.compile(self.reString) except Exception: self.re = None + else: + self.re_match = self.re.match + self.__class__ = _WordRegex - def parseImpl( self, instring, loc, doActions=True ): - if self.re: - result = self.re.match(instring,loc) - if not result: - raise ParseException(instring, loc, self.errmsg, self) - - loc = result.end() - return loc, result.group() - + def parseImpl(self, instring, loc, doActions=True): if instring[loc] not in self.initChars: raise ParseException(instring, loc, self.errmsg, self) @@ -2945,7 +3203,7 @@ class Word(Token): instrlen = len(instring) bodychars = self.bodyChars maxloc = start + self.maxLen - maxloc = min( maxloc, instrlen ) + maxloc = min(maxloc, instrlen) while loc < maxloc and instring[loc] in bodychars: loc += 1 @@ -2955,7 +3213,8 @@ class Word(Token): elif self.maxSpecified and loc < instrlen and instring[loc] in bodychars: throwException = True elif self.asKeyword: - if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars): + if (start > 0 and instring[start - 1] in bodychars + or loc < instrlen and instring[loc] in bodychars): throwException = True if throwException: @@ -2963,38 +3222,49 @@ class Word(Token): return loc, instring[start:loc] - def __str__( self ): + def __str__(self): try: - return super(Word,self).__str__() + return super(Word, self).__str__() except Exception: pass - if self.strRepr is None: def charsAsStr(s): - if len(s)>4: - return s[:4]+"..." + if len(s) > 4: + return s[:4] + "..." else: return s - if ( self.initCharsOrig != self.bodyCharsOrig ): - self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) + if self.initCharsOrig != self.bodyCharsOrig: + self.strRepr = "W:(%s, %s)" % (charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig)) else: self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) return self.strRepr +class _WordRegex(Word): + def parseImpl(self, instring, loc, doActions=True): + result = self.re_match(instring, loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) -class Char(Word): + loc = result.end() + return loc, result.group() + + +class Char(_WordRegex): """A short-cut class for defining ``Word(characters, exact=1)``, when defining a match of any single character in a string of characters. """ def __init__(self, charset, asKeyword=False, excludeChars=None): super(Char, self).__init__(charset, exact=1, asKeyword=asKeyword, excludeChars=excludeChars) - self.reString = "[%s]" % _escapeRegexRangeChars(self.initCharsOrig) - self.re = re.compile( self.reString ) + self.reString = "[%s]" % _escapeRegexRangeChars(''.join(self.initChars)) + if asKeyword: + self.reString = r"\b%s\b" % self.reString + self.re = re.compile(self.reString) + self.re_match = self.re.match class Regex(Token): @@ -3004,26 +3274,35 @@ class Regex(Token): If the given regex contains named groups (defined using ``(?P<name>...)``), these will be preserved as named parse results. + If instead of the Python stdlib re module you wish to use a different RE module + (such as the `regex` module), you can replace it by either building your + Regex object with a compiled RE that was compiled using regex: + Example:: realnum = Regex(r"[+-]?\d+\.\d*") date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') # ref: https://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression roman = Regex(r"M{0,4}(CM|CD|D?{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") + + # use regex module instead of stdlib re module to construct a Regex using + # a compiled regular expression + import regex + parser = pp.Regex(regex.compile(r'[0-9]')) + """ - compiledREtype = type(re.compile("[A-Z]")) - def __init__( self, pattern, flags=0, asGroupList=False, asMatch=False): + def __init__(self, pattern, flags=0, asGroupList=False, asMatch=False): """The parameters ``pattern`` and ``flags`` are passed to the ``re.compile()`` function as-is. See the Python `re module <https://docs.python.org/3/library/re.html>`_ module for an explanation of the acceptable patterns and flags. """ - super(Regex,self).__init__() + super(Regex, self).__init__() if isinstance(pattern, basestring): if not pattern: warnings.warn("null string passed to Regex; use Empty() instead", - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) self.pattern = pattern self.flags = flags @@ -3033,22 +3312,23 @@ class Regex(Token): self.reString = self.pattern except sre_constants.error: warnings.warn("invalid pattern (%s) passed to Regex" % pattern, - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) raise - elif isinstance(pattern, Regex.compiledREtype): + elif hasattr(pattern, 'pattern') and hasattr(pattern, 'match'): self.re = pattern - self.pattern = \ - self.reString = str(pattern) + self.pattern = self.reString = pattern.pattern self.flags = flags else: - raise ValueError("Regex may only be constructed with a string or a compiled RE object") + raise TypeError("Regex may only be constructed with a string or a compiled RE object") + + self.re_match = self.re.match self.name = _ustr(self) self.errmsg = "Expected " + self.name self.mayIndexError = False - self.mayReturnEmpty = True + self.mayReturnEmpty = self.re_match("") is not None self.asGroupList = asGroupList self.asMatch = asMatch if self.asGroupList: @@ -3057,7 +3337,7 @@ class Regex(Token): self.parseImpl = self.parseImplAsMatch def parseImpl(self, instring, loc, doActions=True): - result = self.re.match(instring,loc) + result = self.re_match(instring, loc) if not result: raise ParseException(instring, loc, self.errmsg, self) @@ -3070,7 +3350,7 @@ class Regex(Token): return loc, ret def parseImplAsGroupList(self, instring, loc, doActions=True): - result = self.re.match(instring,loc) + result = self.re_match(instring, loc) if not result: raise ParseException(instring, loc, self.errmsg, self) @@ -3079,7 +3359,7 @@ class Regex(Token): return loc, ret def parseImplAsMatch(self, instring, loc, doActions=True): - result = self.re.match(instring,loc) + result = self.re_match(instring, loc) if not result: raise ParseException(instring, loc, self.errmsg, self) @@ -3087,9 +3367,9 @@ class Regex(Token): ret = result return loc, ret - def __str__( self ): + def __str__(self): try: - return super(Regex,self).__str__() + return super(Regex, self).__str__() except Exception: pass @@ -3111,12 +3391,12 @@ class Regex(Token): """ if self.asGroupList: warnings.warn("cannot use sub() with Regex(asGroupList=True)", - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) raise SyntaxError() if self.asMatch and callable(repl): warnings.warn("cannot use sub() with a callable with Regex(asMatch=True)", - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) raise SyntaxError() if self.asMatch: @@ -3136,20 +3416,20 @@ class QuotedString(Token): - quoteChar - string of one or more characters defining the quote delimiting string - escChar - character to escape quotes, typically backslash - (default= ``None`` ) + (default= ``None``) - escQuote - special quote sequence to escape an embedded quote string (such as SQL's ``""`` to escape an embedded ``"``) - (default= ``None`` ) + (default= ``None``) - multiline - boolean indicating whether quotes can span - multiple lines (default= ``False`` ) + multiple lines (default= ``False``) - unquoteResults - boolean indicating whether the matched text - should be unquoted (default= ``True`` ) + should be unquoted (default= ``True``) - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default= ``None`` => same as quoteChar) - convertWhitespaceEscapes - convert escaped whitespace (``'\t'``, ``'\n'``, etc.) to actual whitespace - (default= ``True`` ) + (default= ``True``) Example:: @@ -3166,13 +3446,14 @@ class QuotedString(Token): [['This is the "quote"']] [['This is the quote with "embedded" quotes']] """ - def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True): - super(QuotedString,self).__init__() + def __init__(self, quoteChar, escChar=None, escQuote=None, multiline=False, + unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True): + super(QuotedString, self).__init__() # remove white space from quote chars - wont work anyway quoteChar = quoteChar.strip() if not quoteChar: - warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + warnings.warn("quoteChar cannot be the empty string", SyntaxWarning, stacklevel=2) raise SyntaxError() if endQuoteChar is None: @@ -3180,7 +3461,7 @@ class QuotedString(Token): else: endQuoteChar = endQuoteChar.strip() if not endQuoteChar: - warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + warnings.warn("endQuoteChar cannot be the empty string", SyntaxWarning, stacklevel=2) raise SyntaxError() self.quoteChar = quoteChar @@ -3195,35 +3476,34 @@ class QuotedString(Token): if multiline: self.flags = re.MULTILINE | re.DOTALL - self.pattern = r'%s(?:[^%s%s]' % \ - ( re.escape(self.quoteChar), - _escapeRegexRangeChars(self.endQuoteChar[0]), - (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + self.pattern = r'%s(?:[^%s%s]' % (re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '')) else: self.flags = 0 - self.pattern = r'%s(?:[^%s\n\r%s]' % \ - ( re.escape(self.quoteChar), - _escapeRegexRangeChars(self.endQuoteChar[0]), - (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + self.pattern = r'%s(?:[^%s\n\r%s]' % (re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '')) if len(self.endQuoteChar) > 1: self.pattern += ( '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]), - _escapeRegexRangeChars(self.endQuoteChar[i])) - for i in range(len(self.endQuoteChar)-1,0,-1)) + ')' - ) + _escapeRegexRangeChars(self.endQuoteChar[i])) + for i in range(len(self.endQuoteChar) - 1, 0, -1)) + ')') + if escQuote: self.pattern += (r'|(?:%s)' % re.escape(escQuote)) if escChar: self.pattern += (r'|(?:%s.)' % re.escape(escChar)) - self.escCharReplacePattern = re.escape(self.escChar)+"(.)" + self.escCharReplacePattern = re.escape(self.escChar) + "(.)" self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) try: self.re = re.compile(self.pattern, self.flags) self.reString = self.pattern + self.re_match = self.re.match except sre_constants.error: warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) raise self.name = _ustr(self) @@ -3231,8 +3511,8 @@ class QuotedString(Token): self.mayIndexError = False self.mayReturnEmpty = True - def parseImpl( self, instring, loc, doActions=True ): - result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None + def parseImpl(self, instring, loc, doActions=True): + result = instring[loc] == self.firstQuoteChar and self.re_match(instring, loc) or None if not result: raise ParseException(instring, loc, self.errmsg, self) @@ -3242,18 +3522,18 @@ class QuotedString(Token): if self.unquoteResults: # strip off quotes - ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + ret = ret[self.quoteCharLen: -self.endQuoteCharLen] - if isinstance(ret,basestring): + if isinstance(ret, basestring): # replace escaped whitespace if '\\' in ret and self.convertWhitespaceEscapes: ws_map = { - r'\t' : '\t', - r'\n' : '\n', - r'\f' : '\f', - r'\r' : '\r', + r'\t': '\t', + r'\n': '\n', + r'\f': '\f', + r'\r': '\r', } - for wslit,wschar in ws_map.items(): + for wslit, wschar in ws_map.items(): ret = ret.replace(wslit, wschar) # replace escaped characters @@ -3266,9 +3546,9 @@ class QuotedString(Token): return loc, ret - def __str__( self ): + def __str__(self): try: - return super(QuotedString,self).__str__() + return super(QuotedString, self).__str__() except Exception: pass @@ -3298,15 +3578,14 @@ class CharsNotIn(Token): ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] """ - def __init__( self, notChars, min=1, max=0, exact=0 ): - super(CharsNotIn,self).__init__() + def __init__(self, notChars, min=1, max=0, exact=0): + super(CharsNotIn, self).__init__() self.skipWhitespace = False self.notChars = notChars if min < 1: - raise ValueError( - "cannot specify a minimum length < 1; use " + - "Optional(CharsNotIn()) if zero-length char group is permitted") + raise ValueError("cannot specify a minimum length < 1; use " + "Optional(CharsNotIn()) if zero-length char group is permitted") self.minLen = min @@ -3321,19 +3600,18 @@ class CharsNotIn(Token): self.name = _ustr(self) self.errmsg = "Expected " + self.name - self.mayReturnEmpty = ( self.minLen == 0 ) + self.mayReturnEmpty = (self.minLen == 0) self.mayIndexError = False - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): if instring[loc] in self.notChars: raise ParseException(instring, loc, self.errmsg, self) start = loc loc += 1 notchars = self.notChars - maxlen = min( start+self.maxLen, len(instring) ) - while loc < maxlen and \ - (instring[loc] not in notchars): + maxlen = min(start + self.maxLen, len(instring)) + while loc < maxlen and instring[loc] not in notchars: loc += 1 if loc - start < self.minLen: @@ -3341,7 +3619,7 @@ class CharsNotIn(Token): return loc, instring[start:loc] - def __str__( self ): + def __str__(self): try: return super(CharsNotIn, self).__str__() except Exception: @@ -3370,30 +3648,30 @@ class White(Token): '\n': '<LF>', '\r': '<CR>', '\f': '<FF>', - 'u\00A0': '<NBSP>', - 'u\1680': '<OGHAM_SPACE_MARK>', - 'u\180E': '<MONGOLIAN_VOWEL_SEPARATOR>', - 'u\2000': '<EN_QUAD>', - 'u\2001': '<EM_QUAD>', - 'u\2002': '<EN_SPACE>', - 'u\2003': '<EM_SPACE>', - 'u\2004': '<THREE-PER-EM_SPACE>', - 'u\2005': '<FOUR-PER-EM_SPACE>', - 'u\2006': '<SIX-PER-EM_SPACE>', - 'u\2007': '<FIGURE_SPACE>', - 'u\2008': '<PUNCTUATION_SPACE>', - 'u\2009': '<THIN_SPACE>', - 'u\200A': '<HAIR_SPACE>', - 'u\200B': '<ZERO_WIDTH_SPACE>', - 'u\202F': '<NNBSP>', - 'u\205F': '<MMSP>', - 'u\3000': '<IDEOGRAPHIC_SPACE>', + u'\u00A0': '<NBSP>', + u'\u1680': '<OGHAM_SPACE_MARK>', + u'\u180E': '<MONGOLIAN_VOWEL_SEPARATOR>', + u'\u2000': '<EN_QUAD>', + u'\u2001': '<EM_QUAD>', + u'\u2002': '<EN_SPACE>', + u'\u2003': '<EM_SPACE>', + u'\u2004': '<THREE-PER-EM_SPACE>', + u'\u2005': '<FOUR-PER-EM_SPACE>', + u'\u2006': '<SIX-PER-EM_SPACE>', + u'\u2007': '<FIGURE_SPACE>', + u'\u2008': '<PUNCTUATION_SPACE>', + u'\u2009': '<THIN_SPACE>', + u'\u200A': '<HAIR_SPACE>', + u'\u200B': '<ZERO_WIDTH_SPACE>', + u'\u202F': '<NNBSP>', + u'\u205F': '<MMSP>', + u'\u3000': '<IDEOGRAPHIC_SPACE>', } def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): - super(White,self).__init__() + super(White, self).__init__() self.matchWhite = ws - self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) ) - #~ self.leaveWhitespace() + self.setWhitespaceChars("".join(c for c in self.whiteChars if c not in self.matchWhite)) + # ~ self.leaveWhitespace() self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) self.mayReturnEmpty = True self.errmsg = "Expected " + self.name @@ -3409,13 +3687,13 @@ class White(Token): self.maxLen = exact self.minLen = exact - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): if instring[loc] not in self.matchWhite: raise ParseException(instring, loc, self.errmsg, self) start = loc loc += 1 maxloc = start + self.maxLen - maxloc = min( maxloc, len(instring) ) + maxloc = min(maxloc, len(instring)) while loc < maxloc and instring[loc] in self.matchWhite: loc += 1 @@ -3426,9 +3704,9 @@ class White(Token): class _PositionToken(Token): - def __init__( self ): - super(_PositionToken,self).__init__() - self.name=self.__class__.__name__ + def __init__(self): + super(_PositionToken, self).__init__() + self.name = self.__class__.__name__ self.mayReturnEmpty = True self.mayIndexError = False @@ -3436,25 +3714,25 @@ class GoToColumn(_PositionToken): """Token to advance to a specific column of input text; useful for tabular report scraping. """ - def __init__( self, colno ): - super(GoToColumn,self).__init__() + def __init__(self, colno): + super(GoToColumn, self).__init__() self.col = colno - def preParse( self, instring, loc ): - if col(loc,instring) != self.col: + def preParse(self, instring, loc): + if col(loc, instring) != self.col: instrlen = len(instring) if self.ignoreExprs: - loc = self._skipIgnorables( instring, loc ) - while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : + loc = self._skipIgnorables(instring, loc) + while loc < instrlen and instring[loc].isspace() and col(loc, instring) != self.col: loc += 1 return loc - def parseImpl( self, instring, loc, doActions=True ): - thiscol = col( loc, instring ) + def parseImpl(self, instring, loc, doActions=True): + thiscol = col(loc, instring) if thiscol > self.col: - raise ParseException( instring, loc, "Text not in expected column", self ) + raise ParseException(instring, loc, "Text not in expected column", self) newloc = loc + self.col - thiscol - ret = instring[ loc: newloc ] + ret = instring[loc: newloc] return newloc, ret @@ -3480,11 +3758,11 @@ class LineStart(_PositionToken): ['AAA', ' and this line'] """ - def __init__( self ): - super(LineStart,self).__init__() + def __init__(self): + super(LineStart, self).__init__() self.errmsg = "Expected start of line" - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): if col(loc, instring) == 1: return loc, [] raise ParseException(instring, loc, self.errmsg, self) @@ -3493,19 +3771,19 @@ class LineEnd(_PositionToken): """Matches if current position is at the end of a line within the parse string """ - def __init__( self ): - super(LineEnd,self).__init__() - self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + def __init__(self): + super(LineEnd, self).__init__() + self.setWhitespaceChars(ParserElement.DEFAULT_WHITE_CHARS.replace("\n", "")) self.errmsg = "Expected end of line" - def parseImpl( self, instring, loc, doActions=True ): - if loc<len(instring): + def parseImpl(self, instring, loc, doActions=True): + if loc < len(instring): if instring[loc] == "\n": - return loc+1, "\n" + return loc + 1, "\n" else: raise ParseException(instring, loc, self.errmsg, self) elif loc == len(instring): - return loc+1, [] + return loc + 1, [] else: raise ParseException(instring, loc, self.errmsg, self) @@ -3513,29 +3791,29 @@ class StringStart(_PositionToken): """Matches if current position is at the beginning of the parse string """ - def __init__( self ): - super(StringStart,self).__init__() + def __init__(self): + super(StringStart, self).__init__() self.errmsg = "Expected start of text" - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): if loc != 0: # see if entire string up to here is just whitespace and ignoreables - if loc != self.preParse( instring, 0 ): + if loc != self.preParse(instring, 0): raise ParseException(instring, loc, self.errmsg, self) return loc, [] class StringEnd(_PositionToken): """Matches if current position is at the end of the parse string """ - def __init__( self ): - super(StringEnd,self).__init__() + def __init__(self): + super(StringEnd, self).__init__() self.errmsg = "Expected end of text" - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): if loc < len(instring): raise ParseException(instring, loc, self.errmsg, self) elif loc == len(instring): - return loc+1, [] + return loc + 1, [] elif loc > len(instring): return loc, [] else: @@ -3550,15 +3828,15 @@ class WordStart(_PositionToken): the beginning of the string being parsed, or at the beginning of a line. """ - def __init__(self, wordChars = printables): - super(WordStart,self).__init__() + def __init__(self, wordChars=printables): + super(WordStart, self).__init__() self.wordChars = set(wordChars) self.errmsg = "Not at the start of a word" - def parseImpl(self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): if loc != 0: - if (instring[loc-1] in self.wordChars or - instring[loc] not in self.wordChars): + if (instring[loc - 1] in self.wordChars + or instring[loc] not in self.wordChars): raise ParseException(instring, loc, self.errmsg, self) return loc, [] @@ -3570,17 +3848,17 @@ class WordEnd(_PositionToken): will also match at the end of the string being parsed, or at the end of a line. """ - def __init__(self, wordChars = printables): - super(WordEnd,self).__init__() + def __init__(self, wordChars=printables): + super(WordEnd, self).__init__() self.wordChars = set(wordChars) self.skipWhitespace = False self.errmsg = "Not at the end of a word" - def parseImpl(self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): instrlen = len(instring) - if instrlen>0 and loc<instrlen: + if instrlen > 0 and loc < instrlen: if (instring[loc] in self.wordChars or - instring[loc-1] not in self.wordChars): + instring[loc - 1] not in self.wordChars): raise ParseException(instring, loc, self.errmsg, self) return loc, [] @@ -3589,90 +3867,89 @@ class ParseExpression(ParserElement): """Abstract subclass of ParserElement, for combining and post-processing parsed tokens. """ - def __init__( self, exprs, savelist = False ): - super(ParseExpression,self).__init__(savelist) - if isinstance( exprs, _generatorType ): + def __init__(self, exprs, savelist=False): + super(ParseExpression, self).__init__(savelist) + if isinstance(exprs, _generatorType): exprs = list(exprs) - if isinstance( exprs, basestring ): - self.exprs = [ ParserElement._literalStringClass( exprs ) ] - elif isinstance( exprs, Iterable ): + if isinstance(exprs, basestring): + self.exprs = [self._literalStringClass(exprs)] + elif isinstance(exprs, ParserElement): + self.exprs = [exprs] + elif isinstance(exprs, Iterable): exprs = list(exprs) # if sequence of strings provided, wrap with Literal - if all(isinstance(expr, basestring) for expr in exprs): - exprs = map(ParserElement._literalStringClass, exprs) + if any(isinstance(expr, basestring) for expr in exprs): + exprs = (self._literalStringClass(e) if isinstance(e, basestring) else e for e in exprs) self.exprs = list(exprs) else: try: - self.exprs = list( exprs ) + self.exprs = list(exprs) except TypeError: - self.exprs = [ exprs ] + self.exprs = [exprs] self.callPreparse = False - def __getitem__( self, i ): - return self.exprs[i] - - def append( self, other ): - self.exprs.append( other ) + def append(self, other): + self.exprs.append(other) self.strRepr = None return self - def leaveWhitespace( self ): + def leaveWhitespace(self): """Extends ``leaveWhitespace`` defined in base class, and also invokes ``leaveWhitespace`` on all contained expressions.""" self.skipWhitespace = False - self.exprs = [ e.copy() for e in self.exprs ] + self.exprs = [e.copy() for e in self.exprs] for e in self.exprs: e.leaveWhitespace() return self - def ignore( self, other ): - if isinstance( other, Suppress ): + def ignore(self, other): + if isinstance(other, Suppress): if other not in self.ignoreExprs: - super( ParseExpression, self).ignore( other ) + super(ParseExpression, self).ignore(other) for e in self.exprs: - e.ignore( self.ignoreExprs[-1] ) + e.ignore(self.ignoreExprs[-1]) else: - super( ParseExpression, self).ignore( other ) + super(ParseExpression, self).ignore(other) for e in self.exprs: - e.ignore( self.ignoreExprs[-1] ) + e.ignore(self.ignoreExprs[-1]) return self - def __str__( self ): + def __str__(self): try: - return super(ParseExpression,self).__str__() + return super(ParseExpression, self).__str__() except Exception: pass if self.strRepr is None: - self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) ) + self.strRepr = "%s:(%s)" % (self.__class__.__name__, _ustr(self.exprs)) return self.strRepr - def streamline( self ): - super(ParseExpression,self).streamline() + def streamline(self): + super(ParseExpression, self).streamline() for e in self.exprs: e.streamline() - # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d ) + # collapse nested And's of the form And(And(And(a, b), c), d) to And(a, b, c, d) # but only if there are no parse actions or resultsNames on the nested And's # (likewise for Or's and MatchFirst's) - if ( len(self.exprs) == 2 ): + if len(self.exprs) == 2: other = self.exprs[0] - if ( isinstance( other, self.__class__ ) and - not(other.parseAction) and - other.resultsName is None and - not other.debug ): - self.exprs = other.exprs[:] + [ self.exprs[1] ] + if (isinstance(other, self.__class__) + and not other.parseAction + and other.resultsName is None + and not other.debug): + self.exprs = other.exprs[:] + [self.exprs[1]] self.strRepr = None self.mayReturnEmpty |= other.mayReturnEmpty self.mayIndexError |= other.mayIndexError other = self.exprs[-1] - if ( isinstance( other, self.__class__ ) and - not(other.parseAction) and - other.resultsName is None and - not other.debug ): + if (isinstance(other, self.__class__) + and not other.parseAction + and other.resultsName is None + and not other.debug): self.exprs = self.exprs[:-1] + other.exprs[:] self.strRepr = None self.mayReturnEmpty |= other.mayReturnEmpty @@ -3682,17 +3959,31 @@ class ParseExpression(ParserElement): return self - def validate( self, validateTrace=[] ): - tmp = validateTrace[:]+[self] + def validate(self, validateTrace=None): + tmp = (validateTrace if validateTrace is not None else [])[:] + [self] for e in self.exprs: e.validate(tmp) - self.checkRecursion( [] ) + self.checkRecursion([]) def copy(self): - ret = super(ParseExpression,self).copy() + ret = super(ParseExpression, self).copy() ret.exprs = [e.copy() for e in self.exprs] return ret + def _setResultsName(self, name, listAllMatches=False): + if __diag__.warn_ungrouped_named_tokens_in_collection: + for e in self.exprs: + if isinstance(e, ParserElement) and e.resultsName: + warnings.warn("{0}: setting results name {1!r} on {2} expression " + "collides with {3!r} on contained expression".format("warn_ungrouped_named_tokens_in_collection", + name, + type(self).__name__, + e.resultsName), + stacklevel=3) + + return super(ParseExpression, self)._setResultsName(name, listAllMatches) + + class And(ParseExpression): """ Requires all given :class:`ParseExpression` s to be found in the given order. @@ -3706,33 +3997,59 @@ class And(ParseExpression): integer = Word(nums) name_expr = OneOrMore(Word(alphas)) - expr = And([integer("id"),name_expr("name"),integer("age")]) + expr = And([integer("id"), name_expr("name"), integer("age")]) # more easily written as: expr = integer("id") + name_expr("name") + integer("age") """ class _ErrorStop(Empty): def __init__(self, *args, **kwargs): - super(And._ErrorStop,self).__init__(*args, **kwargs) + super(And._ErrorStop, self).__init__(*args, **kwargs) self.name = '-' self.leaveWhitespace() - def __init__( self, exprs, savelist = True ): - super(And,self).__init__(exprs, savelist) + def __init__(self, exprs, savelist=True): + exprs = list(exprs) + if exprs and Ellipsis in exprs: + tmp = [] + for i, expr in enumerate(exprs): + if expr is Ellipsis: + if i < len(exprs) - 1: + skipto_arg = (Empty() + exprs[i + 1]).exprs[-1] + tmp.append(SkipTo(skipto_arg)("_skipped*")) + else: + raise Exception("cannot construct And with sequence ending in ...") + else: + tmp.append(expr) + exprs[:] = tmp + super(And, self).__init__(exprs, savelist) self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) - self.setWhitespaceChars( self.exprs[0].whiteChars ) + self.setWhitespaceChars(self.exprs[0].whiteChars) self.skipWhitespace = self.exprs[0].skipWhitespace self.callPreparse = True def streamline(self): + # collapse any _PendingSkip's + if self.exprs: + if any(isinstance(e, ParseExpression) and e.exprs and isinstance(e.exprs[-1], _PendingSkip) + for e in self.exprs[:-1]): + for i, e in enumerate(self.exprs[:-1]): + if e is None: + continue + if (isinstance(e, ParseExpression) + and e.exprs and isinstance(e.exprs[-1], _PendingSkip)): + e.exprs[-1] = e.exprs[-1] + self.exprs[i + 1] + self.exprs[i + 1] = None + self.exprs = [e for e in self.exprs if e is not None] + super(And, self).streamline() self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) return self - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): # pass False as last arg to _parse for first element, since we already # pre-parsed the string as part of our And pre-parsing - loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False ) + loc, resultlist = self.exprs[0]._parse(instring, loc, doActions, callPreParse=False) errorStop = False for e in self.exprs[1:]: if isinstance(e, And._ErrorStop): @@ -3740,7 +4057,7 @@ class And(ParseExpression): continue if errorStop: try: - loc, exprtokens = e._parse( instring, loc, doActions ) + loc, exprtokens = e._parse(instring, loc, doActions) except ParseSyntaxException: raise except ParseBaseException as pe: @@ -3749,25 +4066,25 @@ class And(ParseExpression): except IndexError: raise ParseSyntaxException(instring, len(instring), self.errmsg, self) else: - loc, exprtokens = e._parse( instring, loc, doActions ) + loc, exprtokens = e._parse(instring, loc, doActions) if exprtokens or exprtokens.haskeys(): resultlist += exprtokens return loc, resultlist - def __iadd__(self, other ): - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - return self.append( other ) #And( [ self, other ] ) + def __iadd__(self, other): + if isinstance(other, basestring): + other = self._literalStringClass(other) + return self.append(other) # And([self, other]) - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] + def checkRecursion(self, parseElementList): + subRecCheckList = parseElementList[:] + [self] for e in self.exprs: - e.checkRecursion( subRecCheckList ) + e.checkRecursion(subRecCheckList) if not e.mayReturnEmpty: break - def __str__( self ): - if hasattr(self,"name"): + def __str__(self): + if hasattr(self, "name"): return self.name if self.strRepr is None: @@ -3793,8 +4110,8 @@ class Or(ParseExpression): [['123'], ['3.1416'], ['789']] """ - def __init__( self, exprs, savelist = False ): - super(Or,self).__init__(exprs, savelist) + def __init__(self, exprs, savelist=False): + super(Or, self).__init__(exprs, savelist) if self.exprs: self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) else: @@ -3806,13 +4123,13 @@ class Or(ParseExpression): self.saveAsList = any(e.saveAsList for e in self.exprs) return self - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): maxExcLoc = -1 maxException = None matches = [] for e in self.exprs: try: - loc2 = e.tryParse( instring, loc ) + loc2 = e.tryParse(instring, loc) except ParseException as err: err.__traceback__ = None if err.loc > maxExcLoc: @@ -3820,22 +4137,45 @@ class Or(ParseExpression): maxExcLoc = err.loc except IndexError: if len(instring) > maxExcLoc: - maxException = ParseException(instring,len(instring),e.errmsg,self) + maxException = ParseException(instring, len(instring), e.errmsg, self) maxExcLoc = len(instring) else: # save match among all matches, to retry longest to shortest matches.append((loc2, e)) if matches: - matches.sort(key=lambda x: -x[0]) - for _,e in matches: + # re-evaluate all matches in descending order of length of match, in case attached actions + # might change whether or how much they match of the input. + matches.sort(key=itemgetter(0), reverse=True) + + if not doActions: + # no further conditions or parse actions to change the selection of + # alternative, so the first match will be the best match + best_expr = matches[0][1] + return best_expr._parse(instring, loc, doActions) + + longest = -1, None + for loc1, expr1 in matches: + if loc1 <= longest[0]: + # already have a longer match than this one will deliver, we are done + return longest + try: - return e._parse( instring, loc, doActions ) + loc2, toks = expr1._parse(instring, loc, doActions) except ParseException as err: err.__traceback__ = None if err.loc > maxExcLoc: maxException = err maxExcLoc = err.loc + else: + if loc2 >= loc1: + return loc2, toks + # didn't match as much as before + elif loc2 > longest[0]: + longest = loc2, toks + + if longest != (-1, None): + return longest if maxException is not None: maxException.msg = self.errmsg @@ -3844,13 +4184,13 @@ class Or(ParseExpression): raise ParseException(instring, loc, "no defined alternatives to match", self) - def __ixor__(self, other ): - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - return self.append( other ) #Or( [ self, other ] ) + def __ixor__(self, other): + if isinstance(other, basestring): + other = self._literalStringClass(other) + return self.append(other) # Or([self, other]) - def __str__( self ): - if hasattr(self,"name"): + def __str__(self): + if hasattr(self, "name"): return self.name if self.strRepr is None: @@ -3858,10 +4198,22 @@ class Or(ParseExpression): return self.strRepr - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] + def checkRecursion(self, parseElementList): + subRecCheckList = parseElementList[:] + [self] for e in self.exprs: - e.checkRecursion( subRecCheckList ) + e.checkRecursion(subRecCheckList) + + def _setResultsName(self, name, listAllMatches=False): + if (not __compat__.collect_all_And_tokens + and __diag__.warn_multiple_tokens_in_named_alternation): + if any(isinstance(e, And) for e in self.exprs): + warnings.warn("{0}: setting results name {1!r} on {2} expression " + "may only return a single token for an And alternative, " + "in future will return the full list of tokens".format( + "warn_multiple_tokens_in_named_alternation", name, type(self).__name__), + stacklevel=3) + + return super(Or, self)._setResultsName(name, listAllMatches) class MatchFirst(ParseExpression): @@ -3881,8 +4233,8 @@ class MatchFirst(ParseExpression): number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] """ - def __init__( self, exprs, savelist = False ): - super(MatchFirst,self).__init__(exprs, savelist) + def __init__(self, exprs, savelist=False): + super(MatchFirst, self).__init__(exprs, savelist) if self.exprs: self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) else: @@ -3894,12 +4246,12 @@ class MatchFirst(ParseExpression): self.saveAsList = any(e.saveAsList for e in self.exprs) return self - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): maxExcLoc = -1 maxException = None for e in self.exprs: try: - ret = e._parse( instring, loc, doActions ) + ret = e._parse(instring, loc, doActions) return ret except ParseException as err: if err.loc > maxExcLoc: @@ -3907,7 +4259,7 @@ class MatchFirst(ParseExpression): maxExcLoc = err.loc except IndexError: if len(instring) > maxExcLoc: - maxException = ParseException(instring,len(instring),e.errmsg,self) + maxException = ParseException(instring, len(instring), e.errmsg, self) maxExcLoc = len(instring) # only got here if no expression matched, raise exception for match that made it the furthest @@ -3918,13 +4270,13 @@ class MatchFirst(ParseExpression): else: raise ParseException(instring, loc, "no defined alternatives to match", self) - def __ior__(self, other ): - if isinstance( other, basestring ): - other = ParserElement._literalStringClass( other ) - return self.append( other ) #MatchFirst( [ self, other ] ) + def __ior__(self, other): + if isinstance(other, basestring): + other = self._literalStringClass(other) + return self.append(other) # MatchFirst([self, other]) - def __str__( self ): - if hasattr(self,"name"): + def __str__(self): + if hasattr(self, "name"): return self.name if self.strRepr is None: @@ -3932,10 +4284,22 @@ class MatchFirst(ParseExpression): return self.strRepr - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] + def checkRecursion(self, parseElementList): + subRecCheckList = parseElementList[:] + [self] for e in self.exprs: - e.checkRecursion( subRecCheckList ) + e.checkRecursion(subRecCheckList) + + def _setResultsName(self, name, listAllMatches=False): + if (not __compat__.collect_all_And_tokens + and __diag__.warn_multiple_tokens_in_named_alternation): + if any(isinstance(e, And) for e in self.exprs): + warnings.warn("{0}: setting results name {1!r} on {2} expression " + "may only return a single token for an And alternative, " + "in future will return the full list of tokens".format( + "warn_multiple_tokens_in_named_alternation", name, type(self).__name__), + stacklevel=3) + + return super(MatchFirst, self)._setResultsName(name, listAllMatches) class Each(ParseExpression): @@ -3995,8 +4359,8 @@ class Each(ParseExpression): - shape: TRIANGLE - size: 20 """ - def __init__( self, exprs, savelist = True ): - super(Each,self).__init__(exprs, savelist) + def __init__(self, exprs, savelist=True): + super(Each, self).__init__(exprs, savelist) self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) self.skipWhitespace = True self.initExprGroups = True @@ -4007,15 +4371,15 @@ class Each(ParseExpression): self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) return self - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): if self.initExprGroups: - self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional)) - opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] - opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)] + self.opt1map = dict((id(e.expr), e) for e in self.exprs if isinstance(e, Optional)) + opt1 = [e.expr for e in self.exprs if isinstance(e, Optional)] + opt2 = [e for e in self.exprs if e.mayReturnEmpty and not isinstance(e, (Optional, Regex))] self.optionals = opt1 + opt2 - self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] - self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] - self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] + self.multioptionals = [e.expr for e in self.exprs if isinstance(e, ZeroOrMore)] + self.multirequired = [e.expr for e in self.exprs if isinstance(e, OneOrMore)] + self.required = [e for e in self.exprs if not isinstance(e, (Optional, ZeroOrMore, OneOrMore))] self.required += self.multirequired self.initExprGroups = False tmpLoc = loc @@ -4029,11 +4393,11 @@ class Each(ParseExpression): failed = [] for e in tmpExprs: try: - tmpLoc = e.tryParse( instring, tmpLoc ) + tmpLoc = e.tryParse(instring, tmpLoc) except ParseException: failed.append(e) else: - matchOrder.append(self.opt1map.get(id(e),e)) + matchOrder.append(self.opt1map.get(id(e), e)) if e in tmpReqd: tmpReqd.remove(e) elif e in tmpOpt: @@ -4043,21 +4407,21 @@ class Each(ParseExpression): if tmpReqd: missing = ", ".join(_ustr(e) for e in tmpReqd) - raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) + raise ParseException(instring, loc, "Missing one or more required elements (%s)" % missing) # add any unmatched Optionals, in case they have default values defined - matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt] + matchOrder += [e for e in self.exprs if isinstance(e, Optional) and e.expr in tmpOpt] resultlist = [] for e in matchOrder: - loc,results = e._parse(instring,loc,doActions) + loc, results = e._parse(instring, loc, doActions) resultlist.append(results) finalResults = sum(resultlist, ParseResults([])) return loc, finalResults - def __str__( self ): - if hasattr(self,"name"): + def __str__(self): + if hasattr(self, "name"): return self.name if self.strRepr is None: @@ -4065,86 +4429,88 @@ class Each(ParseExpression): return self.strRepr - def checkRecursion( self, parseElementList ): - subRecCheckList = parseElementList[:] + [ self ] + def checkRecursion(self, parseElementList): + subRecCheckList = parseElementList[:] + [self] for e in self.exprs: - e.checkRecursion( subRecCheckList ) + e.checkRecursion(subRecCheckList) class ParseElementEnhance(ParserElement): """Abstract subclass of :class:`ParserElement`, for combining and post-processing parsed tokens. """ - def __init__( self, expr, savelist=False ): - super(ParseElementEnhance,self).__init__(savelist) - if isinstance( expr, basestring ): - if issubclass(ParserElement._literalStringClass, Token): - expr = ParserElement._literalStringClass(expr) + def __init__(self, expr, savelist=False): + super(ParseElementEnhance, self).__init__(savelist) + if isinstance(expr, basestring): + if issubclass(self._literalStringClass, Token): + expr = self._literalStringClass(expr) else: - expr = ParserElement._literalStringClass(Literal(expr)) + expr = self._literalStringClass(Literal(expr)) self.expr = expr self.strRepr = None if expr is not None: self.mayIndexError = expr.mayIndexError self.mayReturnEmpty = expr.mayReturnEmpty - self.setWhitespaceChars( expr.whiteChars ) + self.setWhitespaceChars(expr.whiteChars) self.skipWhitespace = expr.skipWhitespace self.saveAsList = expr.saveAsList self.callPreparse = expr.callPreparse self.ignoreExprs.extend(expr.ignoreExprs) - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): if self.expr is not None: - return self.expr._parse( instring, loc, doActions, callPreParse=False ) + return self.expr._parse(instring, loc, doActions, callPreParse=False) else: - raise ParseException("",loc,self.errmsg,self) + raise ParseException("", loc, self.errmsg, self) - def leaveWhitespace( self ): + def leaveWhitespace(self): self.skipWhitespace = False self.expr = self.expr.copy() if self.expr is not None: self.expr.leaveWhitespace() return self - def ignore( self, other ): - if isinstance( other, Suppress ): + def ignore(self, other): + if isinstance(other, Suppress): if other not in self.ignoreExprs: - super( ParseElementEnhance, self).ignore( other ) + super(ParseElementEnhance, self).ignore(other) if self.expr is not None: - self.expr.ignore( self.ignoreExprs[-1] ) + self.expr.ignore(self.ignoreExprs[-1]) else: - super( ParseElementEnhance, self).ignore( other ) + super(ParseElementEnhance, self).ignore(other) if self.expr is not None: - self.expr.ignore( self.ignoreExprs[-1] ) + self.expr.ignore(self.ignoreExprs[-1]) return self - def streamline( self ): - super(ParseElementEnhance,self).streamline() + def streamline(self): + super(ParseElementEnhance, self).streamline() if self.expr is not None: self.expr.streamline() return self - def checkRecursion( self, parseElementList ): + def checkRecursion(self, parseElementList): if self in parseElementList: - raise RecursiveGrammarException( parseElementList+[self] ) - subRecCheckList = parseElementList[:] + [ self ] + raise RecursiveGrammarException(parseElementList + [self]) + subRecCheckList = parseElementList[:] + [self] if self.expr is not None: - self.expr.checkRecursion( subRecCheckList ) + self.expr.checkRecursion(subRecCheckList) - def validate( self, validateTrace=[] ): - tmp = validateTrace[:]+[self] + def validate(self, validateTrace=None): + if validateTrace is None: + validateTrace = [] + tmp = validateTrace[:] + [self] if self.expr is not None: self.expr.validate(tmp) - self.checkRecursion( [] ) + self.checkRecursion([]) - def __str__( self ): + def __str__(self): try: - return super(ParseElementEnhance,self).__str__() + return super(ParseElementEnhance, self).__str__() except Exception: pass if self.strRepr is None and self.expr is not None: - self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) + self.strRepr = "%s:(%s)" % (self.__class__.__name__, _ustr(self.expr)) return self.strRepr @@ -4170,13 +4536,16 @@ class FollowedBy(ParseElementEnhance): [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] """ - def __init__( self, expr ): - super(FollowedBy,self).__init__(expr) + def __init__(self, expr): + super(FollowedBy, self).__init__(expr) self.mayReturnEmpty = True - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): + # by using self._expr.parse and deleting the contents of the returned ParseResults list + # we keep any named results that were defined in the FollowedBy expression _, ret = self.expr._parse(instring, loc, doActions=doActions) del ret[:] + return loc, ret @@ -4229,6 +4598,7 @@ class PrecededBy(ParseElementEnhance): self.retreat = retreat self.errmsg = "not preceded by " + str(expr) self.skipWhitespace = False + self.parseAction.append(lambda s, l, t: t.__delitem__(slice(None, None))) def parseImpl(self, instring, loc=0, doActions=True): if self.exact: @@ -4239,19 +4609,18 @@ class PrecededBy(ParseElementEnhance): else: # retreat specified a maximum lookbehind window, iterate test_expr = self.expr + StringEnd() - instring_slice = instring[:loc] + instring_slice = instring[max(0, loc - self.retreat):loc] last_expr = ParseException(instring, loc, self.errmsg) - for offset in range(1, min(loc, self.retreat+1)): + for offset in range(1, min(loc, self.retreat + 1)+1): try: - _, ret = test_expr._parse(instring_slice, loc-offset) + # print('trying', offset, instring_slice, repr(instring_slice[loc - offset:])) + _, ret = test_expr._parse(instring_slice, len(instring_slice) - offset) except ParseBaseException as pbe: last_expr = pbe else: break else: raise last_expr - # return empty list of tokens, but preserve any defined results names - del ret[:] return loc, ret @@ -4278,20 +4647,20 @@ class NotAny(ParseElementEnhance): # integers that are followed by "." are actually floats integer = Word(nums) + ~Char(".") """ - def __init__( self, expr ): - super(NotAny,self).__init__(expr) - #~ self.leaveWhitespace() + def __init__(self, expr): + super(NotAny, self).__init__(expr) + # ~ self.leaveWhitespace() self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs self.mayReturnEmpty = True - self.errmsg = "Found unwanted token, "+_ustr(self.expr) + self.errmsg = "Found unwanted token, " + _ustr(self.expr) - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): if self.expr.canParseNext(instring, loc): raise ParseException(instring, loc, self.errmsg, self) return loc, [] - def __str__( self ): - if hasattr(self,"name"): + def __str__(self): + if hasattr(self, "name"): return self.name if self.strRepr is None: @@ -4300,15 +4669,21 @@ class NotAny(ParseElementEnhance): return self.strRepr class _MultipleMatch(ParseElementEnhance): - def __init__( self, expr, stopOn=None): + def __init__(self, expr, stopOn=None): super(_MultipleMatch, self).__init__(expr) self.saveAsList = True ender = stopOn if isinstance(ender, basestring): - ender = ParserElement._literalStringClass(ender) - self.not_ender = ~ender if ender is not None else None + ender = self._literalStringClass(ender) + self.stopOn(ender) - def parseImpl( self, instring, loc, doActions=True ): + def stopOn(self, ender): + if isinstance(ender, basestring): + ender = self._literalStringClass(ender) + self.not_ender = ~ender if ender is not None else None + return self + + def parseImpl(self, instring, loc, doActions=True): self_expr_parse = self.expr._parse self_skip_ignorables = self._skipIgnorables check_ender = self.not_ender is not None @@ -4319,24 +4694,38 @@ class _MultipleMatch(ParseElementEnhance): # if so, fail) if check_ender: try_not_ender(instring, loc) - loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False ) + loc, tokens = self_expr_parse(instring, loc, doActions, callPreParse=False) try: hasIgnoreExprs = (not not self.ignoreExprs) while 1: if check_ender: try_not_ender(instring, loc) if hasIgnoreExprs: - preloc = self_skip_ignorables( instring, loc ) + preloc = self_skip_ignorables(instring, loc) else: preloc = loc - loc, tmptokens = self_expr_parse( instring, preloc, doActions ) + loc, tmptokens = self_expr_parse(instring, preloc, doActions) if tmptokens or tmptokens.haskeys(): tokens += tmptokens - except (ParseException,IndexError): + except (ParseException, IndexError): pass return loc, tokens + def _setResultsName(self, name, listAllMatches=False): + if __diag__.warn_ungrouped_named_tokens_in_collection: + for e in [self.expr] + getattr(self.expr, 'exprs', []): + if isinstance(e, ParserElement) and e.resultsName: + warnings.warn("{0}: setting results name {1!r} on {2} expression " + "collides with {3!r} on contained expression".format("warn_ungrouped_named_tokens_in_collection", + name, + type(self).__name__, + e.resultsName), + stacklevel=3) + + return super(_MultipleMatch, self)._setResultsName(name, listAllMatches) + + class OneOrMore(_MultipleMatch): """Repetition of one or more of the given expression. @@ -4363,8 +4752,8 @@ class OneOrMore(_MultipleMatch): (attr_expr * (1,)).parseString(text).pprint() """ - def __str__( self ): - if hasattr(self,"name"): + def __str__(self): + if hasattr(self, "name"): return self.name if self.strRepr is None: @@ -4383,18 +4772,18 @@ class ZeroOrMore(_MultipleMatch): Example: similar to :class:`OneOrMore` """ - def __init__( self, expr, stopOn=None): - super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) + def __init__(self, expr, stopOn=None): + super(ZeroOrMore, self).__init__(expr, stopOn=stopOn) self.mayReturnEmpty = True - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): try: return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) - except (ParseException,IndexError): + except (ParseException, IndexError): return loc, [] - def __str__( self ): - if hasattr(self,"name"): + def __str__(self): + if hasattr(self, "name"): return self.name if self.strRepr is None: @@ -4402,6 +4791,7 @@ class ZeroOrMore(_MultipleMatch): return self.strRepr + class _NullToken(object): def __bool__(self): return False @@ -4409,7 +4799,6 @@ class _NullToken(object): def __str__(self): return "" -_optionalNotMatched = _NullToken() class Optional(ParseElementEnhance): """Optional matching of the given expression. @@ -4447,28 +4836,30 @@ class Optional(ParseElementEnhance): ^ FAIL: Expected end of text (at char 5), (line:1, col:6) """ - def __init__( self, expr, default=_optionalNotMatched ): - super(Optional,self).__init__( expr, savelist=False ) + __optionalNotMatched = _NullToken() + + def __init__(self, expr, default=__optionalNotMatched): + super(Optional, self).__init__(expr, savelist=False) self.saveAsList = self.expr.saveAsList self.defaultValue = default self.mayReturnEmpty = True - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): try: - loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) - except (ParseException,IndexError): - if self.defaultValue is not _optionalNotMatched: + loc, tokens = self.expr._parse(instring, loc, doActions, callPreParse=False) + except (ParseException, IndexError): + if self.defaultValue is not self.__optionalNotMatched: if self.expr.resultsName: - tokens = ParseResults([ self.defaultValue ]) + tokens = ParseResults([self.defaultValue]) tokens[self.expr.resultsName] = self.defaultValue else: - tokens = [ self.defaultValue ] + tokens = [self.defaultValue] else: tokens = [] return loc, tokens - def __str__( self ): - if hasattr(self,"name"): + def __str__(self): + if hasattr(self, "name"): return self.name if self.strRepr is None: @@ -4534,20 +4925,20 @@ class SkipTo(ParseElementEnhance): - issue_num: 79 - sev: Minor """ - def __init__( self, other, include=False, ignore=None, failOn=None ): - super( SkipTo, self ).__init__( other ) + def __init__(self, other, include=False, ignore=None, failOn=None): + super(SkipTo, self).__init__(other) self.ignoreExpr = ignore self.mayReturnEmpty = True self.mayIndexError = False self.includeMatch = include self.saveAsList = False if isinstance(failOn, basestring): - self.failOn = ParserElement._literalStringClass(failOn) + self.failOn = self._literalStringClass(failOn) else: self.failOn = failOn - self.errmsg = "No match found for "+_ustr(self.expr) + self.errmsg = "No match found for " + _ustr(self.expr) - def parseImpl( self, instring, loc, doActions=True ): + def parseImpl(self, instring, loc, doActions=True): startloc = loc instrlen = len(instring) expr = self.expr @@ -4589,7 +4980,7 @@ class SkipTo(ParseElementEnhance): skipresult = ParseResults(skiptext) if self.includeMatch: - loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) + loc, mat = expr_parse(instring, loc, doActions, callPreParse=False) skipresult += mat return loc, skipresult @@ -4621,17 +5012,17 @@ class Forward(ParseElementEnhance): See :class:`ParseResults.pprint` for an example of a recursive parser created using ``Forward``. """ - def __init__( self, other=None ): - super(Forward,self).__init__( other, savelist=False ) + def __init__(self, other=None): + super(Forward, self).__init__(other, savelist=False) - def __lshift__( self, other ): - if isinstance( other, basestring ): - other = ParserElement._literalStringClass(other) + def __lshift__(self, other): + if isinstance(other, basestring): + other = self._literalStringClass(other) self.expr = other self.strRepr = None self.mayIndexError = self.expr.mayIndexError self.mayReturnEmpty = self.expr.mayReturnEmpty - self.setWhitespaceChars( self.expr.whiteChars ) + self.setWhitespaceChars(self.expr.whiteChars) self.skipWhitespace = self.expr.skipWhitespace self.saveAsList = self.expr.saveAsList self.ignoreExprs.extend(self.expr.ignoreExprs) @@ -4640,55 +5031,72 @@ class Forward(ParseElementEnhance): def __ilshift__(self, other): return self << other - def leaveWhitespace( self ): + def leaveWhitespace(self): self.skipWhitespace = False return self - def streamline( self ): + def streamline(self): if not self.streamlined: self.streamlined = True if self.expr is not None: self.expr.streamline() return self - def validate( self, validateTrace=[] ): + def validate(self, validateTrace=None): + if validateTrace is None: + validateTrace = [] + if self not in validateTrace: - tmp = validateTrace[:]+[self] + tmp = validateTrace[:] + [self] if self.expr is not None: self.expr.validate(tmp) self.checkRecursion([]) - def __str__( self ): - if hasattr(self,"name"): + def __str__(self): + if hasattr(self, "name"): return self.name + if self.strRepr is not None: + return self.strRepr - # Avoid infinite recursion by setting a temporary name - self.name = self.__class__.__name__ + ": ..." + # Avoid infinite recursion by setting a temporary strRepr + self.strRepr = ": ..." # Use the string representation of main expression. + retString = '...' try: if self.expr is not None: - retString = _ustr(self.expr) + retString = _ustr(self.expr)[:1000] else: retString = "None" finally: - del self.name - return self.__class__.__name__ + ": " + retString + self.strRepr = self.__class__.__name__ + ": " + retString + return self.strRepr def copy(self): if self.expr is not None: - return super(Forward,self).copy() + return super(Forward, self).copy() else: ret = Forward() ret <<= self return ret + def _setResultsName(self, name, listAllMatches=False): + if __diag__.warn_name_set_on_empty_Forward: + if self.expr is None: + warnings.warn("{0}: setting results name {0!r} on {1} expression " + "that has no contained expression".format("warn_name_set_on_empty_Forward", + name, + type(self).__name__), + stacklevel=3) + + return super(Forward, self)._setResultsName(name, listAllMatches) + class TokenConverter(ParseElementEnhance): """ Abstract subclass of :class:`ParseExpression`, for converting parsed results. """ - def __init__( self, expr, savelist=False ): - super(TokenConverter,self).__init__( expr )#, savelist ) + def __init__(self, expr, savelist=False): + super(TokenConverter, self).__init__(expr) # , savelist) self.saveAsList = False class Combine(TokenConverter): @@ -4709,8 +5117,8 @@ class Combine(TokenConverter): # no match when there are internal spaces print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...) """ - def __init__( self, expr, joinString="", adjacent=True ): - super(Combine,self).__init__( expr ) + def __init__(self, expr, joinString="", adjacent=True): + super(Combine, self).__init__(expr) # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself if adjacent: self.leaveWhitespace() @@ -4719,20 +5127,20 @@ class Combine(TokenConverter): self.joinString = joinString self.callPreparse = True - def ignore( self, other ): + def ignore(self, other): if self.adjacent: ParserElement.ignore(self, other) else: - super( Combine, self).ignore( other ) + super(Combine, self).ignore(other) return self - def postParse( self, instring, loc, tokenlist ): + def postParse(self, instring, loc, tokenlist): retToks = tokenlist.copy() del retToks[:] - retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + retToks += ParseResults(["".join(tokenlist._asStringList(self.joinString))], modal=self.modalResults) if self.resultsName and retToks.haskeys(): - return [ retToks ] + return [retToks] else: return retToks @@ -4746,17 +5154,17 @@ class Group(TokenConverter): num = Word(nums) term = ident | num func = ident + Optional(delimitedList(term)) - print(func.parseString("fn a,b,100")) # -> ['fn', 'a', 'b', '100'] + print(func.parseString("fn a, b, 100")) # -> ['fn', 'a', 'b', '100'] func = ident + Group(Optional(delimitedList(term))) - print(func.parseString("fn a,b,100")) # -> ['fn', ['a', 'b', '100']] + print(func.parseString("fn a, b, 100")) # -> ['fn', ['a', 'b', '100']] """ - def __init__( self, expr ): - super(Group,self).__init__( expr ) + def __init__(self, expr): + super(Group, self).__init__(expr) self.saveAsList = True - def postParse( self, instring, loc, tokenlist ): - return [ tokenlist ] + def postParse(self, instring, loc, tokenlist): + return [tokenlist] class Dict(TokenConverter): """Converter to return a repetitive expression as a list, but also @@ -4797,31 +5205,31 @@ class Dict(TokenConverter): See more examples at :class:`ParseResults` of accessing fields by results name. """ - def __init__( self, expr ): - super(Dict,self).__init__( expr ) + def __init__(self, expr): + super(Dict, self).__init__(expr) self.saveAsList = True - def postParse( self, instring, loc, tokenlist ): - for i,tok in enumerate(tokenlist): + def postParse(self, instring, loc, tokenlist): + for i, tok in enumerate(tokenlist): if len(tok) == 0: continue ikey = tok[0] - if isinstance(ikey,int): + if isinstance(ikey, int): ikey = _ustr(tok[0]).strip() - if len(tok)==1: - tokenlist[ikey] = _ParseResultsWithOffset("",i) - elif len(tok)==2 and not isinstance(tok[1],ParseResults): - tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) + if len(tok) == 1: + tokenlist[ikey] = _ParseResultsWithOffset("", i) + elif len(tok) == 2 and not isinstance(tok[1], ParseResults): + tokenlist[ikey] = _ParseResultsWithOffset(tok[1], i) else: - dictvalue = tok.copy() #ParseResults(i) + dictvalue = tok.copy() # ParseResults(i) del dictvalue[0] - if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): - tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + if len(dictvalue) != 1 or (isinstance(dictvalue, ParseResults) and dictvalue.haskeys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue, i) else: - tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0], i) if self.resultsName: - return [ tokenlist ] + return [tokenlist] else: return tokenlist @@ -4848,10 +5256,10 @@ class Suppress(TokenConverter): (See also :class:`delimitedList`.) """ - def postParse( self, instring, loc, tokenlist ): + def postParse(self, instring, loc, tokenlist): return [] - def suppress( self ): + def suppress(self): return self @@ -4861,12 +5269,12 @@ class OnlyOnce(object): def __init__(self, methodCall): self.callable = _trim_arity(methodCall) self.called = False - def __call__(self,s,l,t): + def __call__(self, s, l, t): if not self.called: - results = self.callable(s,l,t) + results = self.callable(s, l, t) self.called = True return results - raise ParseException(s,l,"") + raise ParseException(s, l, "") def reset(self): self.called = False @@ -4898,16 +5306,16 @@ def traceParseAction(f): f = _trim_arity(f) def z(*paArgs): thisFunc = f.__name__ - s,l,t = paArgs[-3:] - if len(paArgs)>3: + s, l, t = paArgs[-3:] + if len(paArgs) > 3: thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc - sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) ) + sys.stderr.write(">>entering %s(line: '%s', %d, %r)\n" % (thisFunc, line(l, s), l, t)) try: ret = f(*paArgs) except Exception as exc: - sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) ) + sys.stderr.write("<<leaving %s (exception: %s)\n" % (thisFunc, exc)) raise - sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) ) + sys.stderr.write("<<leaving %s (ret: %r)\n" % (thisFunc, ret)) return ret try: z.__name__ = f.__name__ @@ -4918,7 +5326,7 @@ def traceParseAction(f): # # global helpers # -def delimitedList( expr, delim=",", combine=False ): +def delimitedList(expr, delim=",", combine=False): """Helper to define a delimited list of expressions - the delimiter defaults to ','. By default, the list elements and delimiters can have intervening whitespace, and comments, but this can be @@ -4933,13 +5341,13 @@ def delimitedList( expr, delim=",", combine=False ): delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc'] delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] """ - dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..." + dlName = _ustr(expr) + " [" + _ustr(delim) + " " + _ustr(expr) + "]..." if combine: - return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) + return Combine(expr + ZeroOrMore(delim + expr)).setName(dlName) else: - return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) + return (expr + ZeroOrMore(Suppress(delim) + expr)).setName(dlName) -def countedArray( expr, intExpr=None ): +def countedArray(expr, intExpr=None): """Helper to define a counted list of expressions. This helper defines a pattern of the form:: @@ -4963,22 +5371,22 @@ def countedArray( expr, intExpr=None ): countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] """ arrayExpr = Forward() - def countFieldParseAction(s,l,t): + def countFieldParseAction(s, l, t): n = t[0] - arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) + arrayExpr << (n and Group(And([expr] * n)) or Group(empty)) return [] if intExpr is None: - intExpr = Word(nums).setParseAction(lambda t:int(t[0])) + intExpr = Word(nums).setParseAction(lambda t: int(t[0])) else: intExpr = intExpr.copy() intExpr.setName("arrayLen") intExpr.addParseAction(countFieldParseAction, callDuringTry=True) - return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...') + return (intExpr + arrayExpr).setName('(len) ' + _ustr(expr) + '...') def _flatten(L): ret = [] for i in L: - if isinstance(i,list): + if isinstance(i, list): ret.extend(_flatten(i)) else: ret.append(i) @@ -5000,7 +5408,7 @@ def matchPreviousLiteral(expr): enabled. """ rep = Forward() - def copyTokenToRepeater(s,l,t): + def copyTokenToRepeater(s, l, t): if t: if len(t) == 1: rep << t[0] @@ -5032,26 +5440,26 @@ def matchPreviousExpr(expr): rep = Forward() e2 = expr.copy() rep <<= e2 - def copyTokenToRepeater(s,l,t): + def copyTokenToRepeater(s, l, t): matchTokens = _flatten(t.asList()) - def mustMatchTheseTokens(s,l,t): + def mustMatchTheseTokens(s, l, t): theseTokens = _flatten(t.asList()) - if theseTokens != matchTokens: - raise ParseException("",0,"") - rep.setParseAction( mustMatchTheseTokens, callDuringTry=True ) + if theseTokens != matchTokens: + raise ParseException('', 0, '') + rep.setParseAction(mustMatchTheseTokens, callDuringTry=True) expr.addParseAction(copyTokenToRepeater, callDuringTry=True) rep.setName('(prev) ' + _ustr(expr)) return rep def _escapeRegexRangeChars(s): - #~ escape these chars: ^-] - for c in r"\^-]": - s = s.replace(c,_bslash+c) - s = s.replace("\n",r"\n") - s = s.replace("\t",r"\t") + # ~ escape these chars: ^-[] + for c in r"\^-[]": + s = s.replace(c, _bslash + c) + s = s.replace("\n", r"\n") + s = s.replace("\t", r"\t") return _ustr(s) -def oneOf( strs, caseless=False, useRegex=True ): +def oneOf(strs, caseless=False, useRegex=True, asKeyword=False): """Helper to quickly define a set of alternative Literals, and makes sure to do longest-first testing when there is a conflict, regardless of the input order, but returns @@ -5065,8 +5473,10 @@ def oneOf( strs, caseless=False, useRegex=True ): caseless - useRegex - (default= ``True``) - as an optimization, will generate a Regex object; otherwise, will generate - a :class:`MatchFirst` object (if ``caseless=True``, or if + a :class:`MatchFirst` object (if ``caseless=True`` or ``asKeyword=True``, or if creating a :class:`Regex` raises an exception) + - asKeyword - (default=``False``) - enforce Keyword-style matching on the + generated expressions Example:: @@ -5081,57 +5491,62 @@ def oneOf( strs, caseless=False, useRegex=True ): [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] """ + if isinstance(caseless, basestring): + warnings.warn("More than one string argument passed to oneOf, pass " + "choices as a list or space-delimited string", stacklevel=2) + if caseless: - isequal = ( lambda a,b: a.upper() == b.upper() ) - masks = ( lambda a,b: b.upper().startswith(a.upper()) ) - parseElementClass = CaselessLiteral + isequal = (lambda a, b: a.upper() == b.upper()) + masks = (lambda a, b: b.upper().startswith(a.upper())) + parseElementClass = CaselessKeyword if asKeyword else CaselessLiteral else: - isequal = ( lambda a,b: a == b ) - masks = ( lambda a,b: b.startswith(a) ) - parseElementClass = Literal + isequal = (lambda a, b: a == b) + masks = (lambda a, b: b.startswith(a)) + parseElementClass = Keyword if asKeyword else Literal symbols = [] - if isinstance(strs,basestring): + if isinstance(strs, basestring): symbols = strs.split() elif isinstance(strs, Iterable): symbols = list(strs) else: warnings.warn("Invalid argument to oneOf, expected string or iterable", - SyntaxWarning, stacklevel=2) + SyntaxWarning, stacklevel=2) if not symbols: return NoMatch() - i = 0 - while i < len(symbols)-1: - cur = symbols[i] - for j,other in enumerate(symbols[i+1:]): - if ( isequal(other, cur) ): - del symbols[i+j+1] - break - elif ( masks(cur, other) ): - del symbols[i+j+1] - symbols.insert(i,other) - cur = other - break - else: - i += 1 - - if not caseless and useRegex: - #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) - try: - if len(symbols)==len("".join(symbols)): - return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols)) + if not asKeyword: + # if not producing keywords, need to reorder to take care to avoid masking + # longer choices with shorter ones + i = 0 + while i < len(symbols) - 1: + cur = symbols[i] + for j, other in enumerate(symbols[i + 1:]): + if isequal(other, cur): + del symbols[i + j + 1] + break + elif masks(cur, other): + del symbols[i + j + 1] + symbols.insert(i, other) + break else: - return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols)) + i += 1 + + if not (caseless or asKeyword) and useRegex: + # ~ print (strs, "->", "|".join([_escapeRegexChars(sym) for sym in symbols])) + try: + if len(symbols) == len("".join(symbols)): + return Regex("[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols)).setName(' | '.join(symbols)) + else: + return Regex("|".join(re.escape(sym) for sym in symbols)).setName(' | '.join(symbols)) except Exception: warnings.warn("Exception creating Regex for oneOf, building MatchFirst", SyntaxWarning, stacklevel=2) - # last resort, just use MatchFirst return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols)) -def dictOf( key, value ): +def dictOf(key, value): """Helper to easily and clearly define a dictionary by specifying the respective patterns for the key and value. Takes care of defining the :class:`Dict`, :class:`ZeroOrMore`, and @@ -5189,8 +5604,8 @@ def originalTextFor(expr, asString=True): Example:: src = "this is test <b> bold <i>text</i> </b> normal text " - for tag in ("b","i"): - opener,closer = makeHTMLTags(tag) + for tag in ("b", "i"): + opener, closer = makeHTMLTags(tag) patt = originalTextFor(opener + SkipTo(closer) + closer) print(patt.searchString(src)[0]) @@ -5199,14 +5614,14 @@ def originalTextFor(expr, asString=True): ['<b> bold <i>text</i> </b>'] ['<i>text</i>'] """ - locMarker = Empty().setParseAction(lambda s,loc,t: loc) + locMarker = Empty().setParseAction(lambda s, loc, t: loc) endlocMarker = locMarker.copy() endlocMarker.callPreparse = False matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") if asString: - extractText = lambda s,l,t: s[t._original_start:t._original_end] + extractText = lambda s, l, t: s[t._original_start: t._original_end] else: - def extractText(s,l,t): + def extractText(s, l, t): t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] matchExpr.setParseAction(extractText) matchExpr.ignoreExprs = expr.ignoreExprs @@ -5216,7 +5631,7 @@ def ungroup(expr): """Helper to undo pyparsing's default grouping of And expressions, even if all but one are non-empty. """ - return TokenConverter(expr).addParseAction(lambda t:t[0]) + return TokenConverter(expr).addParseAction(lambda t: t[0]) def locatedExpr(expr): """Helper to decorate a returned token with its starting and ending @@ -5243,7 +5658,7 @@ def locatedExpr(expr): [[8, 'lksdjjf', 15]] [[18, 'lkkjj', 23]] """ - locator = Empty().setParseAction(lambda s,l,t: l) + locator = Empty().setParseAction(lambda s, l, t: l) return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) @@ -5254,12 +5669,12 @@ lineEnd = LineEnd().setName("lineEnd") stringStart = StringStart().setName("stringStart") stringEnd = StringEnd().setName("stringEnd") -_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) -_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16))) -_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8))) +_escapedPunc = Word(_bslash, r"\[]-*.$+^?()~ ", exact=2).setParseAction(lambda s, l, t: t[0][1]) +_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s, l, t: unichr(int(t[0].lstrip(r'\0x'), 16))) +_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s, l, t: unichr(int(t[0][1:], 8))) _singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1) _charRange = Group(_singleChar + Suppress("-") + _singleChar) -_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" +_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group(OneOrMore(_charRange | _singleChar)).setResultsName("body") + "]" def srange(s): r"""Helper to easily define string ranges for use in Word @@ -5287,7 +5702,7 @@ def srange(s): - any combination of the above (``'aeiouy'``, ``'a-zA-Z0-9_$'``, etc.) """ - _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1)) + _expanded = lambda p: p if not isinstance(p, ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]), ord(p[1]) + 1)) try: return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) except Exception: @@ -5297,9 +5712,9 @@ def matchOnlyAtCol(n): """Helper method for defining parse actions that require matching at a specific column in the input text. """ - def verifyCol(strg,locn,toks): - if col(locn,strg) != n: - raise ParseException(strg,locn,"matched token not at column %d" % n) + def verifyCol(strg, locn, toks): + if col(locn, strg) != n: + raise ParseException(strg, locn, "matched token not at column %d" % n) return verifyCol def replaceWith(replStr): @@ -5315,9 +5730,9 @@ def replaceWith(replStr): OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] """ - return lambda s,l,t: [replStr] + return lambda s, l, t: [replStr] -def removeQuotes(s,l,t): +def removeQuotes(s, l, t): """Helper parse action for removing quotation marks from parsed quoted strings. @@ -5368,7 +5783,7 @@ def tokenMap(func, *args): now is the winter of our discontent made glorious summer by this sun of york ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] """ - def pa(s,l,t): + def pa(s, l, t): return [func(tokn, *args) for tokn in t] try: @@ -5392,34 +5807,34 @@ def _makeTags(tagStr, xml, suppress_LT=Suppress("<"), suppress_GT=Suppress(">")): """Internal helper to construct opening and closing tag expressions, given a tag name""" - if isinstance(tagStr,basestring): + if isinstance(tagStr, basestring): resname = tagStr tagStr = Keyword(tagStr, caseless=not xml) else: resname = tagStr.name - tagAttrName = Word(alphas,alphanums+"_-:") - if (xml): - tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) + tagAttrName = Word(alphas, alphanums + "_-:") + if xml: + tagAttrValue = dblQuotedString.copy().setParseAction(removeQuotes) openTag = (suppress_LT + tagStr("tag") - + Dict(ZeroOrMore(Group(tagAttrName + Suppress("=") + tagAttrValue ))) - + Optional("/", default=[False])("empty").setParseAction(lambda s,l,t:t[0]=='/') + + Dict(ZeroOrMore(Group(tagAttrName + Suppress("=") + tagAttrValue))) + + Optional("/", default=[False])("empty").setParseAction(lambda s, l, t: t[0] == '/') + suppress_GT) else: - tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printables, excludeChars=">") + tagAttrValue = quotedString.copy().setParseAction(removeQuotes) | Word(printables, excludeChars=">") openTag = (suppress_LT + tagStr("tag") + Dict(ZeroOrMore(Group(tagAttrName.setParseAction(downcaseTokens) + Optional(Suppress("=") + tagAttrValue)))) - + Optional("/",default=[False])("empty").setParseAction(lambda s,l,t:t[0]=='/') + + Optional("/", default=[False])("empty").setParseAction(lambda s, l, t: t[0] == '/') + suppress_GT) closeTag = Combine(_L("</") + tagStr + ">", adjacent=False) openTag.setName("<%s>" % resname) # add start<tagname> results name in parse action now that ungrouped names are not reported at two levels - openTag.addParseAction(lambda t: t.__setitem__("start"+"".join(resname.replace(":"," ").title().split()), t.copy())) - closeTag = closeTag("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname) + openTag.addParseAction(lambda t: t.__setitem__("start" + "".join(resname.replace(":", " ").title().split()), t.copy())) + closeTag = closeTag("end" + "".join(resname.replace(":", " ").title().split())).setName("</%s>" % resname) openTag.tag = resname closeTag.tag = resname openTag.tag_body = SkipTo(closeTag()) @@ -5435,7 +5850,7 @@ def makeHTMLTags(tagStr): text = '<td>More info at the <a href="https://github.com/pyparsing/pyparsing/wiki">pyparsing</a> wiki page</td>' # makeHTMLTags returns pyparsing expressions for the opening and # closing tags as a 2-tuple - a,a_end = makeHTMLTags("A") + a, a_end = makeHTMLTags("A") link_expr = a + SkipTo(a_end)("link_text") + a_end for link in link_expr.searchString(text): @@ -5447,7 +5862,7 @@ def makeHTMLTags(tagStr): pyparsing -> https://github.com/pyparsing/pyparsing/wiki """ - return _makeTags( tagStr, False ) + return _makeTags(tagStr, False) def makeXMLTags(tagStr): """Helper to construct opening and closing tag expressions for XML, @@ -5455,9 +5870,9 @@ def makeXMLTags(tagStr): Example: similar to :class:`makeHTMLTags` """ - return _makeTags( tagStr, True ) + return _makeTags(tagStr, True) -def withAttribute(*args,**attrDict): +def withAttribute(*args, **attrDict): """Helper to create a validating parse action to be used with start tags created with :class:`makeXMLTags` or :class:`makeHTMLTags`. Use ``withAttribute`` to qualify @@ -5470,7 +5885,7 @@ def withAttribute(*args,**attrDict): - keyword arguments, as in ``(align="right")``, or - as an explicit dict with ``**`` operator, when an attribute name is also a Python reserved word, as in ``**{"class":"Customer", "align":"right"}`` - - a list of name-value tuples, as in ``(("ns1:class", "Customer"), ("ns2:align","right"))`` + - a list of name-value tuples, as in ``(("ns1:class", "Customer"), ("ns2:align", "right"))`` For attribute names with a namespace prefix, you must use the second form. Attribute names are matched insensitive to upper/lower case. @@ -5517,13 +5932,13 @@ def withAttribute(*args,**attrDict): attrs = args[:] else: attrs = attrDict.items() - attrs = [(k,v) for k,v in attrs] - def pa(s,l,tokens): - for attrName,attrValue in attrs: + attrs = [(k, v) for k, v in attrs] + def pa(s, l, tokens): + for attrName, attrValue in attrs: if attrName not in tokens: - raise ParseException(s,l,"no matching attribute " + attrName) + raise ParseException(s, l, "no matching attribute " + attrName) if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: - raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + raise ParseException(s, l, "attribute '%s' has value '%s', must be '%s'" % (attrName, tokens[attrName], attrValue)) return pa withAttribute.ANY_VALUE = object() @@ -5564,13 +5979,13 @@ def withClass(classname, namespace=''): 1,3 2,3 1,1 """ classattr = "%s:class" % namespace if namespace else "class" - return withAttribute(**{classattr : classname}) + return withAttribute(**{classattr: classname}) opAssoc = SimpleNamespace() opAssoc.LEFT = object() opAssoc.RIGHT = object() -def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): +def infixNotation(baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')')): """Helper method for constructing grammars of expressions made up of operators working in a precedence hierarchy. Operators may be unary or binary, left- or right-associative. Parse actions can also be @@ -5648,9 +6063,9 @@ def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): return loc, [] ret = Forward() - lastExpr = baseExpr | ( lpar + ret + rpar ) - for i,operDef in enumerate(opList): - opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] + lastExpr = baseExpr | (lpar + ret + rpar) + for i, operDef in enumerate(opList): + opExpr, arity, rightLeftAssoc, pa = (operDef + (None, ))[:4] termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr if arity == 3: if opExpr is None or len(opExpr) != 2: @@ -5660,15 +6075,15 @@ def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): thisExpr = Forward().setName(termName) if rightLeftAssoc == opAssoc.LEFT: if arity == 1: - matchExpr = _FB(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + matchExpr = _FB(lastExpr + opExpr) + Group(lastExpr + OneOrMore(opExpr)) elif arity == 2: if opExpr is not None: - matchExpr = _FB(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + matchExpr = _FB(lastExpr + opExpr + lastExpr) + Group(lastExpr + OneOrMore(opExpr + lastExpr)) else: - matchExpr = _FB(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + matchExpr = _FB(lastExpr + lastExpr) + Group(lastExpr + OneOrMore(lastExpr)) elif arity == 3: - matchExpr = _FB(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ - Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + matchExpr = (_FB(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + + Group(lastExpr + OneOrMore(opExpr1 + lastExpr + opExpr2 + lastExpr))) else: raise ValueError("operator must be unary (1), binary (2), or ternary (3)") elif rightLeftAssoc == opAssoc.RIGHT: @@ -5676,15 +6091,15 @@ def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): # try to avoid LR with this extra test if not isinstance(opExpr, Optional): opExpr = Optional(opExpr) - matchExpr = _FB(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + matchExpr = _FB(opExpr.expr + thisExpr) + Group(opExpr + thisExpr) elif arity == 2: if opExpr is not None: - matchExpr = _FB(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + matchExpr = _FB(lastExpr + opExpr + thisExpr) + Group(lastExpr + OneOrMore(opExpr + thisExpr)) else: - matchExpr = _FB(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + matchExpr = _FB(lastExpr + thisExpr) + Group(lastExpr + OneOrMore(thisExpr)) elif arity == 3: - matchExpr = _FB(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ - Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) + matchExpr = (_FB(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + + Group(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr)) else: raise ValueError("operator must be unary (1), binary (2), or ternary (3)") else: @@ -5694,7 +6109,7 @@ def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): matchExpr.setParseAction(*pa) else: matchExpr.setParseAction(pa) - thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) + thisExpr <<= (matchExpr.setName(termName) | lastExpr) lastExpr = thisExpr ret <<= lastExpr return ret @@ -5703,10 +6118,10 @@ operatorPrecedence = infixNotation """(Deprecated) Former name of :class:`infixNotation`, will be dropped in a future release.""" -dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes") -sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes") -quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'| - Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes") +dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*') + '"').setName("string enclosed in double quotes") +sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*") + "'").setName("string enclosed in single quotes") +quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*') + '"' + | Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*") + "'").setName("quotedString using single or double quotes") unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): @@ -5742,7 +6157,7 @@ def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.cop ident = Word(alphas+'_', alphanums+'_') number = pyparsing_common.number arg = Group(decl_data_type + ident) - LPAR,RPAR = map(Suppress, "()") + LPAR, RPAR = map(Suppress, "()") code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) @@ -5777,33 +6192,40 @@ def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.cop if opener == closer: raise ValueError("opening and closing strings cannot be the same") if content is None: - if isinstance(opener,basestring) and isinstance(closer,basestring): - if len(opener) == 1 and len(closer)==1: + if isinstance(opener, basestring) and isinstance(closer, basestring): + if len(opener) == 1 and len(closer) == 1: if ignoreExpr is not None: - content = (Combine(OneOrMore(~ignoreExpr + - CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) + content = (Combine(OneOrMore(~ignoreExpr + + CharsNotIn(opener + + closer + + ParserElement.DEFAULT_WHITE_CHARS, exact=1) + ) + ).setParseAction(lambda t: t[0].strip())) else: - content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS - ).setParseAction(lambda t:t[0].strip())) + content = (empty.copy() + CharsNotIn(opener + + closer + + ParserElement.DEFAULT_WHITE_CHARS + ).setParseAction(lambda t: t[0].strip())) else: if ignoreExpr is not None: - content = (Combine(OneOrMore(~ignoreExpr + - ~Literal(opener) + ~Literal(closer) + - CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) + content = (Combine(OneOrMore(~ignoreExpr + + ~Literal(opener) + + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS, exact=1)) + ).setParseAction(lambda t: t[0].strip())) else: - content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + - CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) - ).setParseAction(lambda t:t[0].strip())) + content = (Combine(OneOrMore(~Literal(opener) + + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS, exact=1)) + ).setParseAction(lambda t: t[0].strip())) else: raise ValueError("opening and closing arguments must be strings if no content expression is given") ret = Forward() if ignoreExpr is not None: - ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) + ret <<= Group(Suppress(opener) + ZeroOrMore(ignoreExpr | ret | content) + Suppress(closer)) else: - ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) - ret.setName('nested %s%s expression' % (opener,closer)) + ret <<= Group(Suppress(opener) + ZeroOrMore(ret | content) + Suppress(closer)) + ret.setName('nested %s%s expression' % (opener, closer)) return ret def indentedBlock(blockStatementExpr, indentStack, indent=True): @@ -5818,7 +6240,7 @@ def indentedBlock(blockStatementExpr, indentStack, indent=True): (multiple statementWithIndentedBlock expressions within a single grammar should share a common indentStack) - indent - boolean indicating whether block must be indented beyond - the the current level; set to False for block of left-most + the current level; set to False for block of left-most statements (default= ``True``) A valid block must contain at least one ``blockStatement``. @@ -5851,15 +6273,15 @@ def indentedBlock(blockStatementExpr, indentStack, indent=True): stmt = Forward() identifier = Word(alphas, alphanums) - funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") + funcDecl = ("def" + identifier + Group("(" + Optional(delimitedList(identifier)) + ")") + ":") func_body = indentedBlock(stmt, indentStack) - funcDef = Group( funcDecl + func_body ) + funcDef = Group(funcDecl + func_body) rvalue = Forward() funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") rvalue << (funcCall | identifier | Word(nums)) assignment = Group(identifier + "=" + rvalue) - stmt << ( funcDef | assignment | identifier ) + stmt << (funcDef | assignment | identifier) module_body = OneOrMore(stmt) @@ -5892,39 +6314,42 @@ def indentedBlock(blockStatementExpr, indentStack, indent=True): def reset_stack(): indentStack[:] = backup_stack - def checkPeerIndent(s,l,t): + def checkPeerIndent(s, l, t): if l >= len(s): return - curCol = col(l,s) + curCol = col(l, s) if curCol != indentStack[-1]: if curCol > indentStack[-1]: - raise ParseException(s,l,"illegal nesting") - raise ParseException(s,l,"not a peer entry") + raise ParseException(s, l, "illegal nesting") + raise ParseException(s, l, "not a peer entry") - def checkSubIndent(s,l,t): - curCol = col(l,s) + def checkSubIndent(s, l, t): + curCol = col(l, s) if curCol > indentStack[-1]: - indentStack.append( curCol ) + indentStack.append(curCol) else: - raise ParseException(s,l,"not a subentry") + raise ParseException(s, l, "not a subentry") - def checkUnindent(s,l,t): + def checkUnindent(s, l, t): if l >= len(s): return - curCol = col(l,s) - if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): - raise ParseException(s,l,"not an unindent") - indentStack.pop() + curCol = col(l, s) + if not(indentStack and curCol in indentStack): + raise ParseException(s, l, "not an unindent") + if curCol < indentStack[-1]: + indentStack.pop() - NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress(), stopOn=StringEnd()) INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT') PEER = Empty().setParseAction(checkPeerIndent).setName('') UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT') if indent: - smExpr = Group( Optional(NL) + - #~ FollowedBy(blockStatementExpr) + - INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) + smExpr = Group(Optional(NL) + + INDENT + + OneOrMore(PEER + Group(blockStatementExpr) + Optional(NL), stopOn=StringEnd()) + + UNDENT) else: - smExpr = Group( Optional(NL) + - (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + smExpr = Group(Optional(NL) + + OneOrMore(PEER + Group(blockStatementExpr) + Optional(NL), stopOn=StringEnd()) + + UNDENT) smExpr.setFailAction(lambda a, b, c, d: reset_stack()) blockStatementExpr.ignore(_bslash + LineEnd()) return smExpr.setName('indented block') @@ -5932,8 +6357,8 @@ def indentedBlock(blockStatementExpr, indentStack, indent=True): alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") -anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag')) -_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\'')) +anyOpenTag, anyCloseTag = makeHTMLTags(Word(alphas, alphanums + "_:").setName('any tag')) +_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(), '><& "\'')) commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity") def replaceHTMLEntity(t): """Helper parser action to replace common HTML entities with their special characters""" @@ -5950,7 +6375,7 @@ restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") "Comment of the form ``// ... (to end of line)``" -cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") +cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/' | dblSlashComment).setName("C++ style comment") "Comment of either form :class:`cStyleComment` or :class:`dblSlashComment`" javaStyleComment = cppStyleComment @@ -5959,10 +6384,10 @@ javaStyleComment = cppStyleComment pythonStyleComment = Regex(r"#.*").setName("Python style comment") "Comment of the form ``# ... (to end of line)``" -_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + - Optional( Word(" \t") + - ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem") -commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList") +_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + + Optional(Word(" \t") + + ~Literal(",") + ~LineEnd()))).streamline().setName("commaItem") +commaSeparatedList = delimitedList(Optional(quotedString.copy() | _commasepitem, default="")).setName("commaSeparatedList") """(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. @@ -6128,7 +6553,7 @@ class pyparsing_common: integer = Word(nums).setName("integer").setParseAction(convertToInteger) """expression that parses an unsigned integer, returns an int""" - hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16)) + hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int, 16)) """expression that parses a hexadecimal integer, returns an int""" signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) @@ -6142,10 +6567,10 @@ class pyparsing_common: """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" mixed_integer.addParseAction(sum) - real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat) + real = Regex(r'[+-]?(?:\d+\.\d*|\.\d+)').setName("real number").setParseAction(convertToFloat) """expression that parses a floating point number and returns a float""" - sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) + sci_real = Regex(r'[+-]?(?:\d+(?:[eE][+-]?\d+)|(?:\d+\.\d*|\.\d+)(?:[eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) """expression that parses a floating point number with optional scientific notation and returns a float""" @@ -6156,15 +6581,18 @@ class pyparsing_common: fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat) """any int or real number, returned as float""" - identifier = Word(alphas+'_', alphanums+'_').setName("identifier") + identifier = Word(alphas + '_', alphanums + '_').setName("identifier") """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address") "IPv4 address (``0.0.0.0 - 255.255.255.255``)" _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") - _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") - _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") + _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part) * 7).setName("full IPv6 address") + _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part) * (0, 6)) + + "::" + + Optional(_ipv6_part + (':' + _ipv6_part) * (0, 6)) + ).setName("short IPv6 address") _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") @@ -6191,7 +6619,7 @@ class pyparsing_common: [datetime.date(1999, 12, 31)] """ - def cvt_fn(s,l,t): + def cvt_fn(s, l, t): try: return datetime.strptime(t[0], fmt).date() except ValueError as ve: @@ -6216,7 +6644,7 @@ class pyparsing_common: [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] """ - def cvt_fn(s,l,t): + def cvt_fn(s, l, t): try: return datetime.strptime(t[0], fmt) except ValueError as ve: @@ -6241,7 +6669,7 @@ class pyparsing_common: # strip HTML links from normal text text = '<td>More info at the <a href="https://github.com/pyparsing/pyparsing/wiki">pyparsing</a> wiki page</td>' - td,td_end = makeHTMLTags("TD") + td, td_end = makeHTMLTags("TD") table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end print(table_text.parseString(text).body) @@ -6251,9 +6679,13 @@ class pyparsing_common: """ return pyparsing_common._html_stripper.transformString(tokens[0]) - _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') - + Optional( White(" \t") ) ) ).streamline().setName("commaItem") - comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list") + _commasepitem = Combine(OneOrMore(~Literal(",") + + ~LineEnd() + + Word(printables, excludeChars=',') + + Optional(White(" \t")))).streamline().setName("commaItem") + comma_separated_list = delimitedList(Optional(quotedString.copy() + | _commasepitem, default='') + ).setName("comma separated list") """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) @@ -6272,7 +6704,8 @@ class _lazyclassproperty(object): def __get__(self, obj, cls): if cls is None: cls = type(obj) - if not hasattr(cls, '_intern') or any(cls._intern is getattr(superclass, '_intern', []) for superclass in cls.__mro__[1:]): + if not hasattr(cls, '_intern') or any(cls._intern is getattr(superclass, '_intern', []) + for superclass in cls.__mro__[1:]): cls._intern = {} attrname = self.fn.__name__ if attrname not in cls._intern: @@ -6303,7 +6736,7 @@ class unicode_set(object): if cc is unicode_set: break for rr in cc._ranges: - ret.extend(range(rr[0], rr[-1]+1)) + ret.extend(range(rr[0], rr[-1] + 1)) return [unichr(c) for c in sorted(set(ret))] @_lazyclassproperty @@ -6359,27 +6792,27 @@ class pyparsing_unicode(unicode_set): class Chinese(unicode_set): "Unicode set for Chinese Unicode Character Range" - _ranges = [(0x4e00, 0x9fff), (0x3000, 0x303f), ] + _ranges = [(0x4e00, 0x9fff), (0x3000, 0x303f),] class Japanese(unicode_set): "Unicode set for Japanese Unicode Character Range, combining Kanji, Hiragana, and Katakana ranges" - _ranges = [ ] + _ranges = [] class Kanji(unicode_set): "Unicode set for Kanji Unicode Character Range" - _ranges = [(0x4E00, 0x9Fbf), (0x3000, 0x303f), ] + _ranges = [(0x4E00, 0x9Fbf), (0x3000, 0x303f),] class Hiragana(unicode_set): "Unicode set for Hiragana Unicode Character Range" - _ranges = [(0x3040, 0x309f), ] + _ranges = [(0x3040, 0x309f),] class Katakana(unicode_set): "Unicode set for Katakana Unicode Character Range" - _ranges = [(0x30a0, 0x30ff), ] + _ranges = [(0x30a0, 0x30ff),] class Korean(unicode_set): "Unicode set for Korean Unicode Character Range" - _ranges = [(0xac00, 0xd7af), (0x1100, 0x11ff), (0x3130, 0x318f), (0xa960, 0xa97f), (0xd7b0, 0xd7ff), (0x3000, 0x303f), ] + _ranges = [(0xac00, 0xd7af), (0x1100, 0x11ff), (0x3130, 0x318f), (0xa960, 0xa97f), (0xd7b0, 0xd7ff), (0x3000, 0x303f),] class CJK(Chinese, Japanese, Korean): "Unicode set for combined Chinese, Japanese, and Korean (CJK) Unicode Character Range" @@ -6387,15 +6820,15 @@ class pyparsing_unicode(unicode_set): class Thai(unicode_set): "Unicode set for Thai Unicode Character Range" - _ranges = [(0x0e01, 0x0e3a), (0x0e3f, 0x0e5b), ] + _ranges = [(0x0e01, 0x0e3a), (0x0e3f, 0x0e5b),] class Arabic(unicode_set): "Unicode set for Arabic Unicode Character Range" - _ranges = [(0x0600, 0x061b), (0x061e, 0x06ff), (0x0700, 0x077f), ] + _ranges = [(0x0600, 0x061b), (0x061e, 0x06ff), (0x0700, 0x077f),] class Hebrew(unicode_set): "Unicode set for Hebrew Unicode Character Range" - _ranges = [(0x0590, 0x05ff), ] + _ranges = [(0x0590, 0x05ff),] class Devanagari(unicode_set): "Unicode set for Devanagari Unicode Character Range" @@ -6407,18 +6840,199 @@ pyparsing_unicode.Japanese._ranges = (pyparsing_unicode.Japanese.Kanji._ranges # define ranges in language character sets if PY_3: - setattr(pyparsing_unicode, "العربية", pyparsing_unicode.Arabic) - setattr(pyparsing_unicode, "中文", pyparsing_unicode.Chinese) - setattr(pyparsing_unicode, "кириллица", pyparsing_unicode.Cyrillic) - setattr(pyparsing_unicode, "Ελληνικά", pyparsing_unicode.Greek) - setattr(pyparsing_unicode, "עִברִית", pyparsing_unicode.Hebrew) - setattr(pyparsing_unicode, "日本語", pyparsing_unicode.Japanese) - setattr(pyparsing_unicode.Japanese, "漢字", pyparsing_unicode.Japanese.Kanji) - setattr(pyparsing_unicode.Japanese, "カタカナ", pyparsing_unicode.Japanese.Katakana) - setattr(pyparsing_unicode.Japanese, "ひらがな", pyparsing_unicode.Japanese.Hiragana) - setattr(pyparsing_unicode, "한국어", pyparsing_unicode.Korean) - setattr(pyparsing_unicode, "ไทย", pyparsing_unicode.Thai) - setattr(pyparsing_unicode, "देवनागरी", pyparsing_unicode.Devanagari) + setattr(pyparsing_unicode, u"العربية", pyparsing_unicode.Arabic) + setattr(pyparsing_unicode, u"中文", pyparsing_unicode.Chinese) + setattr(pyparsing_unicode, u"кириллица", pyparsing_unicode.Cyrillic) + setattr(pyparsing_unicode, u"Ελληνικά", pyparsing_unicode.Greek) + setattr(pyparsing_unicode, u"עִברִית", pyparsing_unicode.Hebrew) + setattr(pyparsing_unicode, u"日本語", pyparsing_unicode.Japanese) + setattr(pyparsing_unicode.Japanese, u"漢字", pyparsing_unicode.Japanese.Kanji) + setattr(pyparsing_unicode.Japanese, u"カタカナ", pyparsing_unicode.Japanese.Katakana) + setattr(pyparsing_unicode.Japanese, u"ひらがな", pyparsing_unicode.Japanese.Hiragana) + setattr(pyparsing_unicode, u"한국어", pyparsing_unicode.Korean) + setattr(pyparsing_unicode, u"ไทย", pyparsing_unicode.Thai) + setattr(pyparsing_unicode, u"देवनागरी", pyparsing_unicode.Devanagari) + + +class pyparsing_test: + """ + namespace class for classes useful in writing unit tests + """ + + class reset_pyparsing_context: + """ + Context manager to be used when writing unit tests that modify pyparsing config values: + - packrat parsing + - default whitespace characters. + - default keyword characters + - literal string auto-conversion class + - __diag__ settings + + Example: + with reset_pyparsing_context(): + # test that literals used to construct a grammar are automatically suppressed + ParserElement.inlineLiteralsUsing(Suppress) + + term = Word(alphas) | Word(nums) + group = Group('(' + term[...] + ')') + + # assert that the '()' characters are not included in the parsed tokens + self.assertParseAndCheckLisst(group, "(abc 123 def)", ['abc', '123', 'def']) + + # after exiting context manager, literals are converted to Literal expressions again + """ + + def __init__(self): + self._save_context = {} + + def save(self): + self._save_context["default_whitespace"] = ParserElement.DEFAULT_WHITE_CHARS + self._save_context["default_keyword_chars"] = Keyword.DEFAULT_KEYWORD_CHARS + self._save_context[ + "literal_string_class" + ] = ParserElement._literalStringClass + self._save_context["packrat_enabled"] = ParserElement._packratEnabled + self._save_context["packrat_parse"] = ParserElement._parse + self._save_context["__diag__"] = { + name: getattr(__diag__, name) for name in __diag__._all_names + } + self._save_context["__compat__"] = { + "collect_all_And_tokens": __compat__.collect_all_And_tokens + } + return self + + def restore(self): + # reset pyparsing global state + if ( + ParserElement.DEFAULT_WHITE_CHARS + != self._save_context["default_whitespace"] + ): + ParserElement.setDefaultWhitespaceChars( + self._save_context["default_whitespace"] + ) + Keyword.DEFAULT_KEYWORD_CHARS = self._save_context["default_keyword_chars"] + ParserElement.inlineLiteralsUsing( + self._save_context["literal_string_class"] + ) + for name, value in self._save_context["__diag__"].items(): + setattr(__diag__, name, value) + ParserElement._packratEnabled = self._save_context["packrat_enabled"] + ParserElement._parse = self._save_context["packrat_parse"] + __compat__.collect_all_And_tokens = self._save_context["__compat__"] + + def __enter__(self): + return self.save() + + def __exit__(self, *args): + return self.restore() + + class TestParseResultsAsserts: + """ + A mixin class to add parse results assertion methods to normal unittest.TestCase classes. + """ + def assertParseResultsEquals( + self, result, expected_list=None, expected_dict=None, msg=None + ): + """ + Unit test assertion to compare a ParseResults object with an optional expected_list, + and compare any defined results names with an optional expected_dict. + """ + if expected_list is not None: + self.assertEqual(expected_list, result.asList(), msg=msg) + if expected_dict is not None: + self.assertEqual(expected_dict, result.asDict(), msg=msg) + + def assertParseAndCheckList( + self, expr, test_string, expected_list, msg=None, verbose=True + ): + """ + Convenience wrapper assert to test a parser element and input string, and assert that + the resulting ParseResults.asList() is equal to the expected_list. + """ + result = expr.parseString(test_string, parseAll=True) + if verbose: + print(result.dump()) + self.assertParseResultsEquals(result, expected_list=expected_list, msg=msg) + + def assertParseAndCheckDict( + self, expr, test_string, expected_dict, msg=None, verbose=True + ): + """ + Convenience wrapper assert to test a parser element and input string, and assert that + the resulting ParseResults.asDict() is equal to the expected_dict. + """ + result = expr.parseString(test_string, parseAll=True) + if verbose: + print(result.dump()) + self.assertParseResultsEquals(result, expected_dict=expected_dict, msg=msg) + + def assertRunTestResults( + self, run_tests_report, expected_parse_results=None, msg=None + ): + """ + Unit test assertion to evaluate output of ParserElement.runTests(). If a list of + list-dict tuples is given as the expected_parse_results argument, then these are zipped + with the report tuples returned by runTests and evaluated using assertParseResultsEquals. + Finally, asserts that the overall runTests() success value is True. + + :param run_tests_report: tuple(bool, [tuple(str, ParseResults or Exception)]) returned from runTests + :param expected_parse_results (optional): [tuple(str, list, dict, Exception)] + """ + run_test_success, run_test_results = run_tests_report + + if expected_parse_results is not None: + merged = [ + (rpt[0], rpt[1], expected) + for rpt, expected in zip(run_test_results, expected_parse_results) + ] + for test_string, result, expected in merged: + # expected should be a tuple containing a list and/or a dict or an exception, + # and optional failure message string + # an empty tuple will skip any result validation + fail_msg = next( + (exp for exp in expected if isinstance(exp, str)), None + ) + expected_exception = next( + ( + exp + for exp in expected + if isinstance(exp, type) and issubclass(exp, Exception) + ), + None, + ) + if expected_exception is not None: + with self.assertRaises( + expected_exception=expected_exception, msg=fail_msg or msg + ): + if isinstance(result, Exception): + raise result + else: + expected_list = next( + (exp for exp in expected if isinstance(exp, list)), None + ) + expected_dict = next( + (exp for exp in expected if isinstance(exp, dict)), None + ) + if (expected_list, expected_dict) != (None, None): + self.assertParseResultsEquals( + result, + expected_list=expected_list, + expected_dict=expected_dict, + msg=fail_msg or msg, + ) + else: + # warning here maybe? + print("no validation for {!r}".format(test_string)) + + # do this last, in case some specific test results can be reported instead + self.assertTrue( + run_test_success, msg=msg if msg is not None else "failed runTests" + ) + + @contextmanager + def assertRaisesParseException(self, exc_type=ParseException, msg=None): + with self.assertRaises(exc_type, msg=msg): + yield if __name__ == "__main__": diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__init__.py deleted file mode 100644 index 8ed060f..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .core import TomlError -from .parser import load, loads -from .test import translate_to_test -from .writer import dump, dumps \ No newline at end of file diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 0399b6e14c5ec9e796b9c61746572bbbdb160cf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 337 zcmYjMu};J=3~k!9*PeP3d`5?(5-?VXg_Q+ZIuJ!95|xrBa?*pF_#QUCCo2Qu7nra+ zoh84#=NCK9({8uTFn$hS&mVYxlQ@kW#VuwS5LBj^$t)WgBc7Yw7Gq)g$X8vM(pF=& za&9)Z9&6i-4eIhC>#ARdBRZCvM`z6)fP*ei+&HOHNf^*Ok09q@WYi)$5p{@kM=jQ; zk}%wN+r(cSXrRqf<s}3SP@n)#6;4f1uI3v|5zUIs4Z>#zEpdXsp^w)0e)9Wi4pADj wzkI!3-mjdb;+o>1XXT*x$A~NULQL}%g}Cs?R1emv#poOQRG=4HcE(!v53-R~Pyhe` diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/core.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/core.cpython-38.pyc deleted file mode 100644 index 7015fffd72158516cfddf7849b1ebed9cb5740ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 914 zcmbVKJ8u&~5T3o;dnDMAh$twDM3Iw-EdfP@P!tIvIu|?|7pzXVYdGs(?4BcHpR44D zBxO2&&$bl&06HWjX4bN0BP!-JvokxpJKubBANu`$K>2a;?c;9-@STEf;TW8wng?j! zfCR~|Q59VIV<x?KkoXy9cErQz9MwEVqX5sr*pqnr8pgi#CC8P^K!&&mGQu}vyZ62> zi`QD$It%dDTF8%3U!j@-nig(Y2OaCY&hPkbz{m&TVGP2@JrKO(XafoOFdHSI?Y*5< zZC)z(yp4s(tGpG$Mx`<){iG}}@=94hs|y=X@<LT<sgl5Qql$?p1~lQ&AsIq*2YL^e zU#G*iY=%wVoaB{h)1o+e`uX|n>$5tgO{d~QRkGH@=CZ{Ghgq%Fpt;mOUMHH2W1k(e z(0%j64Gn`e%nZk}5%LL!<KrPZlHEWDQ{-TZ3{0{ADZk~|xi^|0ESATM<&#H?W%7bd zV8cnR%d~Y(Z1qGf-Z35H;u>2Sf@UKjOsj>Uehnc8How0O(q;c2<I(1=<HeCCuz%Sk z3G_WI`>#3Z9wi9c7Gj*QRt-X?<Qno0ud6iu8F-dvjsL>F5M?cA1^GQ8zRc2Mm2soe teX4P=DYRQs(^N<ejV5Ms6#H&(lz5srbHNr)ciqt&zg$&4qw7CW;Sa7=z7hZc diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/parser.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/parser.cpython-38.pyc deleted file mode 100644 index 3d691beeea0a9985b202f498f49054e66e3d84d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10111 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 `&kbwNEnwCVH zyV!b#W))}NT!MvG^ZgP8&HWN!g8G!}5GGXVE;3*wKpu`~SS`jm*CBl1T(kkcr$Y;W z`#ojQ{@=JKT$ri92bBy+S#U`PHPbDJ`)Za9Q2#&~zK`@eMA(AMCkMS@PF-8(LR+^2 z*4Q{)jmIAfa$K{nYxa7!QF}y=;L4n^Z8Wsk9bAUJDGPmSOjD{P$3r{F6SC<(<rDZG z#bNC+9M#672zi`G`A;Bl0%my~#)w#zu5rS|&RBpL7SZg)=h|e9ohJx0`!z_SlQc{4 z$R!WN#`izy8SRG$>z!a}Jc*;H!PPp6(M|QY!Li<$0!P!}18e^jmH2-V9H$aojK(!+ zOkDhfi(bw?kLcN%@8@$b;12zN(Xaa}_x8ZtcoRJ)h%c<_=>zkaAgOTFHif(HKyBiL zc%{{<zZ)g0xRLX&GpcmV>FJI&Jw2_?K;zYqDEWO#ICA|ls3;|IPY~1^*t)swIwCO} z34FbQo^UE0sQak)h`@ADEb`sYo_KCgEURg1E<TAwcTap%J%_L2qz=edKx?1D=ryvB zUK*zu*nUEl2*uPNP(s+HXbYrcwFFV*u<87d*dTm+g)(<3A)Yw4VK)aC)Yf-jI;f)v zguzOY&nhN$urx-wrzv3=Tm=;+=;q4Tr|1L<I=Z32M*TICpX2d6NDPsJ=OGv*4@7@i ze(N-b$Slr;>6BNWJe@+_0%%(}I2SIUgwBKM7Kd6>O**5}x$tbD^cR)WH=Pq_P3GeW zfb};7KLc-2l7j&D87m^740kGkGBPdwA0$?B_ZsJL9r9}*^>b`^HGqr`Oyb;)Z?F== z@4@IS+=Y`$#$Vr)cGE<_gL~8}&Z%_kZX#~Wbs6g7oB%Kc^G@P_7&tOT=7UWNw=Jd@ z)R&lz`cq2&oRTY)kYXv?KInVL%b>8LypF7A`-^>@DzR?S+8tT;D23|+eNkY;;rWq; zR9`6^Tza_8HV&8@!4;T^e*t}A`LP(ZEb)`$ZyPBc`s@6xP+y^L=QQ~u+5lVx(c1$Q zUq;~nY%dOn)9L>#P&E8&czlY_C@`g~dj>?~hu0u=bBE4wNN%DJix!8Hy*T7?bvDip zz+%6@9Y=?th&;>%mMG*zn*<#%693wUYM>D3kr;fhP1ffkC*FjUE#WGP3J+}v)Ni8b zO%mKV2-@J1o|BL=;uPqV;2OpAk%Pbm|2algsV~dF<Et--vMacn<n45X|N2m?`)VHx zvbQ|t*IG>+>Q`HlgMby$sG?&f-2EUfwIy!+_&+M})e7&&C=hM5@!x#Z$Ec_0N+zvX zaej{|hN62!ZBz2Qlzd9b14{mg5(<6PUs3Xq5(X;9EmAdJcJ((z(d-8#!ivTFq}06L z%wjzun^%xb!NT)q4(MQ;1#A4ba_>R8Ed7{<`3nbh{Ff~tKcDGgPwK7I@r?K%m$*|~ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/test.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/test.cpython-38.pyc deleted file mode 100644 index e208799f207d2a0b3a49310c7edf441b2af0b128..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1216 zcmah|J8u&~5Z>K;_<XVRQWOakM3A6x5gRZP5JeFZp-GV<0Ra|Z9k*+9<X-Hqt=O@f zI29eDrAX+~@dNk~)LTM<@)wYhn7vDg6AJb;b2l?Pv)?zf_oQ5Q5v-rxFRy+Z2>sB; z_;SE_03tR)QABZw8i*2Vgg7D%f>D2t8O&^vhQ(}FfVcA$#S124#ch|bVWb~s=xD=v zj$-l*QIlHxsNqt)g(~(j)I}S|7<2`z$yUN6Pd0hWuh;AMeeFJ71U^iVhaloRD2WD0 z;t}Bs6jQPf)&V(0YiI<8vzP&~$JC&vj%oi84-jA1F=}1PbJqv3o7w|R3!lhIp83{< z%$PdT8bH=q#0LL+T7)Wl)Qt(97>gAk_L-KXb0Mb){;#x5ClA~KIvlSy0g-QX3ee<d zm*{l9XN31KMbMs^jdLx42_Xw)OSj-Mr~s(EoP9xtct{2qh>;QgNZy%S=m;HQH6ytf zi_nv-DU+sTLRJh#sy7whR=CS`H#7C?UQI@6Ee+D8AQsXK!=>AA?sRtQiKm^JG`lRO z39qF+nM7et7ptZ{<*v}cmwpnZt7VPK24%xTQ2)k1r&m|P#P>q6T0P4;NAPsU8NoRy z)z$<{Lro2j@P~|Aj$8MkLU;jQ3h$h8;rc=YtS}HctSPXCruu(Se{;CLc*^oP_j(ng zOxa7BvbtW_ValP<PZ>l^nXi*1gdhj6)dF5j6@pl@HsfH2i6{H^?sE0k-J!CD<U!o- z&v#<BlQLg2x|o$)UfjLLhn2E&1CjMU_Mx!usj>peBB4x;iq8NbuIJBZH8i&g2Q@V; zp$rJ~dF{3H-$#|3`Ee&3N}HWn1AfGL!l7qHy%&2IddBtWCP2h>Pzbwt7Gx5%NnBil zuTzhUr{UYhSw>|d!=|i`3__7ZyaM^E(1`;-p^RVEmH~KyN)osEg0_nr-U*<r${3dH dR%SzVR-%M<Lbj@>A*Mk&xI_pB4QNd4l0VESC~yD( diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/utils.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/utils.cpython-38.pyc deleted file mode 100644 index f6f9254e459a26b532a0f51e4ccf975ea119b5f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2126 zcmZ`)&2HO95Z+l*6eY)wlDJM<q(G2Hg#}l#V+SZA1dY)i>Pw6QP7hVx5`vaW6zi|c zb&$y9p>W#gkdD6f*k{>m4~1VLr+%}H;-54WW_EXmJHwgzX7uCYVp-t%_vK%|{vHVN z4<F7yJ`UTUWCu(MMSaoAS87pAQ>o;PTAuQh|3<WYRZs!ef-0&IYw*2LB~^YSR5=ze zipO3nRJ12*3#YIqb|*iq?yI8*S*_0N=Gpr6-MM*bUEOc&tF_wW)yK_Ny8824{g?dS z{JmO-*zmhYV)a1Zfs$1)Bc_y!8D*4`zMb;d(+rXWPv22uPZ%$yWBxw5tJzS^w`JY! zY;A2ljC5=ZgSP2Bw}oeVbU3z^aa$*Gbf&LKOD`=APJ|9|`R&7XGZ?Rrd*ga<n3#6I zU*CNG;PBPfsLeu0(aU(KMtXhx+KdMM^+VI^CynuIyLiDi>LL<0DX2`>$tTS<yAUc1 z7C<i4zp*jGAh4;NxnlhxKNZIkVT-B91=AbGpYM+;lS5y5nRF5#+E?x_N;)G|IF>3{ z&aHW>m`iSo%rgZOOpD4(J=V`8?D)gVT&lcWlG1*V6*7?pSuqQ<67B?PAr)zm7Sk{- z!IM<svN)#HpM^+$Y4?=lJuQN{BAjyMryStvBW5MA-uAawMJ=@6pgp!;Z)j}bijru? zt1Wc<qqec7=xJ{dw?@O*hN^91gOe>WS8?C8Yh}$&ENN7>*U=+O&#W{PORp^{OFNdH zSlV;N%o)4Z1+XiiWEo7*3Tjf3zAV!{T9Fl5A@|0G>M#g7C|8|7u|cNAOfU?UI4J2m z$O6DPLlzW$CWdG#r;`U#Z*paZ4ZJB2e7&uFoXV<zYS98Ls9@@)*z-N+D`Ms<`NG!* zUeJgDxV#B)yHhwnG2D@BeHCBh(rl^qme$@<eNs8v$d2weH#W28(IzjG<?2uM>Y!d# zPpdo4>XT-5uTkwzu6-b_1-5i(I-_nkiH*Jv({|B}0R1S5JENgWY|tHPbdg<f3D2cA zOpNYwS!$l<G+Cc5*dRIVc6+Zb<=-ylCgzRzIW8o(zyyVKTZR-k@+m+$0$P%K4Z04$ zaQ@-hunkJS0*gfpg=k?KD2b`{(P^eiNLpEcf-4<1Fn@T@<m$^vP0?u)I&V*$(C!J@ zVwC3uBf?MOe%A)?a>Up^!<G%Bs5k7HD7p`M;#|<=`g<5R=IRf;^R#l_Ie)2m0neHv z({->Dsn@Yssm!Hh>U)qs0L^{fIP>+skRNx(&Bj6Iu3Rje5M6R&J(ZZR&pBB<a{|o; z^W0oaE|wi^IF>14iUHriJUZh*=)33%pdR?=$>sCj>3wv9uV`7^f<_glGWAl(W**8G zoWr{Q0+#h%u*uR<cGPSD<T(cd8?37``x2~HaJkc4EO6t(({W<y`Q;!3Ga0rAaTD() z6)-_d0HjZ$1kn|mRL-K#U)`-0x!`;&iflQG1|xOY=lzu^`t7jY&o!E{;0mR=QkpY) z&biCF8%zw#4Uqe*2r2aV=fGMk=@lrf#GhEPGa8J0{a7=)+#iXXSFTGeg6Iv=Uu^3C aeAw_&{*m7>;1V8#a3sqz48m*SjsF0fi^cK) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/writer.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/__pycache__/writer.cpython-38.pyc deleted file mode 100644 index 82c5535ff2eca20ea99886a73d03558105296475..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3557 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 GbN>Z`+!rDM diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/core.py b/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/core.py deleted file mode 100644 index c182734..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/core.py +++ /dev/null @@ -1,13 +0,0 @@ -class TomlError(RuntimeError): - def __init__(self, message, line, col, filename): - RuntimeError.__init__(self, message, line, col, filename) - self.message = message - self.line = line - self.col = col - self.filename = filename - - def __str__(self): - return '{}({}, {}): {}'.format(self.filename, self.line, self.col, self.message) - - def __repr__(self): - return 'TomlError({!r}, {!r}, {!r}, {!r})'.format(self.message, self.line, self.col, self.filename) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/parser.py b/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/parser.py deleted file mode 100644 index 3493aa6..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/parser.py +++ /dev/null @@ -1,341 +0,0 @@ -import string, re, sys, datetime -from .core import TomlError -from .utils import rfc3339_re, parse_rfc3339_re - -if sys.version_info[0] == 2: - _chr = unichr -else: - _chr = chr - -def load(fin, translate=lambda t, x, v: v, object_pairs_hook=dict): - return loads(fin.read(), translate=translate, object_pairs_hook=object_pairs_hook, filename=getattr(fin, 'name', repr(fin))) - -def loads(s, filename='<string>', translate=lambda t, x, v: v, object_pairs_hook=dict): - if isinstance(s, bytes): - s = s.decode('utf-8') - - s = s.replace('\r\n', '\n') - - root = object_pairs_hook() - tables = object_pairs_hook() - scope = root - - src = _Source(s, filename=filename) - ast = _p_toml(src, object_pairs_hook=object_pairs_hook) - - def error(msg): - raise TomlError(msg, pos[0], pos[1], filename) - - def process_value(v, object_pairs_hook): - kind, text, value, pos = v - if kind == 'str' and value.startswith('\n'): - value = value[1:] - if kind == 'array': - if value and any(k != value[0][0] for k, t, v, p in value[1:]): - error('array-type-mismatch') - value = [process_value(item, object_pairs_hook=object_pairs_hook) for item in value] - elif kind == 'table': - value = object_pairs_hook([(k, process_value(value[k], object_pairs_hook=object_pairs_hook)) for k in value]) - return translate(kind, text, value) - - for kind, value, pos in ast: - if kind == 'kv': - k, v = value - if k in scope: - error('duplicate_keys. Key "{0}" was used more than once.'.format(k)) - scope[k] = process_value(v, object_pairs_hook=object_pairs_hook) - else: - is_table_array = (kind == 'table_array') - cur = tables - for name in value[:-1]: - if isinstance(cur.get(name), list): - d, cur = cur[name][-1] - else: - d, cur = cur.setdefault(name, (None, object_pairs_hook())) - - scope = object_pairs_hook() - name = value[-1] - if name not in cur: - if is_table_array: - cur[name] = [(scope, object_pairs_hook())] - else: - cur[name] = (scope, object_pairs_hook()) - elif isinstance(cur[name], list): - if not is_table_array: - error('table_type_mismatch') - cur[name].append((scope, object_pairs_hook())) - else: - if is_table_array: - error('table_type_mismatch') - old_scope, next_table = cur[name] - if old_scope is not None: - error('duplicate_tables') - cur[name] = (scope, next_table) - - def merge_tables(scope, tables): - if scope is None: - scope = object_pairs_hook() - for k in tables: - if k in scope: - error('key_table_conflict') - v = tables[k] - if isinstance(v, list): - scope[k] = [merge_tables(sc, tbl) for sc, tbl in v] - else: - scope[k] = merge_tables(v[0], v[1]) - return scope - - return merge_tables(root, tables) - -class _Source: - def __init__(self, s, filename=None): - self.s = s - self._pos = (1, 1) - self._last = None - self._filename = filename - self.backtrack_stack = [] - - def last(self): - return self._last - - def pos(self): - return self._pos - - def fail(self): - return self._expect(None) - - def consume_dot(self): - if self.s: - self._last = self.s[0] - self.s = self[1:] - self._advance(self._last) - return self._last - return None - - def expect_dot(self): - return self._expect(self.consume_dot()) - - def consume_eof(self): - if not self.s: - self._last = '' - return True - return False - - def expect_eof(self): - return self._expect(self.consume_eof()) - - def consume(self, s): - if self.s.startswith(s): - self.s = self.s[len(s):] - self._last = s - self._advance(s) - return True - return False - - def expect(self, s): - return self._expect(self.consume(s)) - - def consume_re(self, re): - m = re.match(self.s) - if m: - self.s = self.s[len(m.group(0)):] - self._last = m - self._advance(m.group(0)) - return m - return None - - def expect_re(self, re): - return self._expect(self.consume_re(re)) - - def __enter__(self): - self.backtrack_stack.append((self.s, self._pos)) - - def __exit__(self, type, value, traceback): - if type is None: - self.backtrack_stack.pop() - else: - self.s, self._pos = self.backtrack_stack.pop() - return type == TomlError - - def commit(self): - self.backtrack_stack[-1] = (self.s, self._pos) - - def _expect(self, r): - if not r: - raise TomlError('msg', self._pos[0], self._pos[1], self._filename) - return r - - def _advance(self, s): - suffix_pos = s.rfind('\n') - if suffix_pos == -1: - self._pos = (self._pos[0], self._pos[1] + len(s)) - else: - self._pos = (self._pos[0] + s.count('\n'), len(s) - suffix_pos) - -_ews_re = re.compile(r'(?:[ \t]|#[^\n]*\n|#[^\n]*\Z|\n)*') -def _p_ews(s): - s.expect_re(_ews_re) - -_ws_re = re.compile(r'[ \t]*') -def _p_ws(s): - s.expect_re(_ws_re) - -_escapes = { 'b': '\b', 'n': '\n', 'r': '\r', 't': '\t', '"': '"', - '\\': '\\', 'f': '\f' } - -_basicstr_re = re.compile(r'[^"\\\000-\037]*') -_short_uni_re = re.compile(r'u([0-9a-fA-F]{4})') -_long_uni_re = re.compile(r'U([0-9a-fA-F]{8})') -_escapes_re = re.compile(r'[btnfr\"\\]') -_newline_esc_re = re.compile('\n[ \t\n]*') -def _p_basicstr_content(s, content=_basicstr_re): - res = [] - while True: - res.append(s.expect_re(content).group(0)) - if not s.consume('\\'): - break - if s.consume_re(_newline_esc_re): - pass - elif s.consume_re(_short_uni_re) or s.consume_re(_long_uni_re): - v = int(s.last().group(1), 16) - if 0xd800 <= v < 0xe000: - s.fail() - res.append(_chr(v)) - else: - s.expect_re(_escapes_re) - res.append(_escapes[s.last().group(0)]) - return ''.join(res) - -_key_re = re.compile(r'[0-9a-zA-Z-_]+') -def _p_key(s): - with s: - s.expect('"') - r = _p_basicstr_content(s, _basicstr_re) - s.expect('"') - return r - if s.consume('\''): - if s.consume('\'\''): - r = s.expect_re(_litstr_ml_re).group(0) - s.expect('\'\'\'') - else: - r = s.expect_re(_litstr_re).group(0) - s.expect('\'') - return r - return s.expect_re(_key_re).group(0) - -_float_re = re.compile(r'[+-]?(?:0|[1-9](?:_?\d)*)(?:\.\d(?:_?\d)*)?(?:[eE][+-]?(?:\d(?:_?\d)*))?') - -_basicstr_ml_re = re.compile(r'(?:""?(?!")|[^"\\\000-\011\013-\037])*') -_litstr_re = re.compile(r"[^'\000\010\012-\037]*") -_litstr_ml_re = re.compile(r"(?:(?:|'|'')(?:[^'\000-\010\013-\037]))*") -def _p_value(s, object_pairs_hook): - pos = s.pos() - - if s.consume('true'): - return 'bool', s.last(), True, pos - if s.consume('false'): - return 'bool', s.last(), False, pos - - if s.consume('"'): - if s.consume('""'): - r = _p_basicstr_content(s, _basicstr_ml_re) - s.expect('"""') - else: - r = _p_basicstr_content(s, _basicstr_re) - s.expect('"') - return 'str', r, r, pos - - if s.consume('\''): - if s.consume('\'\''): - r = s.expect_re(_litstr_ml_re).group(0) - s.expect('\'\'\'') - else: - r = s.expect_re(_litstr_re).group(0) - s.expect('\'') - return 'str', r, r, pos - - if s.consume_re(rfc3339_re): - m = s.last() - return 'datetime', m.group(0), parse_rfc3339_re(m), pos - - if s.consume_re(_float_re): - m = s.last().group(0) - r = m.replace('_','') - if '.' in m or 'e' in m or 'E' in m: - return 'float', m, float(r), pos - else: - return 'int', m, int(r, 10), pos - - if s.consume('['): - items = [] - with s: - while True: - _p_ews(s) - items.append(_p_value(s, object_pairs_hook=object_pairs_hook)) - s.commit() - _p_ews(s) - s.expect(',') - s.commit() - _p_ews(s) - s.expect(']') - return 'array', None, items, pos - - if s.consume('{'): - _p_ws(s) - items = object_pairs_hook() - if not s.consume('}'): - k = _p_key(s) - _p_ws(s) - s.expect('=') - _p_ws(s) - items[k] = _p_value(s, object_pairs_hook=object_pairs_hook) - _p_ws(s) - while s.consume(','): - _p_ws(s) - k = _p_key(s) - _p_ws(s) - s.expect('=') - _p_ws(s) - items[k] = _p_value(s, object_pairs_hook=object_pairs_hook) - _p_ws(s) - s.expect('}') - return 'table', None, items, pos - - s.fail() - -def _p_stmt(s, object_pairs_hook): - pos = s.pos() - if s.consume( '['): - is_array = s.consume('[') - _p_ws(s) - keys = [_p_key(s)] - _p_ws(s) - while s.consume('.'): - _p_ws(s) - keys.append(_p_key(s)) - _p_ws(s) - s.expect(']') - if is_array: - s.expect(']') - return 'table_array' if is_array else 'table', keys, pos - - key = _p_key(s) - _p_ws(s) - s.expect('=') - _p_ws(s) - value = _p_value(s, object_pairs_hook=object_pairs_hook) - return 'kv', (key, value), pos - -_stmtsep_re = re.compile(r'(?:[ \t]*(?:#[^\n]*)?\n)+[ \t]*') -def _p_toml(s, object_pairs_hook): - stmts = [] - _p_ews(s) - with s: - stmts.append(_p_stmt(s, object_pairs_hook=object_pairs_hook)) - while True: - s.commit() - s.expect_re(_stmtsep_re) - stmts.append(_p_stmt(s, object_pairs_hook=object_pairs_hook)) - _p_ews(s) - s.expect_eof() - return stmts diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/test.py b/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/test.py deleted file mode 100644 index ec8abfc..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/test.py +++ /dev/null @@ -1,30 +0,0 @@ -import datetime -from .utils import format_rfc3339 - -try: - _string_types = (str, unicode) - _int_types = (int, long) -except NameError: - _string_types = str - _int_types = int - -def translate_to_test(v): - if isinstance(v, dict): - return { k: translate_to_test(v) for k, v in v.items() } - if isinstance(v, list): - a = [translate_to_test(x) for x in v] - if v and isinstance(v[0], dict): - return a - else: - return {'type': 'array', 'value': a} - if isinstance(v, datetime.datetime): - return {'type': 'datetime', 'value': format_rfc3339(v)} - if isinstance(v, bool): - return {'type': 'bool', 'value': 'true' if v else 'false'} - if isinstance(v, _int_types): - return {'type': 'integer', 'value': str(v)} - if isinstance(v, float): - return {'type': 'float', 'value': '{:.17}'.format(v)} - if isinstance(v, _string_types): - return {'type': 'string', 'value': v} - raise RuntimeError('unexpected value: {!r}'.format(v)) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/utils.py b/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/utils.py deleted file mode 100644 index 636a680..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/utils.py +++ /dev/null @@ -1,67 +0,0 @@ -import datetime -import re - -rfc3339_re = re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))') - -def parse_rfc3339(v): - m = rfc3339_re.match(v) - if not m or m.group(0) != v: - return None - return parse_rfc3339_re(m) - -def parse_rfc3339_re(m): - r = map(int, m.groups()[:6]) - if m.group(7): - micro = float(m.group(7)) - else: - micro = 0 - - if m.group(8): - g = int(m.group(8), 10) * 60 + int(m.group(9), 10) - tz = _TimeZone(datetime.timedelta(0, g * 60)) - else: - tz = _TimeZone(datetime.timedelta(0, 0)) - - y, m, d, H, M, S = r - return datetime.datetime(y, m, d, H, M, S, int(micro * 1000000), tz) - - -def format_rfc3339(v): - offs = v.utcoffset() - offs = int(offs.total_seconds()) // 60 if offs is not None else 0 - - if offs == 0: - suffix = 'Z' - else: - if offs > 0: - suffix = '+' - else: - suffix = '-' - offs = -offs - suffix = '{0}{1:02}:{2:02}'.format(suffix, offs // 60, offs % 60) - - if v.microsecond: - return v.strftime('%Y-%m-%dT%H:%M:%S.%f') + suffix - else: - return v.strftime('%Y-%m-%dT%H:%M:%S') + suffix - -class _TimeZone(datetime.tzinfo): - def __init__(self, offset): - self._offset = offset - - def utcoffset(self, dt): - return self._offset - - def dst(self, dt): - return None - - def tzname(self, dt): - m = self._offset.total_seconds() // 60 - if m < 0: - res = '-' - m = -m - else: - res = '+' - h = m // 60 - m = m - h * 60 - return '{}{:.02}{:.02}'.format(res, h, m) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/writer.py b/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/writer.py deleted file mode 100644 index 73b5089..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/pytoml/writer.py +++ /dev/null @@ -1,106 +0,0 @@ -from __future__ import unicode_literals -import io, datetime, math, string, sys - -from .utils import format_rfc3339 - -if sys.version_info[0] == 3: - long = int - unicode = str - - -def dumps(obj, sort_keys=False): - fout = io.StringIO() - dump(obj, fout, sort_keys=sort_keys) - return fout.getvalue() - - -_escapes = {'\n': 'n', '\r': 'r', '\\': '\\', '\t': 't', '\b': 'b', '\f': 'f', '"': '"'} - - -def _escape_string(s): - res = [] - start = 0 - - def flush(): - if start != i: - res.append(s[start:i]) - return i + 1 - - i = 0 - while i < len(s): - c = s[i] - if c in '"\\\n\r\t\b\f': - start = flush() - res.append('\\' + _escapes[c]) - elif ord(c) < 0x20: - start = flush() - res.append('\\u%04x' % ord(c)) - i += 1 - - flush() - return '"' + ''.join(res) + '"' - - -_key_chars = string.digits + string.ascii_letters + '-_' -def _escape_id(s): - if any(c not in _key_chars for c in s): - return _escape_string(s) - return s - - -def _format_value(v): - if isinstance(v, bool): - return 'true' if v else 'false' - if isinstance(v, int) or isinstance(v, long): - return unicode(v) - if isinstance(v, float): - if math.isnan(v) or math.isinf(v): - raise ValueError("{0} is not a valid TOML value".format(v)) - else: - return repr(v) - elif isinstance(v, unicode) or isinstance(v, bytes): - return _escape_string(v) - elif isinstance(v, datetime.datetime): - return format_rfc3339(v) - elif isinstance(v, list): - return '[{0}]'.format(', '.join(_format_value(obj) for obj in v)) - elif isinstance(v, dict): - return '{{{0}}}'.format(', '.join('{} = {}'.format(_escape_id(k), _format_value(obj)) for k, obj in v.items())) - else: - raise RuntimeError(v) - - -def dump(obj, fout, sort_keys=False): - tables = [((), obj, False)] - - while tables: - name, table, is_array = tables.pop() - if name: - section_name = '.'.join(_escape_id(c) for c in name) - if is_array: - fout.write('[[{0}]]\n'.format(section_name)) - else: - fout.write('[{0}]\n'.format(section_name)) - - table_keys = sorted(table.keys()) if sort_keys else table.keys() - new_tables = [] - has_kv = False - for k in table_keys: - v = table[k] - if isinstance(v, dict): - new_tables.append((name + (k,), v, False)) - elif isinstance(v, list) and v and all(isinstance(o, dict) for o in v): - new_tables.extend((name + (k,), d, True) for d in v) - elif v is None: - # based on mojombo's comment: https://github.com/toml-lang/toml/issues/146#issuecomment-25019344 - fout.write( - '#{} = null # To use: uncomment and replace null with value\n'.format(_escape_id(k))) - has_kv = True - else: - fout.write('{0} = {1}\n'.format(_escape_id(k), _format_value(v))) - has_kv = True - - tables.extend(reversed(new_tables)) - - if (name or has_kv) and tables: - fout.write('\n') diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__init__.py index 1d30e3e..517458b 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__init__.py @@ -9,14 +9,14 @@ Requests HTTP Library ~~~~~~~~~~~~~~~~~~~~~ -Requests is an HTTP library, written in Python, for human beings. Basic GET -usage: +Requests is an HTTP library, written in Python, for human beings. +Basic GET usage: >>> import requests >>> r = requests.get('https://www.python.org') >>> r.status_code 200 - >>> 'Python is a programming language' in r.content + >>> b'Python is a programming language' in r.content True ... or POST: @@ -27,14 +27,14 @@ usage: { ... "form": { - "key2": "value2", - "key1": "value1" + "key1": "value1", + "key2": "value2" }, ... } The other HTTP methods are supported - see `requests.api`. Full documentation -is at <http://python-requests.org>. +is at <https://requests.readthedocs.io>. :copyright: (c) 2017 by Kenneth Reitz. :license: Apache 2.0, see LICENSE for more details. @@ -90,18 +90,29 @@ except (AssertionError, ValueError): "version!".format(urllib3.__version__, chardet.__version__), RequestsDependencyWarning) -# Attempt to enable urllib3's SNI support, if possible -from pip._internal.utils.compat import WINDOWS -if not WINDOWS: +# Attempt to enable urllib3's fallback for SNI support +# if the standard library doesn't support SNI or the +# 'ssl' library isn't available. +try: + # Note: This logic prevents upgrading cryptography on Windows, if imported + # as part of pip. + from pip._internal.utils.compat import WINDOWS + if not WINDOWS: + raise ImportError("pip internals: don't import cryptography on Windows") try: + import ssl + except ImportError: + ssl = None + + if not getattr(ssl, "HAS_SNI", False): from pip._vendor.urllib3.contrib import pyopenssl pyopenssl.inject_into_urllib3() # Check cryptography version from cryptography import __version__ as cryptography_version _check_cryptography(cryptography_version) - except ImportError: - pass +except ImportError: + pass # urllib3's DependencyWarnings should be silenced. from pip._vendor.urllib3.exceptions import DependencyWarning diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-38.pyc index c075fce513cc0a356130232602cd3f63c6d8ba7a..67c88b86d3e4d14487fd16b951793f838c8bad9d 100644 GIT binary patch delta 974 zcmXAn&2Jk;7{+(j8~n9)?9_EW>?CWK#7UcYTf0e33M6)#qy?!x1XOs1h_>Fr*=A<f zommH*OAtB00VJw9gOY2nxgl}k)KmWeA5i}R?g%8r%w|@4=6!$j?6b3@`Jwc>oc%PD zNojH{|M%O$i~P%M8Ew71_5JC|v5Q=jWa&7JBMp!9UvbXOoT2Z~i78hMl85|L&7U$f zoI6UfKai##*MR)zny-JR;R&2~v+np=jQ=hDIdY8_pdgb9=hrWk6S;X(q)C{REP*G_ z5Yl8`@hb1<Q^aytkymljK0&7FG)zmoaX#Z-!_ybKj2UwaBuPt9qGc%4S(ufP$%tQ< zd=BR5Jj_!IELwp|#EX(wp-OMSji{d_@6rWWi0Ua>FTx_yzLde!q(+xui7vx3y$LrX z!wk7aS73#%!YZvpo!Vg2+i;uSfjhJT4cdfe<SUW8bPd+%I;=;1ncSl-Xhrob851K^ zen_`qi?*RHp*qkGbmTloI&>Sh<zIHrAK;w}biRwX&$J79JlJ?X<Idwv*K#XA#pGMY zzP4O-{t@dsOQ$*x_qx{J&L@_*)I;=4)MEdN`-VBSlCrKw^#~6e)eWn9?2rL&h+Tt~ z_=asW{9=H4$m<L{Zg_~@pv&uCaQVil>f2rWFre6G!@=OWXLHuIUB~w@=>{ysy#CGb z#6HIUu}!>Zc7GTi27a^Nvbh)H)xOg`a(b9wX5%@1^Q77L`j+R1nE4Lj8<rdRwb1ft zUnW^yHtdH%k2(Frp%wVnQ_pvUulXqcu)Tk<|M=0am`ggScKL1cM}+o7Cf!Cg@g&`v z9i<;d2|J7hY!u_1jN&~UI$_90CGj?05Wl1oV~g^FkHo8VP5hazOf0F+<nq%5f8`Om zBT+P$PFX{7jWy-O?yCA78n~Enwx-Csl6wlroW93es(nw%hLZbAib~#B@_~{MrHm3B zbM6H`XPb&`DQ0rH!2v($%6QJ&igz^eySb2KAF1^?33@%x@3D`?U*;bALab$~<+vU* Yk%1COM<&Xmly1s7A(@GCqL-=s4-?`6x&QzG delta 804 zcmXAn%Tg0T6hNnwiI8OS00Idlgb*O%m4uM+5Cs#IqHtxETIyX$MWziSeKWCVLV+6= zEOem@YJMR31FQH2t?~mb7x@88H*R$0#_q8fXKtUq_x7XaOX^)R{5TW}C}Mm+{rLQ6 z<SLvZ>ebTQ3!Ug13u6Q#M4=Ju+nZ%!LM)0yFeJ=ScetkzMYu2<K|jQV8>F#ILX;;; zE2b)R^d!K)5|KlcXG+WSROUw57{(zka@B4^kJ5P0BYODsA?C+%7{>{iz$7F^zYD*+ zFf0~Qkitor#5AOF3Z`5?B76oiI1SV8JjSv(12b+sD&kp~b>lHMhdIb$9`ZO3^RA1t z1zdzhT!JNBhGi^30gF(?5|nTSR<I0ZqAZG2CD<xfpn_GXx`pFx4cB4ajVG87H(&!d zVbckFQZ*rouCf}`#5c)mSckf}X05wR@AgRd9<5(0J@GhHeU;EtbX%X)(;vK|N`0s- zOf`Nx+{1&J-G*fxW%l<T1)N_V+tIy$oikNSEC(|GNA`rCm$O@$>}i8_XxX_``Pf#e z)IPV5%~pZa*BxrvR?+0m>!>g5N$-?wY?s<byI`~|yTMpt^|;zOtC$TbuR8-#kMqgj zAi3*Y;5{LG&ULU(a?YRNCIRO_oAk|z9|N2dEx*?f9$?$#_8#XZhqNd!9-h*cZt`M> zGiJP~6zSO!ZQF*~vUpz9^)<`DHlr^MW>d}=gmOM>^A~-EuZoygWX=sVb;>MWm1a$1 zU21QmZSV~_-ITZ~u_ZAkaZBR1#I`_x(4v;*Zo4Dh9qBZ2UAto)9*OoAuSs8**i{@B onhW*^nAvO^ttP+k^g{dOf%7AjjrugA5)aYHpjQ(NJNfYRKX}E?(f|Me diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-38.pyc index a1bd847fd6f8477c94c5128e595463847254a7f7..1432de07ce5919dcf6951034cb2c2b215240f2da 100644 GIT binary patch delta 146 zcmey*ypn}Cl$V!_0SGkz?TX(yk+)b|KBJ_hpx8=ZzbLh^G_|;-Sg$BGF{LCUH6=f} zST8fbip@yR$VAT|lR;(TG6yCjgNZLTIH&1n<maa97gd&)W@YLZ7bWYbB<5wN<|OAA xm82HyRa92#m!;;F>E~o7=@(R%WaQ@=>sja*XO^Vu79=KTC#I(sPu|Ap2>?{~GxY!f delta 104 zcmZ3<@}HSEl$V!_0SKO#ZHU`4k+)b)Dx;*Nz)D}gpt2+*KTo$PwXig`xTIJwzbL(m z%}CG4NY5aXL22S@2PQ+yiElT^IqH|>7U&mb7U*W?6_+ID<meh@n3Pr+=O=;$CqH2H F1ONdLBb@*M diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-38.pyc index 00d8e51e63275eb47fa7b6368cc268e4517fa36d..bcfa33a6fbea9e49344c91576cdb1809ccf58fd4 100644 GIT binary patch delta 94 zcmZqVTE@i_%FD~e00f%<cExYx>0@%v($C1xP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7cOgUOQ#0JYyBtN;K2 delta 57 zcmZ3+)yTyY%FD~e00hs=HpFe@>0^>})i22{&@ad=(9O&%E=kPE(KX62DXlQhPXq~W JzRTpv1OVY?5;y<= diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-38.pyc index 00342c88b4b110a6e04f27c7677984d644749c5d..c7c88259ec9b8226b5e19360db390a0620b27d87 100644 GIT binary patch delta 107 zcmdnc!g#fXktdXwmx}=iH2>|2-^eqW)j3%|BR@A)zo@dbG%HiTxF}gaB{45EH77a0 zs3f&mucER_zbrMcOg|?xNxz`7BqKl1SkFSgII|>Gw;(Y&J25@Ac=KM?NGqmW5|bSr KBo-SuFaZF>10{w4 delta 66 zcmccG!nmP@ktdXwmx}=io|kQi+sHGSRnAVoB)34nAhSR>Gq1QLF(*gYD8r<*!Z<$> SB)ItzYorxp)Mgt8NhSco1{Hz; diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/api.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/api.cpython-38.pyc index 3fb5b9855ad05ac3ccd28d794769fdd93cecd5cd..c1b34eda3ac2f7d2b095e6519e8be4b4ba50866f 100644 GIT binary patch delta 443 zcmX|7u}&L75cQrCV%>2V5g~9lWe~=f1PWv+R**S@6@-m2T@-fljdN?Cy~pm_U>Zvl zNOUBpNNLliLnoTlp+vO&1x<=nh`T`Yrg`(;%t-Toy}nwS*s*OhlVI-d=Pu2kPn;0) zC;CeCW(g>L=Qb!UB&1evRBM~t56!x}viiX4we81&`p!SH(x|Mbu8_&zs=MJfTuO`4 ztMSYD+StlIE0@b4aX-pi?aD{T7hQDZu-|WUN6Dt+u^z{uDWpbKJRBZ51MCf)fbTis zQ2U~{SX_1#*SHX}W`})36@9nnNg=+nOoP0QZ|pW9wWyMN|CDt|CKH|IK98W<GT{-F z1%Wu&mFRJaO|2+!1wEl5lw!a=^a{W=9Pl83Jp_dsv;exs0)-S_F!leC2t%RJOKt5V zc-Uh7KtrjE+Aq=M!9FTYlOz5Z8*m}#BA6UmACjcilQeHD{xMlKNGJY1^~SJ|Qr$@P jaXItlc_}`ez9r-|_GdN-`4(Nw9@{U?T-MI!%)fOHbkv7p delta 173 zcmX?Wa>R%)l$V!_0SKO#ZHTLv*vQw$$T)ZMRK}7?lDw1m^6cC!!yL#lxtcp!&QiZ5 zw?Mxjvp_d9uec;JCr8&P!=$vrI6o02I9ZWLn^AkSFAo<Jqy6RxzAQ#YzsZOBy_u?> zP8JrJIC%|k$mBXfE$(QbRmChI3pqD$7W8Cd%-H-_*p`X0e6zKfDHCJc=0XV{M#ia= T_enPK>T~gP@N)2S@q-`$AssOE diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-38.pyc index 316134205681a738b1244d3fa4b725aaad75644e..70e9b5611f6feb7c573649741eec7c9bdf47ac02 100644 GIT binary patch delta 1809 zcmah}&2Jk;6!)xm*Bd()Byp3nn-4c_(r)U;*d@l4(#B~D5k+kgDFPZ~Hr|Qt#Ieon zIE^cp0zCi%4())15J(9~NI^mfS%At3E^tKR0$K?W9QY$Z1?G({+o@_;X?}Y1zW2?0 z@Auj3so;fR(C^`&`S(}pUq1`(mC(CvQi`X~Q)$&}d$(ljtD$RX8&SoU-jtAss&K!8 zsHev1YZ9?*o-NImx6u_3=OMw{tf3|k*$VBUep}rN)VOp-+UC|<z4f~E4MIUykxwZy zt(GzSQcf-0!xQ;49nF>2ag<ammDPOIA(^Oc74x`|DG`dD>CNip=msusL<{-lXt_#r zrQ*@)WYo!1e57n;)~qacn4z50)mxG*{iXUeuOIm(I5G<Tqsqi!=l#do*UBdWh(`qI zY*Sr|>}%aSB)}Wyu)vQabI_11k>MM@A14PvHpF4aOU8h1F&bW*u5bBj549vavg@@9 z1)=KtvY1+wl7<sWIB}H{&0(_3!x!2`{SX8Y9-}R)8Q^fwr6b0!_^vO9EgKVujNYaU z*M02!p2&s$Kpp^?0GI@r0*C>`0lF6CAeWxw$ARX7f@rd)YF=`X*Y+p<KCr!W;JLt5 zWE{lp3O9ZNcnJ<RKkYInZumyn=YijX@b{+DEHL}9cVdqT7Huy&T&LL2y&tK^fP9d> z7JT4t@hTlk^&f&ay=Z{F(Ko*9^>6mQlXw(Ds3Zv13cvusV;o%B$yqUS7VhxZonhH4 z{qH6J!&K#_@tH&y<BJ0y{GahmEZ)U<CUiXv|7J=qa$IEZAh#!HIk|L&t|S{d>g<ou zvwcrP&R!0e<%xTfo8$~z-1BXtOtUOJIIg$4lbit6lK_npu%*G#t55^-1OSx4Rh)7m zPferIuIf7GLuk9+3Mr6zP&y6pFu)@KFgUJ1Z56U5lBc<K@;Go80iFbS3gpt6c~`|n zYUi`AR!)~K;$WNPgvdz6TqzZIy$hV+5O;mW%!XB{VDbzL4NWv&atVCt_4%PWWQq=$ z;|#Mom|<|Fu3fT7*6Dn``low`By^m8r$<g41^rPs;P8>GIO$A@&riz{Nr49+!OvH) zLtS~fWLJ4xV7x|VxP+{*m@$oJ*>lFpzze`A0hHOth8Yk|7>4_c>=(o6Y`nTWtf12n z+0_Vk%B7-%#Y>rYkyBtH5)hBl;S~fT>Z@QVQ_S~Cik%(Vf8c!(y#xS%-(?2h9(j4} zFo+`nw{H{R#aLo=aSUdzQLH=Z#M#cMd9~{j5!s8JMLHreu}<3Cr9GE|(jnaa918q6 z{T#$%Q8mA|qA6NL3u&s5^Uf2?itF`z$m?LX3Lx4v$ueVa#b6t{YH4{DXQ<fT1U8mf QFv3Mg4>V%4L*Zlp0-_gg5dZ)H delta 1746 zcmai!&2Jk;6u>?E<&B-CB*aN<H?~Qdzy_y@ohGD#lDKJUX$wI>R3JdQWH+{3$2PO$ zwjf8T$e~gZs@ka#haM6Rpd2buS>p2qLi_=o${Z?zKyc&60mR3=S<7*%1T4)@Z{M5u z-uTU%cP;bdv@vHG0U!VUa{lAj?%p=KCG;L0kka#~h;&xA<#nZsHV{#5>0Jr=h*m{w zXax~pmCI`qK2!Cr`)y?dt@yYO2_31Tx(?YY(MgM~tp}>yx+HCI@AY8qQ|T*&TIrk0 z4E<V}?(631|Ck&m%jMy6zC4sKy2L6JhSIqMm5ZY#3zYPPIvbJxk`(Dr&9BP=6p&yk zsN)|^!4bL|c%1&G-U>n}ED)w2X|D_>8sAM8&_y|p^W`cWI#MKhTaD9G{x1eXVD9AD zlyMB?hQbS6kDk=4hZ>emg~|NLVk`4!9byrJy&#eZ!qgJUIe1%ypY{33Ly$m3+~1Ju z30`iwFcjIApZRl+Wjol#J@;&e&jkIuB{|m%Vjo~1pdVlYMgS>50<cvMFCFLxIA-~B zp&_6qx}s~kj0bpm??gsn%g%}42o5G61oKW&$GE}ft5In@Mu+`9^rzqt2K;?ftyh?S z*V-R?czc*Ie44b?_)t3t;w1gdIC#IfmaSaj8oKXu8MV_d+j_Tkz^`rZk3R(|G;Dyk z3TOwM<Y0=Mvr_nJ_<jb^6p?<?eskhKTs7{R9vk1q`N{(y{Gan!D!q%d-El1eCov_4 zT!!pT#9DHen_H-mr3vqhVHyg(+V&!xS>||4=^vT6h)>Y9(6?Thrs!;EZ=}(l_z-M; z0^pT^zS9|7g&N@J08j#^y5&Nim{G4^wPlCoN;Z=#xPWJ1(-FW?z>|Pu94xS46|yCq zC%I+(ENGtx%mGe=T{?M$X-<*Y`7G1R3uOztj*YXz6wRcVlu0xBI2Sn5%wJqQZxt#I zeu>U>^?Nrt53#~Ex9c!6MF(WK!mPi{I0VwpU9fQ0ZN9zQ-R>?4Jw|_zB;#q=A7ep2 zQ%J>KSS;}e)Ch#9X(k%h4nPuzo{8>9Q}k+dD!2lQBA`USkD5WzaF7kJQe$tlxyfpy zdsTE4vM?PxZn;!+9dRq>9()))L^5#!O;N!hvR(#9g*be8Ow*N~zI`{rbO`|ebe9MB zP0!o$K`=i8xOa4bZiG6q7vk`~yu$3XCq?hX%+*~dhB&=A^Cbu)4we9EYm{ug7$Jqh zI?hqx%Y}y~rii8o^d()@lX{1)2|MpHF`3T!eC<Ab1>Eug(UOnS>+u^Y7=27Dy?)kN XBw|{N@q}TTh!9Qp?d7JY6O;b}zfD%6 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-38.pyc index 0261dadfeae99dc8f8610ac7d4d7d83e3f225bec..7f645a6e665b65e78acb473fb029c487996eae68 100644 GIT binary patch delta 93 zcmcb_@|}ezl$V!_0SGkz?TX*X^O4axK|douH&wr=va~cSQ@^+<SwAH)FEceKIlrhR vwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*kUG?O_1;!PmQ delta 56 zcmey)a*2f}l$V!_0SKO#ZHU{*^N~@`TE8T>K))cfKsPh5xFj(rN7pFBq_n~~KM^E2 I*@4L%0Quq)RR910 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-38.pyc index 7e373f643ce8e04d144c3d4548ceb7c0f1671528..11a3e048aafc61ac4aafcf419e164deaf5d676d0 100644 GIT binary patch delta 116 zcmZ3=bBc#Il$V!_0SGkz?TY`qk++4_IZ;0&KQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+H_-@_JTZMyAPsSta?I Oco;>PSQtT&0|)^JXCuh~ delta 99 zcmX@bvy_K7l$V!_0SKO#ZHSw?k++3a&PKl^w?Mxjvp_d9uec;JCr8&P!=$vrI6o02 lIQa^zuO_1eGYcaGaxro-u`wDj$}sXkp$HR1hJ%rV5dbhj6c+#h diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-38.pyc index 76a4d43bb46d152d4adb9fc90cfde24c67501941..5324822ab4ed69efc060858f31c71e8cc4228cc6 100644 GIT binary patch delta 96 zcmaDoiE+YYMxIb!UM>b8(EPV6ej`sjt8<cmMt*Lpeo<v<X;!9waZ$2<N@8ASYEE)~ yQAujCUPWb<epzZ>nSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B&J@#ap}N6r8(ej<$k delta 59 zcmbO*nep``MxIb!UM>b8cwV+4ZX-`TtDLQVNp69DL1uw&W?pegVor{(QHDurg>il& LNO1Ey)<@0&D^3&{ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-38.pyc index a3474e1fa64ac6454485ba706b7d9bf1f1cf0b2b..25d0a10cabbf221b4348db82652a48d93e83a54b 100644 GIT binary patch delta 196 zcmcbr@m+&Al$V!_0SGkz?TSy`$or4kIaNO+KQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+H_-vnI<%E=HxvxA_z& z8*#}@7Uz#*G@e|<Z!|fXO=j|b{wIvqla~lsO}@`6Gx?{$R1PMf12`CqG$#wPn@m0< fSj}4o6exy@YJo+&gsQo!;G&xag&i50S%g>sQ3X0K delta 164 zcmeyaaaDsil$V!_0SKO#ZHTMg$or33&OyH<w?Mxjvp_d9uec;JCr8&P!=$vrI6o02 zxY>_oBNwCMB!0!o3wfj`+ww;-8cm+TZ!|erKzi~s{wIu9lTQm+f#nnhr*g3Xjpkrv qVJy;|Y{+IZ`IBHZe>qU77%r{_7GEb+%~OLUzS&sVk&&5Ih!p@l&nvP3 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/help.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/help.cpython-38.pyc index 800fd7295fbf12d1966043a824be9c3abb88afb1..75e2b3d4cbe885a4caf1e40bb01ec6ee03944260 100644 GIT binary patch delta 100 zcmZn`T_MU7%FD~e00f%<cExYx`M}~Fub+{ho2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu zTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5(FiuDK!<E_c}IhOzc Dr}88F delta 63 zcmZ1>+APWw%FD~e00hs=HpFe@`M@G)rC*X;pkI(#pqrUjT#}fRqid95Qd(i0p9m7% PY|naxg)wR}3)d0=XA=}H diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-38.pyc index ec2c8dfae88a63f32bef87c526055908ac9e219c..c734232f7cf0e92377b97b99f88c927d6af69768 100644 GIT binary patch delta 94 zcmdnVevh3el$V!_0SGkz?TX*XQ_JX_pr4VSo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5(lIinC00Mnfyu>b%7 delta 57 zcmcb|zLT9Nl$V!_0SKO#ZHU{*Q_Co4tzVK`pkI(#pqrUjT#}fRqid95Qd(i0p9m7% Je1=ho2>|on5<LI_ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/models.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/models.cpython-38.pyc index 4eb009ed5c90678d227dffc5106e095efc4280de..09f562e5e40bd3d89f334bdaa1576e125990a346 100644 GIT binary patch delta 467 zcmWlRQAiU39Eb0Bo3pN6V8m8|)0!{S+!<-4&4p=F6AG5goDXqrS36xdy}ONO7J*je zLr8xb6%2Yw9|}VL^w1s*%7_TU5g|kb?JXjF=s`iK*7rSr@Rdv0EJ2RRvLsXq{3)GZ zTa?Mwt179?Wlb^j+3cvUSY|>=s)nwm6B*Oitl*XWq>|H&oRZcrDC2oMl`#$m4=a{# zYpvsIVobfHS-j+W<-sSuUaz7i91b^{G_tFK)_v>n^IF4wpq*~+okKr)_Wi<1a{Aw6 zkU#qO0CE1&6m=rWp}+`Gq6f`S+ooLR#-!WcHic<is~r*ypHr~iwrp>|=opjCTM+)6 zthQmn5YGv0wQPuZOX*;v<b((}c0v-l5R3p4e^*j~mm>$ZIM7OG+TWmuydBHf!CyP} zI}oF-oi{K;vz=FQn~EVX)ps%GsN9vqES)&Af_t<(G>u1G46Oo1%7)Weph|cii+ty( zN5l($+;a$6=G9{^-~)Z@eTNmA?|Y5UtRL^L!B1X@)B#`k<v>zI9s5pYfHuB+x+0>F yC!&9WQJxrV0%o`n18Q5Ms%~i(JvsXu1%5d640ulc!xaorAYQJHHsdi7-Twf(U7&LS delta 431 zcmWlOZz$t&9LIm}?{>rN=WyCdVK{aE&i}&ijtkKgHHJ}F%UqV(*7iHy;p#HE?$O=# z$pdmv(4LU!BV`^aQ;P@OO5rIFl=8>}$^*yi_3ZU}2qPATY?EcZ^u*QJ`p3%+nRHo- zSsnG6eJ)>#%M(x?Zg)w=aMkB8m0rhl<V)SI5m8>sbbx-Or_<Z)JLIy-Gz(PHR?cs< zP;2fD+Ne730A2i;mjT#0Bj2jUAdeOd0NZp>xKcK5P!lH+#J9L!$&;m(RD&w3NuM+$ zdjAxpXPr;aE_p<sG^z97^K#L>z&`ygHR%NmNP}Kz!O>C+kie;B!+?<|%HuUCrs=8( z8mX;%A1N%?6l>5;b+z9Sq@CIc%+QhYnmXzjzev=N;U|5q|A#+hQG%G`BjprWpwN3a zLiDO3gmn%#7zH*t_MrxdaD0;vIHZ@&Q5@50^BzukzUAEuT=SVF1vuyHcBeoxcXoII zGw*g@2sH7c^$~FKV)q*$$Wa@RRAF_v0z&~)K=t~EoOIlCi&>8Jt^#Z1vtPhMUHvii KbN+x$K=}_1IFWY% diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-38.pyc index 45fbe514d437e253a3fa6ff55da298b356fde4d3..65a6fbe84d899ad2f628caffc2e64ab0ff95d23c 100644 GIT binary patch delta 93 zcmX@l{Dqk(l$V!_0SGkz?TX*Xlg#Lxte=seo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu vTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?1M)m(d9TxR)TZ delta 56 zcmeyue4d#nl$V!_0SKO#ZHU{*lgub*r(cp=pkI(#pqrUjT#}fRqid95Qd(i0p9m71 Iyou2X0Oe~EJ^%m! diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-38.pyc index 17c22e499115e6c41b767a86a53a84523ecc5647..83fe2f8cb6ec19ad65165a5c44b206671db1e98f 100644 GIT binary patch delta 3765 zcmZuzdu&_P8TYxiuN}W*=bbolnly>?a^H_EO<$qu5<$x-uPeZDeQr`euI-+C(=@@J z$I?k?s8!0@q%!T12v%sv7~p9FwgK80V_P?1Lz{HRB$%`TQbGM^(q2OQzGFyP)I|QB z?{Uueedjyh`Of{p1@fm0#CyBf>$1RK^y3%eXU==WWaa$8V3|-`R@NMfgIK7Y%2}sY zqtpo6k#%Wq#jSZ1kLFdpnosd*e#I|z&TK%dRcf`M64XLUNUKxoguEtOuQezQTBFja zH7QL(=E^o}ElP{ls<aB;oo&;?N?6dIa<*OTP&%}T645%9P9gMWH)vf-m)5OxYa5k~ zT948r<i2dL)~ECd+MkVT{Yt-}17Kr78PEomL2XDG(uS2`EvCe@P0A*rugz}OwkTT! z9fSb4DqD#~mD1a2C{vb}3A<y_rCQV5l^u6la&0z?x-;Vf=@*Cv|3R}$*>SfeC*5Vq z$-r5a9jar7&^lUwhA6uQ-9Q_G9+|MvCfa<)LYvjkEm@UO;9F=b@U7}7@Ox+*4WF?n zV^q4$5^Z1PF2=8r$NW)Zx{olbGL?>}k_InG&2@IOCYjG?QffAJ+>}##ys)sfa#{Mb z^<Xk~BCn}2wlFuBPQ`SVjL}36<|XsYQ1#){3yZN+YVK4F7RCw-#)*7x>+r6ao-)*- zLL!+-%&IznR30Le{7v~)vZZptagLB%E4?)b2yyVVYl0lFJnM2wWS;-nbCMk9L*5N! zoFDZj%NGnkwXXz<mb7n`6bY5jN?(R?rFIn(RdlZesbiI}*9?%Qr6p4GQRhm?s4M!? z^-HAao|RTf$qiaJ==?>0+DdCO61!UTz|Ws<D0-;tENF5b)UkgemVjPqT(y+kMSnTn zv`q9CqZ!Q`Eof#*D!FscDh;OVP*(KDrJ`k}wdgI9RS5zk={6&rZiipTjFfS}*%qj~ z6etG9E%(-yYKz`<WTmrMOC_AWOimu764=;)@=~xET<N49p(|UAE)aGXB{1n;vJ#82 zQSg>@&k{QFuJj_mN`SVk^g#fQRjK3vI=U8&H{DOAOwBUMzeBynU`Adhg?FeAsZyvI zg5a(h14Zu=+VGa7qH|edQc=1CGAy5Lfz%K3!~U?n3#cBR_RkU<|Gj@h>;0t&luwGO zNkbow61EF&`l1wz{hN&NP+(HN8+fMhWMFS_h#f+v2Eeq=u`Iib|1dBek!SKuOBkj- zna%5}>C%k^GxYhCal*8v^Qj!~seO<?SG!n$53ar!;XZ^o!Ze=<_LJkB1s{}`L7;!} z;ZV4y&g!(fh>O(mo=_L@RE~z;A~0!V{m#Hwa1{p04j>%o+4^v63CNG(r~3dbcA3ah zlU23`iIY?=*1s*0^L(i(+Ho9|B78Q5R1#q~LMOsG{+p)eG1EDvF5JXeo-sQ}qh2<S zO5t`Isj6F~(1_{Isq^sy%b!lEIy=w9%{SYNAg`_Dn@<vA@ON9HUDsp&4zBB4gF&Qp zfDt~_dMfY`vbYz9CYa7^CmUt92k2@3Mr*S*=M3?yt)1iw_qFwwXFZCI`lufogPjIw zEsQb^(h!Ue(PS)&lkO0Wg(x-EhN8GWX(evjPCH<xhwh{i+6hg_OLx%?v<oO7-A%jc zMxgw(hxWp(0PUku7;9-i9e^=N2kF2N5Ft8DV=&gyO>{Gi^>ho}3S$G^Mz_P*NE@JI zja1%kn<UoZ;bA`9KH*t}4VkvYoN)q<|AF>U$67g<&IC;q43+6j6w5hGLx%sf{ke(9 zk(@>dB0Pa`2|-L;v%qRmmO&7U-AJKBW<|Knf6@^nX@0dMNuK0KBVn@2bCDxN<1a>{ z<gv>8kq4!+I3%nU(>{~Rs=8^T2_pf;tmkvp;}?!aM8Y%%6K$%x8AdlUF0MH!`tW3e zF%bpUCi5bQl_I<dvZ5>lK$(sLQw#9~QyIo!+UE)dm9b}V(z6H^gq;YY3fqtpv5X=m z!jP-=dKLvD(LPOOvnq{OUj>~#&Tr}NA&*z)y01B>*0x$TxX#m!wkcI_a02W{9n6nz zeuVHme|jiV7F&rSU&aXy)nKlB5f;T(#0Et6gj10c(Hqb*n??|4yzY2K2EGJZ(}uY+ zow{lmsobn?x^*?jj|_+Hxb@d7Cx>;i7i}G5-vYcOv9H0vP<hE(4GV)c<;;A7&Fbqf zCANizO4p|Sq+S>?9Y>BH`}~nxZeuT^nV0y&=2p^K`TFJqq#q|7V&6o0Rf$yJ8sH^2 zZ70+O9juV88>GYE20>K1exjF%2rFv89@cdwdwI=}Fj=)$$m_<=N@n{TWShw5D=_Jj zZT<QiEwvWrjPXi-=O2iBZ6*69zj=2vIa-<BJxV&!7JKOiUS+CgRYSdpzcR9o6#2hK z{vNZ!v*UyprLpKNk{Nhz&cQ=X-PCgip7n7HJlCF_ZPo&hu?J=ja?fZ7$@0O`p-{T| zl~nycD%#+EKFzbEcLmm+_cVWNG+HB$03N5~T;7u*k8rkUTj~LbFdD9&>iR_(yts&1 zpQh`MM0QTC_VjsFiJp(uWx8ioBmPOx5%<vaLs`whrNbMO%_lRg%>84HEh?__Ac&e3 z*Xsnb5Al6ted-L5pFR~r_cH1*>}r1!&K#dOGVS7tGznvG;*6UBOzW(gW5SC#W&z@P zz>72^!P|C-|8{J^Axi-gkZhIzjNL}$^SJzBer(@BS#-c@<V7;#Kt(;(9w@fkfvQai zcn?e|ubU3|+DkF$X`-V{qwfC`8FhW8qHdsP=-+gMnK=J=U#I;AV4vaL`)9~L{?PvI z@`@ckqzHdy|FgH>-^oh1L}hjvy<ixoJ)570Jm*l*jF1J0ex`;^8IK}$n*9;A>$37X z$bQFPJ@Bv(Et>KvJYt<`eCA+>T?5hEm9HM$MS9af!d;8P!1@8;uDyfw_52P2`yT&b zeER_r8y3i?H&M()@1`fCF6eP1AJ_7yRJH>|RSSPbN*vSofO?lt-}Dr`EB-^x<U<}k zba&H}pXyCdJPx%62XCnH_*MRmLuL7WRQ`>3O!Sg#d}3m6`B4-+hVWeg(-Du;d@>$q z@1f}X2u~qAjqp5zC^d1sKSTEC2){sh4dK@aR}ip<7@iKpyfMrV!+_Zb2v-pxA^gfz zz|AfKcPoK<yN^c>xAC#VBi<=z*y(fHoo=U%UF6qV>ne{No+soYe4j*`|ADm$Ka0h~ zJ_3yHWgo)8-sY2&;cnBN%xAOkahb~J^y(WdTD={nm~t|&6%q#j;$#b1<d00o$P@fm zlNoZEZ=br8yur^-ZILk?_7Qk$;(wX)g$@8~b2#C{&PhDPBY8+0|L;_P4GWYl_}}|K Da&W4T delta 3768 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 E2X-u)y8r+H diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-38.pyc index 2d26448302055077f5477a221cfd87c757a36197..b7a517707c3a51d2cebf6518f8af4365d614a85a 100644 GIT binary patch delta 248 zcmdn0FjbK^l$V!_0SGkz?TU|?$a{~8k7?rDh3c*qiMa(isa958Tna#7XJ@C7nOl%w zRH9InT3DJ|Tv7}cpWMf&$pcbgY+w!%*v%-V1rjhZw1De`Y0*p0Pf0C~R*%WoSC0kD zZvM=e!0nu_pOK%Ns$W!DTAG!qUtE-|pOToDnVORfv@f+-ucER_zbrMcOg|?xNxz`7 zBqKl1SkFSgII|>Gw;(Y&J25@Acyb}H0b}vxMZ5)!MU#d38W}4lPvx7*m_1pazm!>o ThjsEpe%Z+q0z#9o@y7!Iie^k~ delta 133 zcmbQLxK)8Sl$V!_0SKO#ZHQBx$a|0JGULRz3nvROiA+ApD9U1NV9qu96{8f3iJ=7- zP*iHO9#aChoRfY@Zh?M5W`S;IUU5lcPL8fohDm9Kaeg95aPmc71IB{MOne25`IC$J i8W~F`f90FWm@&DZzm!>!hjp@}fb8T70inre0`UNV9VmJL diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-38.pyc index a5b04a29895f50298b91fc44bc22224f503ff29d..ec498a0d6d5600e9d9acc0997f93e46a320b2797 100644 GIT binary patch delta 1374 zcmZ`&%Wf1$6z%u)c-*!@#sm`xn4oA(>^5M~2rLVX4aAACWW>UgD3wlEVGs0UQq^NT zAYcJMV3qO*JTl6P4U0&TvS34Y*_ITEEo`zx$^vq4jgcc~GSZx`Qr~;-Ij5_hj=dQR zt_4A#0l(_IU&ybU!GXnj*ifTxP?K7TnOb$rG^kCT#7>>Mle%@+G%gv`rQSn>ddz)b z*FD&ms1JLem0<7F@>QeSx0x)DYHCwemN;dc(fLMPyf$&1_3RJZy&S;uZx*iQDGPbK z)w<CL1&>1-Wet|ZIWL%)+-Tnp*IBk6CXMgIX1iF+vy+pxP&5iQ(Tw7o(JB-2tvg|k z%cEXAR|3k8#eH}vH_2}?UbQ(|RQ65QR_=O~v>3<1T^PVu6+#3nfH5UxO8)MV6E+qM z0RR_v^W6ylZCm}&c1pe~jmf*E+A&n1Tlt>eJ(MNgQ8noK(bM&TyyG7p-N9d;S!Eg9 zX!6+^`P@G@p-p+(f#{fBT{~KQLV%kSa#p_YACn8^@C@=-EoCPx)3NXaJ!F*#f%k;W z!aHFB80PK$((E6RFUmjFFpVqPJ%srYY?QB~#Y8;-khCKkz8|VC$VYt_x~g4tEP9Tv zXeyMQit}=~a&Mnj?5VznXk?;@vY2rP=(s0;u8fX<3d?Hut0*@w))?P0TX}@A9|-wE z{#99-(quOGkN^YZA0zb2z=`u_ds%MuU!CqYDO(hre}?r({;vrF=d1~VUxUEE{&EoO zh7m>(_97faID~-Gc@<$C;d6xT52#mo9<|s(`8fE*McMJ@u3`CS@Z_Ra<tQhMQl?zd zYJ&CSSdUY;BH<@s-7!^}kT{8i0D0TISoe*5Iq>a4tm+kl*7TiR82l>4X&p;}K?>KF z5M{$*?{%iN)mZ*ExO5VG_-TNxOQ)}mDp7VlY9+<LylR^@C|r|sLr3mUVBaJ{h%kkq zqtp@UD6v=tTdrc3Bp;k<d(+sVNimQW_zS$YzUf#4j&J*}4(dv^thrSs&Xa`2MI+Ay yw~S?=_ToHkMn(6exk#svjQ;vMWIbmaaG3IE(ww#uHj6hz;PG-w{nn5@wD=DV86&>{ delta 1274 zcmZ`(-A)rh7~S33-EM!jK&Ti|B({m6VkuI@U>Za)V$^_22%#5DHoF5f?zZdf7U4!O z^xlwp1~pBLKd<2f7@ZrvGx6Fh6OHptAt=@+J)PP8zBA{Xnd!Iu%e=i}+bKnSzHYx= zf4*lA%~i$3Q)-H*dYZ2WT1^X34F!5lSCs|DL!SOr@pPg;K{Z3n4bK#FlbB+j@Dj^P z(b|je^{axVh<JL5dV~`1THTG`eL+ScBcA`5EyqDv4(nm5-iTty_e&F7ldYXf(}9O< z)GVnZY|V7%Oi|s|XhQsO!*4z$w1{XDX6QcI<;J$-w+IE!4%qN2jd4WcdQ1Y0$Jj3u zPk<QOBS3ILH|+!Xw{7#Ft-_uqYNN2aY@@mE^&as%%S?&-Je#s2Q}$%o8|%#A5&mR# zlQhUqNM|myZ`N!{nlhz>sI7K%9ci&J7W@?BX||fYI|kfEjU%5lWF+)d7g-66#e0ma z>_hT>7Mw3iry{uH>~(4&_xBofP*hxHA5-%kK?WF#x-zHb27sa<y25UxADxhbOrEMo zavvKmp$H@y>~nhXTtN(roxr)#jJF6q8o7xvd4TZ(D`eKjB^jay5I{EcBtSQdy4wtQ z@32>y<;hMHM^Q}aS*XwduSsM{Nhq>h7Fp)miamWR3$^_K#{dQZh5&{EKt3G-C<2TE z9A+m+aNML|n|-o}4Uq2c_2pP!_QiFnOy_#T2?#f$Rw(R`Lp`jz9}B%8#%+}+F?M|? ziiE^NUZ|_FpV{@(P}MC6scD_<_S`PRYHf`Rlb*O~7;_}fa<^kEtvc*`&r$_?=tTkh zcS_z0p76+q)AHj#yh@vwMBxV8?kzk%4}B$oF@Q3Fj8aA<ql98^@4Iq|?;kjm_A1aJ zNg<F`@r~dw$WnDJt6Ru2WKfGmOLBA5Z3dweQw`dXGA~evp*$&a(`Bxb`VfGhTh*ZH SwR|!I$1(!LdLoB<Z~g}JEdlKS diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-38.pyc index 4dfb1c94fd06511a9f3fd6db9d8814325947ea10..643819c2280e345839be27f1cec3deb950fa60bd 100644 GIT binary patch delta 1491 zcmb7@{cjXS7{~9~z4o^E+Fq|fg_fhGwAYur(xbFJC~fH*l$N$!TVSEI*L~J@+uggm zyG3e<7`z07F+eA3H2l!|5|KoL84VFkP)QWjm?*{{PNV(77-LA37!rRl>g*|hfRpTe zzR!1_nP+CQbN(&3aRof19*@(;TIjFq6RQ_IC2;vd&1454uevpl=m8trF-P@kUeTM? zxvEdg7xS~)p%!R<(Vx|VTBrrYqO8tS3oqQ>c1kN3%d@dl-K<rJ6<O_4w`i4OWmdb@ zDlH_2v}&<hs}XCoTCtY-9<ff&Uk<O>#0YxPhxr#dv0fHtw_?E@cOLW@`mr!=6B{sq zMT{G84X$O3;yNs5+=dFS#|`OIAU0wNmNIKQZp0vC6K=vX#%3(X&5SKrfm;}3Scz4P zJ8%|5Se*uOC)Qvsb6T+u!;HHyg7u7TxD^{1+cApU7(1{Lw=?d>CTwQx#1@P(cFEnR zaL3ai_TWxzWkxUV!ZyY|*p3~HdvP~*GWKB?b~En79_(f8m$}&i+=F}5Ha2@d_TfI} z4&og4;{e;(5bno8<_x2X!+3x>2QZE!%!%VDjxmnl!R1jrv@#Cjm^_Au12*v>qsVv& zkKj?3au~<)7^8?2ILUZK&RIT+i4_pXvucW|V<;iAu?dv%QN~G}#u>&0a&cQoBVTbB zeIdxW26dEm8M_q8BuT!z)SJn9Y$0XJ8DT+J=M%aiXL6<%P1(rshN;u<`Dggf$;eDf zlOy`#!osW)F?1<{iKHT{Qc7ou;S-BbM2^eJ;}KPvip(#XGpS@W+#E3!Q?8p&NOOs4 z*&u00Bh=IDjxm6Pq#*AaNc2wLNgh<%<8g4nll{K9-}<#PPQ_4?hM7o8vhF6-_b$9i zmHaM%@933+GzUMDXy7F0;ON_d5QIncgd|U~D#0o(Wtc%-mgJ-vloF~MR1=07iaCS- zwQx90zAXAV*UhTvE^>3tdf>>nYr;i#u-T04v+@gI=lmdW`Wdn*FF+dB4#7v{YG8=m zUHjYruhl{RT(|jQy)DJPu8meDul0Zn=!xPbo}JrOavWOe>5^hAxELIRar%4k1z^G1 zvQBu4eo<Bi@DjaW9s{^UYb)O1fYPrkm#mEG(1-8|4OO27Sf%gOC;$&gY25>G&_H;a z12;KYuR#I*r5>yszSnRAV)Rl}1;`^sjfdd?O*O_im?4*&?y>O~oBMo^b8LflYlDse z=s#pH!QS#boTe|gY_dweADe^cXw{C}0I$>gJ8L<(MM~S2;V!w^)(=kNZodmR=xVzc z;1Bw12dm{IM>}UZJ5O$Rejr#&hd`etD{Y13)viJ)rPo*wmGrajZ>;rS=_L@Q+xMKa zf{*v!f@Ab--!5yFJNp!Pl1BS^D`*-J;T&BWDB-|Gt`44o*GTiwPkx>)ud7z~xmAeQ zouqy^4)4+Q@G8KkM2^?O6j_S*_GDaAN>ydaR8mPpXQ#I5IS=RQxlCnz6H3yQ^<+Yw zSTGgU&>fbWE2XsggsBTw^0U-Gau47<`Fr${I&gFDe?MrqGX?8-J11~X-pvb@f?LQF STAfir5Q4&bp_Fuu_5TCp;j|(E delta 1292 zcmZvaTTB#J7{~XULD*$?S%g(Uh00Z~i(KU*2(ny+<qj*17hL#Hbzug`0HznM57O3X zy`HA&gGsS{(3cvT)7C_irnNOODX~p$`asjvv`H_CNllt2zO~<M)3?saoZtWZpYQwT z%*k21O;_G0@2J<C=-}tqldDG~SG}3^?$wfGO)BCHkLl4o<baAzhSyBel43gE@R`Y4 za!e-}o6Qt0HKv`c{hHt0qHVdlUVSF!xr|&hPs@wxL?hoU&<bMOZR|1&wL-H<D>93< zVzWdmVc(;b>PahQHym03UL?VHUD3*Q=k#tQ&nQ>Os>EibEIYIcq{7eKjxE^AtV9~p znN>J}ZP>m{S~bq>Kqgx?$ij2XTI@tNa}RQm%dA5l@|pE0z%FJ3q9{ZWmo}mpCG6}) zDax2l2%wzVjNPbU?n5Q2m@TMA4YL)s*u&h9I@B}U^dK6}(iyECjo8aZ2b$2#?8H8_ zFuTx-{mcVsLy*~xc62a%bY(h(PIN6h&XU%P1L$VA57X#Dh&R@cUi7gufEf&6kexvc zVVIpEj9`>GjPS|`4&ESbR39J3nBSp=^-+v74?@EsP8q{t9AS>*C?=SizG>wUj&aH1 zn2NAEf=NvA+ED;Ha{|xfIP(~kVMmc6Hk9k)RkfXb;!8El<L<YhTRMW#sYUsldQQ!1 zEMGL|%jcu>WzpG%#fV{)Ri3C`dZB7AVw*xH)KIznJt0gK7A>wjG%26CPN_5_m%IrI zDdMzmIK{;maw9Ri5bH2IrCV<ClkX$CCErdC5`8a!*u1RJ&tlSlO8J`PV}B8emaRYL zxVg--Z}Udn<lLNLmB!kHBgT^6Zdr4d<q@rE0k=vH$3pDVCySTTW|cQcJofjC`t+yV zWsed_6qhp7#cGBp{@;e;UPh;Thh3D!4IMt|-*!#qo!-nmNp&(SE5i=zvcohcFK53+ z92DfX(aUl=H;3p=c`>hn=so!$|E5B><$U2aJ3}r0jPA+%#pmtc87PesJr#G${vt)L z297J_7U>lxdE{#qWS_~osx_*S!D@rZDL$wfr(Wr<ZBS@RbksfJ^{V=AvcxO(cj&aN zZOFDiFxEIj=j0cS4~SOe#imk)J`s2Kt<Xbps3k-$ajWGKeJoG4CK3H9FYM>eF7d2w zTKQWM2!2Yc$Zs#B3_0AMN|YmycYJ3zZSE2jkl%D&wu8y;&uLs1^fcS0dMHXS%CADI z9X#sQ=)4T{Wh#^?LIbbUJL21cUs4o4Jj<}Bb)Je;%O%zahv`GPbLcVAeL*9o6cK@u z&U!2EzbtDLs}0{obaqj<W+TSL(qhzDu;OhuernE~k1SdVcJc*#a>})lCzOAQb)3^l Y|1%U1dF+>h;$b*T&2a7ze}qH-03nof+W-In diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__version__.py b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__version__.py index 9844f74..531e26c 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/requests/__version__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/requests/__version__.py @@ -4,11 +4,11 @@ __title__ = 'requests' __description__ = 'Python HTTP for Humans.' -__url__ = 'http://python-requests.org' -__version__ = '2.22.0' -__build__ = 0x022200 +__url__ = 'https://requests.readthedocs.io' +__version__ = '2.24.0' +__build__ = 0x022400 __author__ = 'Kenneth Reitz' __author_email__ = 'me@kennethreitz.org' __license__ = 'Apache 2.0' -__copyright__ = 'Copyright 2019 Kenneth Reitz' +__copyright__ = 'Copyright 2020 Kenneth Reitz' __cake__ = u'\u2728 \U0001f370 \u2728' diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/api.py b/venv/lib/python3.8/site-packages/pip/_vendor/requests/api.py index ef71d07..e978e20 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/requests/api.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/requests/api.py @@ -16,7 +16,7 @@ from . import sessions def request(method, url, **kwargs): """Constructs and sends a :class:`Request <Request>`. - :param method: method for the new :class:`Request` object. + :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``. :param url: URL for the new :class:`Request` object. :param params: (optional) Dictionary, list of tuples or bytes to send in the query string for the :class:`Request`. @@ -50,6 +50,7 @@ def request(method, url, **kwargs): >>> import requests >>> req = requests.request('GET', 'https://httpbin.org/get') + >>> req <Response [200]> """ @@ -92,7 +93,9 @@ def head(url, **kwargs): r"""Sends a HEAD request. :param url: URL for the new :class:`Request` object. - :param \*\*kwargs: Optional arguments that ``request`` takes. + :param \*\*kwargs: Optional arguments that ``request`` takes. If + `allow_redirects` is not provided, it will be set to `False` (as + opposed to the default :meth:`request` behavior). :return: :class:`Response <Response>` object :rtype: requests.Response """ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/auth.py b/venv/lib/python3.8/site-packages/pip/_vendor/requests/auth.py index bdde51c..eeface3 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/requests/auth.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/requests/auth.py @@ -50,7 +50,7 @@ def _basic_auth_str(username, password): "Non-string passwords will no longer be supported in Requests " "3.0.0. Please convert the object you've passed in ({!r}) to " "a string or bytes object in the near future to avoid " - "problems.".format(password), + "problems.".format(type(password)), category=DeprecationWarning, ) password = str(password) @@ -239,7 +239,7 @@ class HTTPDigestAuth(AuthBase): """ # If response is not 4xx, do not auth - # See https://github.com/requests/requests/issues/3772 + # See https://github.com/psf/requests/issues/3772 if not 400 <= r.status_code < 500: self._thread_local.num_401_calls = 1 return r diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/compat.py b/venv/lib/python3.8/site-packages/pip/_vendor/requests/compat.py index 6a86893..9e29371 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/requests/compat.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/requests/compat.py @@ -47,6 +47,7 @@ if is_py2: import cookielib from Cookie import Morsel from StringIO import StringIO + # Keep OrderedDict for backwards compatibility. from collections import Callable, Mapping, MutableMapping, OrderedDict @@ -63,6 +64,7 @@ elif is_py3: from http import cookiejar as cookielib from http.cookies import Morsel from io import StringIO + # Keep OrderedDict for backwards compatibility. from collections import OrderedDict from collections.abc import Callable, Mapping, MutableMapping diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/exceptions.py b/venv/lib/python3.8/site-packages/pip/_vendor/requests/exceptions.py index a91e1fd..9ef9e6e 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/requests/exceptions.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/requests/exceptions.py @@ -94,11 +94,11 @@ class ChunkedEncodingError(RequestException): class ContentDecodingError(RequestException, BaseHTTPError): - """Failed to decode response content""" + """Failed to decode response content.""" class StreamConsumedError(RequestException, TypeError): - """The content for this response was already consumed""" + """The content for this response was already consumed.""" class RetryError(RequestException): @@ -106,21 +106,18 @@ class RetryError(RequestException): class UnrewindableBodyError(RequestException): - """Requests encountered an error when trying to rewind a body""" + """Requests encountered an error when trying to rewind a body.""" # Warnings class RequestsWarning(Warning): """Base warning for Requests.""" - pass class FileModeWarning(RequestsWarning, DeprecationWarning): """A file was opened in text mode, but Requests determined its binary length.""" - pass class RequestsDependencyWarning(RequestsWarning): """An imported dependency doesn't match the expected version range.""" - pass diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/models.py b/venv/lib/python3.8/site-packages/pip/_vendor/requests/models.py index 0839957..015e715 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/requests/models.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/requests/models.py @@ -12,7 +12,7 @@ import sys # Import encoding now, to avoid implicit import later. # Implicit import within threads may cause LookupError when standard library is in a ZIP, -# such as in Embedded Python. See https://github.com/requests/requests/issues/3578. +# such as in Embedded Python. See https://github.com/psf/requests/issues/3578. import encodings.idna from pip._vendor.urllib3.fields import RequestField @@ -280,6 +280,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): >>> import requests >>> req = requests.Request('GET', 'https://httpbin.org/get') >>> r = req.prepare() + >>> r <PreparedRequest [GET]> >>> s = requests.Session() @@ -358,7 +359,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): #: We're unable to blindly call unicode/str functions #: as this will include the bytestring indicator (b'') #: on python 3.x. - #: https://github.com/requests/requests/pull/2238 + #: https://github.com/psf/requests/pull/2238 if isinstance(url, bytes): url = url.decode('utf8') else: @@ -472,12 +473,12 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): not isinstance(data, (basestring, list, tuple, Mapping)) ]) - try: - length = super_len(data) - except (TypeError, AttributeError, UnsupportedOperation): - length = None - if is_stream: + try: + length = super_len(data) + except (TypeError, AttributeError, UnsupportedOperation): + length = None + body = data if getattr(body, 'tell', None) is not None: @@ -608,7 +609,7 @@ class Response(object): #: File-like object representation of response (for advanced usage). #: Use of ``raw`` requires that ``stream=True`` be set on the request. - # This requirement does not apply for use internally to Requests. + #: This requirement does not apply for use internally to Requests. self.raw = None #: Final URL location of Response. @@ -915,7 +916,7 @@ class Response(object): return l def raise_for_status(self): - """Raises stored :class:`HTTPError`, if one occurred.""" + """Raises :class:`HTTPError`, if one occurred.""" http_error_msg = '' if isinstance(self.reason, bytes): diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/sessions.py b/venv/lib/python3.8/site-packages/pip/_vendor/requests/sessions.py index d73d700..e8e2d60 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/requests/sessions.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/requests/sessions.py @@ -11,9 +11,10 @@ import os import sys import time from datetime import timedelta +from collections import OrderedDict from .auth import _basic_auth_str -from .compat import cookielib, is_py3, OrderedDict, urljoin, urlparse, Mapping +from .compat import cookielib, is_py3, urljoin, urlparse, Mapping from .cookies import ( cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies) from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT @@ -162,7 +163,7 @@ class SessionRedirectMixin(object): resp.raw.read(decode_content=False) if len(resp.history) >= self.max_redirects: - raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects, response=resp) + raise TooManyRedirects('Exceeded {} redirects.'.format(self.max_redirects), response=resp) # Release the connection back into the pool. resp.close() @@ -170,7 +171,7 @@ class SessionRedirectMixin(object): # Handle redirection without scheme (see: RFC 1808 Section 4) if url.startswith('//'): parsed_rurl = urlparse(resp.url) - url = '%s:%s' % (to_native_string(parsed_rurl.scheme), url) + url = ':'.join([to_native_string(parsed_rurl.scheme), url]) # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2) parsed = urlparse(url) @@ -192,19 +193,16 @@ class SessionRedirectMixin(object): self.rebuild_method(prepared_request, resp) - # https://github.com/requests/requests/issues/1084 + # https://github.com/psf/requests/issues/1084 if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect): - # https://github.com/requests/requests/issues/3490 + # https://github.com/psf/requests/issues/3490 purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding') for header in purged_headers: prepared_request.headers.pop(header, None) prepared_request.body = None headers = prepared_request.headers - try: - del headers['Cookie'] - except KeyError: - pass + headers.pop('Cookie', None) # Extract any cookies sent on the response to the cookiejar # in the new request. Because we've mutated our copied prepared @@ -271,7 +269,6 @@ class SessionRedirectMixin(object): if new_auth is not None: prepared_request.prepare_auth(new_auth) - return def rebuild_proxies(self, prepared_request, proxies): """This method re-evaluates the proxy configuration by considering the @@ -352,13 +349,13 @@ class Session(SessionRedirectMixin): Or as a context manager:: >>> with requests.Session() as s: - >>> s.get('https://httpbin.org/get') + ... s.get('https://httpbin.org/get') <Response [200]> """ __attrs__ = [ 'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify', - 'cert', 'prefetch', 'adapters', 'stream', 'trust_env', + 'cert', 'adapters', 'stream', 'trust_env', 'max_redirects', ] @@ -661,11 +658,13 @@ class Session(SessionRedirectMixin): extract_cookies_to_jar(self.cookies, request, r.raw) - # Redirect resolving generator. - gen = self.resolve_redirects(r, request, **kwargs) - # Resolve redirects if allowed. - history = [resp for resp in gen] if allow_redirects else [] + if allow_redirects: + # Redirect resolving generator. + gen = self.resolve_redirects(r, request, **kwargs) + history = [resp for resp in gen] + else: + history = [] # Shuffle things around if there's history. if history: @@ -728,7 +727,7 @@ class Session(SessionRedirectMixin): return adapter # Nothing matches :-/ - raise InvalidSchema("No connection adapters were found for '%s'" % url) + raise InvalidSchema("No connection adapters were found for {!r}".format(url)) def close(self): """Closes all adapters and as such the session""" diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/status_codes.py b/venv/lib/python3.8/site-packages/pip/_vendor/requests/status_codes.py index 813e8c4..d80a7cd 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/requests/status_codes.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/requests/status_codes.py @@ -5,12 +5,15 @@ The ``codes`` object defines a mapping from common names for HTTP statuses to their numerical codes, accessible either as attributes or as dictionary items. ->>> requests.codes['temporary_redirect'] -307 ->>> requests.codes.teapot -418 ->>> requests.codes['\o/'] -200 +Example:: + + >>> import requests + >>> requests.codes['temporary_redirect'] + 307 + >>> requests.codes.teapot + 418 + >>> requests.codes['\o/'] + 200 Some codes have multiple names, and both upper- and lower-case versions of the names are allowed. For example, ``codes.ok``, ``codes.OK``, and diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/structures.py b/venv/lib/python3.8/site-packages/pip/_vendor/requests/structures.py index da930e2..8ee0ba7 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/requests/structures.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/requests/structures.py @@ -7,7 +7,9 @@ requests.structures Data structures that power Requests. """ -from .compat import OrderedDict, Mapping, MutableMapping +from collections import OrderedDict + +from .compat import Mapping, MutableMapping class CaseInsensitiveDict(MutableMapping): diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/requests/utils.py b/venv/lib/python3.8/site-packages/pip/_vendor/requests/utils.py index 8170a8d..c1700d7 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/requests/utils.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/requests/utils.py @@ -19,6 +19,7 @@ import sys import tempfile import warnings import zipfile +from collections import OrderedDict from .__version__ import __version__ from . import certs @@ -26,7 +27,7 @@ from . import certs from ._internal_utils import to_native_string from .compat import parse_http_list as _parse_list_header from .compat import ( - quote, urlparse, bytes, str, OrderedDict, unquote, getproxies, + quote, urlparse, bytes, str, unquote, getproxies, proxy_bypass, urlunparse, basestring, integer_types, is_py3, proxy_bypass_environment, getproxies_environment, Mapping) from .cookies import cookiejar_from_dict @@ -179,7 +180,7 @@ def get_netrc_auth(url, raise_errors=False): except KeyError: # os.path.expanduser can fail when $HOME is undefined and # getpwuid fails. See https://bugs.python.org/issue20164 & - # https://github.com/requests/requests/issues/1846 + # https://github.com/psf/requests/issues/1846 return if os.path.exists(loc): @@ -266,6 +267,8 @@ def from_key_val_list(value): >>> from_key_val_list([('key', 'val')]) OrderedDict([('key', 'val')]) >>> from_key_val_list('string') + Traceback (most recent call last): + ... ValueError: cannot encode objects that are not 2-tuples >>> from_key_val_list({'key': 'val'}) OrderedDict([('key', 'val')]) @@ -292,7 +295,9 @@ def to_key_val_list(value): >>> to_key_val_list({'key': 'val'}) [('key', 'val')] >>> to_key_val_list('string') - ValueError: cannot encode objects that are not 2-tuples. + Traceback (most recent call last): + ... + ValueError: cannot encode objects that are not 2-tuples :rtype: list """ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/six.py b/venv/lib/python3.8/site-packages/pip/_vendor/six.py index 89b2188..83f6978 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/six.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/six.py @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2018 Benjamin Peterson +# Copyright (c) 2010-2020 Benjamin Peterson # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ import sys import types __author__ = "Benjamin Peterson <benjamin@python.org>" -__version__ = "1.12.0" +__version__ = "1.15.0" # Useful for very coarse version differentiation. @@ -255,9 +255,11 @@ _moved_attributes = [ MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), MovedModule("builtins", "__builtin__"), MovedModule("configparser", "ConfigParser"), + MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"), MovedModule("copyreg", "copy_reg"), MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), - MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"), MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), MovedModule("http_cookies", "Cookie", "http.cookies"), MovedModule("html_entities", "htmlentitydefs", "html.entities"), @@ -637,13 +639,16 @@ if PY3: import io StringIO = io.StringIO BytesIO = io.BytesIO + del io _assertCountEqual = "assertCountEqual" if sys.version_info[1] <= 1: _assertRaisesRegex = "assertRaisesRegexp" _assertRegex = "assertRegexpMatches" + _assertNotRegex = "assertNotRegexpMatches" else: _assertRaisesRegex = "assertRaisesRegex" _assertRegex = "assertRegex" + _assertNotRegex = "assertNotRegex" else: def b(s): return s @@ -665,6 +670,7 @@ else: _assertCountEqual = "assertItemsEqual" _assertRaisesRegex = "assertRaisesRegexp" _assertRegex = "assertRegexpMatches" + _assertNotRegex = "assertNotRegexpMatches" _add_doc(b, """Byte literal""") _add_doc(u, """Text literal""") @@ -681,6 +687,10 @@ def assertRegex(self, *args, **kwargs): return getattr(self, _assertRegex)(*args, **kwargs) +def assertNotRegex(self, *args, **kwargs): + return getattr(self, _assertNotRegex)(*args, **kwargs) + + if PY3: exec_ = getattr(moves.builtins, "exec") @@ -716,16 +726,7 @@ else: """) -if sys.version_info[:2] == (3, 2): - exec_("""def raise_from(value, from_value): - try: - if from_value is None: - raise value - raise value from from_value - finally: - value = None -""") -elif sys.version_info[:2] > (3, 2): +if sys.version_info[:2] > (3,): exec_("""def raise_from(value, from_value): try: raise value from from_value @@ -805,13 +806,33 @@ if sys.version_info[:2] < (3, 3): _add_doc(reraise, """Reraise an exception.""") if sys.version_info[0:2] < (3, 4): + # This does exactly the same what the :func:`py3:functools.update_wrapper` + # function does on Python versions after 3.2. It sets the ``__wrapped__`` + # attribute on ``wrapper`` object and it doesn't raise an error if any of + # the attributes mentioned in ``assigned`` and ``updated`` are missing on + # ``wrapped`` object. + def _update_wrapper(wrapper, wrapped, + assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + for attr in assigned: + try: + value = getattr(wrapped, attr) + except AttributeError: + continue + else: + setattr(wrapper, attr, value) + for attr in updated: + getattr(wrapper, attr).update(getattr(wrapped, attr, {})) + wrapper.__wrapped__ = wrapped + return wrapper + _update_wrapper.__doc__ = functools.update_wrapper.__doc__ + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, updated=functools.WRAPPER_UPDATES): - def wrapper(f): - f = functools.wraps(wrapped, assigned, updated)(f) - f.__wrapped__ = wrapped - return f - return wrapper + return functools.partial(_update_wrapper, wrapped=wrapped, + assigned=assigned, updated=updated) + wraps.__doc__ = functools.wraps.__doc__ + else: wraps = functools.wraps @@ -824,7 +845,15 @@ def with_metaclass(meta, *bases): class metaclass(type): def __new__(cls, name, this_bases, d): - return meta(name, bases, d) + if sys.version_info[:2] >= (3, 7): + # This version introduced PEP 560 that requires a bit + # of extra care (we mimic what is done by __build_class__). + resolved_bases = types.resolve_bases(bases) + if resolved_bases is not bases: + d['__orig_bases__'] = bases + else: + resolved_bases = bases + return meta(name, resolved_bases, d) @classmethod def __prepare__(cls, name, this_bases): @@ -861,12 +890,11 @@ def ensure_binary(s, encoding='utf-8', errors='strict'): - `str` -> encoded to `bytes` - `bytes` -> `bytes` """ + if isinstance(s, binary_type): + return s if isinstance(s, text_type): return s.encode(encoding, errors) - elif isinstance(s, binary_type): - return s - else: - raise TypeError("not expecting type '%s'" % type(s)) + raise TypeError("not expecting type '%s'" % type(s)) def ensure_str(s, encoding='utf-8', errors='strict'): @@ -880,12 +908,15 @@ def ensure_str(s, encoding='utf-8', errors='strict'): - `str` -> `str` - `bytes` -> decoded to `str` """ - if not isinstance(s, (text_type, binary_type)): - raise TypeError("not expecting type '%s'" % type(s)) + # Optimization: Fast return for the common case. + if type(s) is str: + return s if PY2 and isinstance(s, text_type): - s = s.encode(encoding, errors) + return s.encode(encoding, errors) elif PY3 and isinstance(s, binary_type): - s = s.decode(encoding, errors) + return s.decode(encoding, errors) + elif not isinstance(s, (text_type, binary_type)): + raise TypeError("not expecting type '%s'" % type(s)) return s @@ -908,10 +939,9 @@ def ensure_text(s, encoding='utf-8', errors='strict'): raise TypeError("not expecting type '%s'" % type(s)) - def python_2_unicode_compatible(klass): """ - A decorator that defines __unicode__ and __str__ methods under Python 2. + A class decorator that defines __unicode__ and __str__ methods under Python 2. Under Python 3 it does nothing. To support Python 2 and 3 with a single code base, define a __str__ method diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__init__.py index c4c0dde..667e9bc 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__init__.py @@ -4,11 +4,7 @@ urllib3 - Thread-safe connection pooling and re-using. from __future__ import absolute_import import warnings -from .connectionpool import ( - HTTPConnectionPool, - HTTPSConnectionPool, - connection_from_url -) +from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, connection_from_url from . import exceptions from .filepost import encode_multipart_formdata @@ -24,25 +20,25 @@ from .util.retry import Retry import logging from logging import NullHandler -__author__ = 'Andrey Petrov (andrey.petrov@shazow.net)' -__license__ = 'MIT' -__version__ = '1.25.3' +__author__ = "Andrey Petrov (andrey.petrov@shazow.net)" +__license__ = "MIT" +__version__ = "1.25.9" __all__ = ( - 'HTTPConnectionPool', - 'HTTPSConnectionPool', - 'PoolManager', - 'ProxyManager', - 'HTTPResponse', - 'Retry', - 'Timeout', - 'add_stderr_logger', - 'connection_from_url', - 'disable_warnings', - 'encode_multipart_formdata', - 'get_host', - 'make_headers', - 'proxy_from_url', + "HTTPConnectionPool", + "HTTPSConnectionPool", + "PoolManager", + "ProxyManager", + "HTTPResponse", + "Retry", + "Timeout", + "add_stderr_logger", + "connection_from_url", + "disable_warnings", + "encode_multipart_formdata", + "get_host", + "make_headers", + "proxy_from_url", ) logging.getLogger(__name__).addHandler(NullHandler()) @@ -59,10 +55,10 @@ def add_stderr_logger(level=logging.DEBUG): # even if urllib3 is vendored within another package. logger = logging.getLogger(__name__) handler = logging.StreamHandler() - handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s')) + handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s")) logger.addHandler(handler) logger.setLevel(level) - logger.debug('Added a stderr logging handler to logger: %s', __name__) + logger.debug("Added a stderr logging handler to logger: %s", __name__) return handler @@ -74,18 +70,17 @@ del NullHandler # shouldn't be: otherwise, it's very hard for users to use most Python # mechanisms to silence them. # SecurityWarning's always go off by default. -warnings.simplefilter('always', exceptions.SecurityWarning, append=True) +warnings.simplefilter("always", exceptions.SecurityWarning, append=True) # SubjectAltNameWarning's should go off once per host -warnings.simplefilter('default', exceptions.SubjectAltNameWarning, append=True) +warnings.simplefilter("default", exceptions.SubjectAltNameWarning, append=True) # InsecurePlatformWarning's don't vary between requests, so we keep it default. -warnings.simplefilter('default', exceptions.InsecurePlatformWarning, - append=True) +warnings.simplefilter("default", exceptions.InsecurePlatformWarning, append=True) # SNIMissingWarnings should go off only once. -warnings.simplefilter('default', exceptions.SNIMissingWarning, append=True) +warnings.simplefilter("default", exceptions.SNIMissingWarning, append=True) def disable_warnings(category=exceptions.HTTPWarning): """ Helper for quickly disabling all urllib3 warnings. """ - warnings.simplefilter('ignore', category) + warnings.simplefilter("ignore", category) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-38.pyc index f815b1d364f9e679a7f6836617eb0264d5f4ad03..ac4fe2050e0f85f6433baece100dd6fa27b48734 100644 GIT binary patch delta 136 zcmZ1`a9n^ll$V!_0SGkz?TWA7$a{u~(Q@-GCS4}yB>jy1+*JLd%F@!TO#R}bWc`%H zyv)>`<ou$N)MCAg$}0V`)VwnNoXjNsg36MN{5)el3;p8El2qM-#N_P6^wi?Xs;sJv m`jfp`UoZx3HeuVr$YTVwiG`Vmk%LKuY4Q(tH5MTzA!Y#h2q_)_ delta 103 zcmX>uuuOnAl$V!_0SKO#ZHQaAk@pM}qw(fjOu9^Rw)!Qx1^NY<1-hAe#U+V3Il4v} zCZ!d|`H3LG$zH6gjK-4-SYI%PZ;oW!!N_9<G=znjhmnIxgl)1chZ+YLBh!C2W+7$( DMmZZ$ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-38.pyc index bbe823d8ac413244fce61d2bb0b22ee9900d2fa5..9801f04b660e2d1bb837b68f02b7ec8ef0c23834 100644 GIT binary patch delta 820 zcmXAnZ%7ky7{~YA?ryh#=VWu6PF**r+fsLwC}n1mk^LjnrS=cj+)ka&Iqq(f(u+Vt z1dHM+DkAy=QiNFJUPKb~E}~aO;ESSn72%tD-HYt^TX)=t=bqp5kMHmKohT*5L8sGZ zB2Vn^dNR7bB$l9OR34w6Qe<_uSe(epnwpj~seD$+rKeS0(c%|p=j0hBKO^U|BXVI@ zAD_;*#dpbCR##dJsq|!OOwsTw$lyRHvj`P<i^+i9_`~#=A&%YrduTVTmc0O7*eiU3 zV;Hcm!T`RrzO5W0gJ?V*2N+<s=ISve_|dSvhI3f3zW@a#$E`p;jq(r(z&csRW)Unx z1^HNkGd?<sJS=0c`w85}U+(*G53hPI!vhqnuE1lwS#`~4&aexnOYo3;WIAY?hk2M} z5~di3yS;~n7^nwG;TSG?8{ru~_jX{vZ@{}kJBkD*@Bj-UIG`4IeC0dJpCV3m043fn z@X2IeNha4Y?APEW-ti->8!gof0B^8VGXukzukz#mfB+wiBY~#?Lo|&ur!tuh!&av= z_9QK4rZ|C1!4M>HHQ40)K^$6?z{EL-E-dg{%ofWU--8m=4%6t<1Tj{%Qaem>hN4{F zW*JlTTvpQ=z<rYD?xQCzijx%m1X!^7EviyblSwarlNO20xloWaUk*u7jccJv=);<Z zW{~hu!v>l9M##^Nki;hJ4FBY4iB^m>USO$@6!Y+EnpkbdN@F`f7QZy@g!3pyQqX~g zi2h%)LEMaN3)8{X9TaU84HRc7%1U%mOTl=wqh*wudnm>!Xs7b*<xZdN>0C<FrWCS^ z8CA#Y(PnvqL}=XvWJx5^PL_ie%;dESW+EW)49}21&QU4wf=j5y&FC5w@oucMj$z0p Wi{K?vyFg?-f`eSQhvf2R*YSVUN5I_x delta 783 zcmX|;Ur1AN6vywmclWn@_pjNm+gj$@rqiJ|)bha!v?6Q~Ij30`uH~j%P967NS42Uf zU{5`ChzKk4Ax(@>FZCex&`UuDAwfh%<Wu$#^{i0+eg^#>KIib|ob&zt&Tk>{E8*y} z+btYD--`3SYmo)V0+hE#^`SzvkSo;XhBZBv&(}3%caENK97!<|c|HmjY~Uxrj!S$R zWWz7)7oZmV$SY_xc9{19G-F<R2ZyjlehBUOLw;fJq#hd2oZvz^wwS&6+42;+@s@QS zQW&${fHM4Q+X8~IW*a4N6$`EzK=dki;3hs%E?Xx555VV&f}N#VxQow9uX)6@X`H(V z_rxjg05=9>Fvusk2*ES%Hfa{reY9^D7u}UGjUU`im~*$9)fg4k!+6E&DmhBi88+KQ zVd4mf4o`=BiYX2X4iqqf18g)ZSoFlmF)FH^xGcLQl1vU~lF3<I@o2D!U0#I8#&_>H zz!DDoisS?<ZKI_M{`Q&SwL!K%065NiMIn_=FB>n*bl#d`WdcJx9`pyH3v>RkYlRA0 z1qCPCfB^YJcw^chfU=FLJyegFRG9{q6{#l~*l0x_$msc;rmu6?1DZ3=bSFaxLjvE( zUYrcbunF%6CSU;Tf`00FBp86rI1(I$IDQJ&fDg@~_w=e?LS8XV8~wN*S``yC3*&0V zX~HyBVjC1QG_5uID|Z15;_Yw)^y1ra3ZhtFrT^PjH_laUuV7bJ>lqpuLJX%EHr~I7 zWdr!Ls;M^1(%lSa88)n#v&x)4TKn=TO&iMS*^#tb#CUZL^y8&!k4KUO6I&Edcu9~% oTZu#@r{u%A>PK)6dm_!-fTzFc05^?J8WqXL{#B3!A~<7z0Y?PC0RR91 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-38.pyc index 121685f80c01730929fd417ae9a854f0d27ae495..1f6e0b73cc9722406d1d23deecbd1a3b6f537ab5 100644 GIT binary patch delta 3138 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 HqN)D}z?Izh delta 3293 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 PDta<{OOI%>N;LUDQ8&ZQ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-38.pyc index 94fc1e6553969c057f50711935f1e83696cad2dc..06c2b58aa0b6f272a635ae62e5ca1f0a1faaaf0c 100644 GIT binary patch delta 3642 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 Q#HO;aG42hPg$}j-zh$9E>i_@% delta 3409 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-38.pyc index 36dda800c8fdeb8fb1e50d9aad497a5ab8d619d2..4fc5d5cddf5db205dacbcdd1ed66ae8236efa215 100644 GIT binary patch delta 2152 zcmY*ZT}&KR6rMXfyX>xXyUWl51!SO0VGHbn6ay3rlv1E=NENEFX~kh@V5ePX@XRcQ zW)%&_5EEP58(&N{M4R}cNt;F=?2CQVMiVtAM&g5-n5bzq#s_`S)^jdDF0+|4d%o}d z-Jf&bAG<seIkjU)Si&c9|D#Ez>Pn=Fow?ccJzEMc`%cG)C8NjaeMvHU&4^jCtemb# z<dD&aNS_%%i+!l~8w02hm;qBk3m+nfjX^{Pg+&AEM~orVhs;J1BZ0_KV;GTPVX+_e z5n~kfQK2^($HpZ&ah&Jn&jyWD#+fx!u$ar8vr;akQ-*F^W;X4BXS&IS#fzzV)1FUd zt*O-9qL*>(_GD+uwLG(BPEViLXH1t*`x;mgzvO$372m2+erK^5uGbBq2r@+uDiGmq zp;G>!G{k!XKQfKi6g|h{{LP{<Ke6S=9^mm{nkD#3u#T^W72dnIncod|Ev0?5cN>p_ zU($>4b?Z=glE?DWvV2a?v%EYl=Y4O<mn0_T<-9cMGo*0|D$p#UtohyCoC#2c8bnd7 zMI5kZEL+b`BJ4my0V*0wi1Q0*P0=AW<AO@~LnMkxkarutE>$D3a&}QY3C_ae5QX7i z*TwlAEgqvp$xSQT1)d7Mq3%WG(E^mgUa|IQ*iz$&AKb>pY1eM8hJRsfAHTP&YUg7_ z)3!=1AQ#L0cJXnw9<^b@sT@ocf_kyptKmI-c*j3%KY6k<T#vK_5@-Sq{D)Z8&Zi1o zWM~vs{27^2n-HJc#x)7<+Rk6qX2dfETmYH{_j%NdwIB`!9OKXIuHj>$GQJXfR;8U- zEMy@mJo`%)A}Pe5-{Sb?vM&Ch#8F!jTHb=0!l0GEs9slT>sPknZ6Z{*H0yr^@mKl& z@;ba~_t*ik^4EE2cMEIaH$&xWJMvcxd}U}y-|BakcC%;);@61VxVF4+PZ$5B?5x^} z;M)aG3_AIj@eV#)?)keAf0wsaALfk}X|)@*_qJJfi_*TTm{jRxZ*Job3T|P~MYRX< z54UkWg6pcxsJ)2a-p2I`?&r#@>LJ8GF5vudh`1$f)SlO~mLaa?pkq&4Gda*b%dwx- z!M5xf{b?piVGSPwOhdbnF>Nj9BBklJHZn1Ba$K9EOO2}WKXmHx6G?3_2VmM>c2NY# zK^7-NyJk41Yd3frw%O7gj*fyLmg$NxUdG%Adcn$OwJB2sNISNtr#&oU-qMAaX4$T1 z>PAwV$XKp+VZCN8jg?KA+O)NRwo~ib(;3~yCZ5q2og8eYToQ$2tr*C2Hml!AO-l%i z#G}*XrI~ix$=RL>npc<&umFK{3*(IE&AHvF)Qsh2a#P8)Gn?92`PSER-JI#B+B%Cm zT7?gfRadHgcs`#NoKYD1#QEK+I`8jC{2TsqZ5_Yi)3{rGLmfcmy8>%J44`!>O~hMc z5BD%XR3po;)O51n_}!Y7z+qHjkiSq=#vLsj`-6OgC?qCh%P9Bxiq;W2LPj($`4?J6 z>?i!QdC7ytK2StG$=Y#s2${c$-54bdhBmX~JZ|CN)?N=#emKgP>sn>T_y={3eyBwV zBkxj=;-7yD{C#M+Q9b(qweCB@yW{<Gi1B<pp=`O1pj!Yh<z{LbMzG0ND^4IDDZm*J zGL~rOuhhR7pm7Ru9^1ETiN+u_lAs9&G^#+%BpN+HGX`j)0F95e@DqAAXNrLhG&6t( z1JDEj>UN;E2I^*@wgu`>phg7hIG`hiei8#DXxG*%BLl8$0`=H>SlSDqRlx}yJ!NOt zf<3d2k;|Hga5a*93`H?3_DAVgj6Z)gh;Kj%L`$NfXdoIcDT?|_1dlR|$hz&i3`HY| MhDubl2}Ohd0T?UdP5=M^ delta 1513 zcmY+DUuau(6vyxH=H`Es-1IhW)4yqwHc4yjy8hWZ`!D@tD~>v7r&6(!H5XRQns|~* zRmPkXw+Erx1A?0m^AElZp`+-7pj3U(2cb+5AukpY=43JiVJ|{G=a&|fT=Kj3d_U*> z?(d#In~R^#d(V12E`@$~U*2B+G5D^xMV!9fvo9`r&EOSnDLSiUMlz#sDw$E!cEz&P zN%mM~oa}MaW@_YNA!Q<yA|)j~y2zf)Op!fh#^fGxQl>LAq|8W<1lf;gX33tFc6VlO zK}kGuk57>hC13hnA(zGL>ep@Ky~PXp-u!Alxw=*;rnA}P@$&=g8~wR7i+IBl6At{& z@{aKAENTygr<Qgo*l2MGP3)YpS%hfEMf*h&!Jq8&LSTpEhKS==jxg%(5c-_M_;+)& zzl9=_9I73L;#02cMk^V|D^+O4JC*@F=3X`0NIy}<+KAQd?7Hs>5yE9(OW-u)8d?-# zQ&piV>VeIIKYN}u+DV&adiXjgv~w`-x|=ZV{Z~XeUObDh`I5E>`9TNXaWxuYdOTYZ zrb1Yr$D^OakXQ38S1^Hn-g^0sU+8}tT|`zYs1>?o<XwN!h>@PHU;<*2eN_9B5of)M z#U)!ZHjD)68&xbJS+Fi=bd!Fuigio2SC{wqkp4y`!`Jm8d@GQ}n|{r6wTj&K*JH5$ zzIaq7WD_F|Nm0%PSL^KxUlo${hSrbYZxDJf>F+T+Yy{jlhVi$?=dE1K5Ab0ijJvT8 zyc#ST{iJ-zu1AH3etFQzrWIp=^iQkUfMoZZUN8npzg5KsCEIF#)fgguyNV4-w$O6k z;FkHkik*;5ZQb&pB>l?@rs0|35PsACqIH<mZ?~Ezu@KrePLc6_r5l{0Ex38Ko%xOt zVJ}$=>v<D!Gkj9~f<J_>xktzyMtKR~%|spMA`V}Px8MXRLKUt9ycQW0W7yz|1vnLZ zN0jEsUSk1Go-!I;uuc&975hSzL$`*FT}j-Feqwu!R7l|~oyXKa6ui|L#{*}x3gdV= z)@Y;%{!ag+BwNVy@Wiyi!*cL624WNH0|lRnCB&4Bo2Hn*D&ho8%VX@vvcWmh|EXfE z%qM!#j9<RQlM6heCErwTZOvRMuIAQe0CE64d%%+foxJd50FMB0uLCzVaQ6bYY033; zI=gO`10P|P+YY$DfO`qJeSrG}xFLWm4^-kl1-O{Nbpx&!OwdyDrV0fU{yz%m1^6Rj zj^?}Jxsqe#LN2qOHOB;r1^%EKQDf7sbh+u`yH&SoR^8B@^yI9y>(*MS((2O7o@Fnq O?jX%ktCNRQxBmwM#W<M& diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-38.pyc index e7fb4dd2583179c7bad535aa161bc3f72756eebb..5d44a0c473f3ba302973987fbdc26e5b2432d8d3 100644 GIT binary patch delta 338 zcmW-aJxc>Y5Qa0e>t%D^UHnJ_l8`1uNWd&8h+PT`u@VtWKVm%0Y0Sr65^@1MyMTpP z*ogl@w$erjSSg6Ttv^8!kvn&tfwy_)nfI>xTs3!1Q;*3hg^vf$y}5<!hrH1~x4G;0 z`=<`~+&Vw5wH&)yZ@WF)s|@`SAK0w{Z#qZ3<M$fv)=FiKdrr?@>eT9IwG-P5M)(SD zut7@TiY_S<SQa<hDkL{$lgDIeh`>Ve5g!A@f<|IIzpaoVBL)VckclW2y6zL$7nkOc zOkXK(Db7TEc8bDWV5YM`L@E6OFcDvwJ%l&0v+xe^DT>(%X1|q^QcBVSOEyX=!Vn|I zuJgBr3x#ts7|;}g+#h`g!74D5W!S$LJmnwCi}J((rWOsNTda)o7yfFDf`%-l5lu)X GN68;O=S~g) delta 280 zcmX?VKhK^wl$V!_0SKO#ZHTMi$m`D}XRTk7TcBT%S)iMlS6q^qlcQ^tVNzOQoSz61 zoIIcD3}f-+9A-_%;?2{TRhb!$H}7FHW90V$8dA&wB-ogkm^l7!X5{E*WMrJ&%h@d+ z0Fn{_5)4c{%q)ytjBNke{<E-c*5;~YW=z<;l(&MJyC0;652S{DvxXom3!~U%JyB^! zrp;cWrx_WKZWa@dWn#RvxkU0JBjbzBZqkRCB!7dn2!XWl@iFo-GBL0)3jJsL&&4`f zS#FMUJxEptNN_N+2s1GP;V&+JCRV0DJZc=g9AX^842+W>$?arRnmk8dl81|#<1YsX KhX98R3o`(}(m#d( diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-38.pyc index 2c77f521754be7f55609fe9cee6253d48866bcf6..f20915bf8103606187351b25f67f1e336da84ad0 100644 GIT binary patch delta 130 zcmZ22dO?&ol$V!_0SGkz?TYW%$g9W5SUlN=aYlmCEw+@@<ouLWO~zXsN%^IDDTzgu zD;bJ}fNFmw>1X8Urs@|}mX>B^>K7L!>!&2<Wv1pN=NFZv7VA}1R_T|e=9TH^WG3ks gRF-7q=Nao+=oe>}r0NzVCTAz6rxtJKXPUzS0RM0-?EnA( delta 93 zcmca0x>}Ssl$V!_0SKO#ZHQ~x$g9W5STxy&afY?=Ew+@@<ouLWO~zXsN%^IDDTzgu tD;bJ}fNFo)>X+me=oe%b=w{{>mn7!o=o)31lvWt$CxQewn=sAc003H;9(4c! diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-38.pyc index 08d9102da74235651838d43620765c1f3b0120d3..6d292f4c34ce005451178b59b81a5cfd7cf0e407 100644 GIT binary patch delta 3652 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 Dm9b%l delta 2969 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 Kww18>!hZqOh<;lD diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-38.pyc index 369e119fea0ee86d9d58b289aac59b7c5044d832..c1e0a38b1de34562b33c9ac1fd710252f70160c4 100644 GIT binary patch delta 278 zcmcbpJwt~#l$V!_0SGkz?TT;O$XmeboT#6XpPQ;*R9RY@m8oA`l&qhUn3tKFlbl~v zl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2(-keHmEn4Vg^c{Zy%BNrRUTrMU? zrvIB?un9ApS_8SoS|CAg4kivJE=CqcCI+VeKm|Y&$o|j9f-X`eHn~wmY_l0x4kLFk zNIM@$JL~4P+$%Y>lR*Mt^K>~F*?=apFmf=0tYZP012&b1m5q_<9~<lBa*=gPazOPQ cj4U!dOkC^?j9~bai=Rt^O9aN7>@3;`0OE~2xc~qF delta 201 zcmbQCb5WZ&l$V!_0SKO#ZHP<X$XmcFXQN+|TcBT%S)iMlS6q^qlcQ^tVNzOQoSz61 z+<bu5oso?Rq=k92AiFTLvJsG3ECmwa=3wGr;$q}sWcts-#PpAi1;*MO&eg)m?FCZE z2U5tk`5E_04#jAYfC5NBjRR;V2NMe;2O|?mH!};P5ECEM<Xs}`<UmGqFtW(-FmW+6 UFakOMx!AZQxC9~W$z7s-0PyuE0{{R3 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-38.pyc index 0b6399a4fad4a23b10dca4cc7fcc7ea3406c8e71..57b5a2d7f0916825e216ae38e3d74b166b561ab0 100644 GIT binary patch delta 6878 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 delta 6124 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 T>q@9C<O#LvBvcuy(E|SiGguDv diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/_collections.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/_collections.py index 34f2381..019d151 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/_collections.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/_collections.py @@ -1,4 +1,5 @@ from __future__ import absolute_import + try: from collections.abc import Mapping, MutableMapping except ImportError: @@ -6,6 +7,7 @@ except ImportError: try: from threading import RLock except ImportError: # Platform-specific: No threads available + class RLock: def __enter__(self): pass @@ -19,7 +21,7 @@ from .exceptions import InvalidHeader from .packages.six import iterkeys, itervalues, PY3 -__all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict'] +__all__ = ["RecentlyUsedContainer", "HTTPHeaderDict"] _Null = object() @@ -82,7 +84,9 @@ class RecentlyUsedContainer(MutableMapping): return len(self._container) def __iter__(self): - raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.') + raise NotImplementedError( + "Iteration over this class is unlikely to be threadsafe." + ) def clear(self): with self.lock: @@ -150,7 +154,7 @@ class HTTPHeaderDict(MutableMapping): def __getitem__(self, key): val = self._container[key.lower()] - return ', '.join(val[1:]) + return ", ".join(val[1:]) def __delitem__(self, key): del self._container[key.lower()] @@ -159,12 +163,13 @@ class HTTPHeaderDict(MutableMapping): return key.lower() in self._container def __eq__(self, other): - if not isinstance(other, Mapping) and not hasattr(other, 'keys'): + if not isinstance(other, Mapping) and not hasattr(other, "keys"): return False if not isinstance(other, type(self)): other = type(self)(other) - return (dict((k.lower(), v) for k, v in self.itermerged()) == - dict((k.lower(), v) for k, v in other.itermerged())) + return dict((k.lower(), v) for k, v in self.itermerged()) == dict( + (k.lower(), v) for k, v in other.itermerged() + ) def __ne__(self, other): return not self.__eq__(other) @@ -184,9 +189,9 @@ class HTTPHeaderDict(MutableMapping): yield vals[0] def pop(self, key, default=__marker): - '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. + """D.pop(k[,d]) -> v, remove specified key and return the corresponding value. If key is not found, d is returned if given, otherwise KeyError is raised. - ''' + """ # Using the MutableMapping function directly fails due to the private marker. # Using ordinary dict.pop would expose the internal structures. # So let's reinvent the wheel. @@ -228,8 +233,10 @@ class HTTPHeaderDict(MutableMapping): with self.add instead of self.__setitem__ """ if len(args) > 1: - raise TypeError("extend() takes at most 1 positional " - "arguments ({0} given)".format(len(args))) + raise TypeError( + "extend() takes at most 1 positional " + "arguments ({0} given)".format(len(args)) + ) other = args[0] if len(args) >= 1 else () if isinstance(other, HTTPHeaderDict): @@ -295,7 +302,7 @@ class HTTPHeaderDict(MutableMapping): """Iterate over all headers, merging duplicate ones together.""" for key in self: val = self._container[key.lower()] - yield val[0], ', '.join(val[1:]) + yield val[0], ", ".join(val[1:]) def items(self): return list(self.iteritems()) @@ -306,7 +313,7 @@ class HTTPHeaderDict(MutableMapping): # python2.7 does not expose a proper API for exporting multiheaders # efficiently. This function re-reads raw lines from the message # object and extracts the multiheaders properly. - obs_fold_continued_leaders = (' ', '\t') + obs_fold_continued_leaders = (" ", "\t") headers = [] for line in message.headers: @@ -316,14 +323,14 @@ class HTTPHeaderDict(MutableMapping): # in RFC-7230 S3.2.4. This indicates a multiline header, but # there exists no previous header to which we can attach it. raise InvalidHeader( - 'Header continuation with no previous header: %s' % line + "Header continuation with no previous header: %s" % line ) else: key, value = headers[-1] - headers[-1] = (key, value + ' ' + line.strip()) + headers[-1] = (key, value + " " + line.strip()) continue - key, value = line.split(':', 1) + key, value = line.split(":", 1) headers.append((key, value.strip())) return cls(headers) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/connection.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/connection.py index 57c58fe..6da1cf4 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/connection.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/connection.py @@ -1,4 +1,5 @@ from __future__ import absolute_import +import re import datetime import logging import os @@ -11,6 +12,7 @@ from .packages.six.moves.http_client import HTTPException # noqa: F401 try: # Compiled with SSL? import ssl + BaseSSLError = ssl.SSLError except (ImportError, AttributeError): # Platform-specific: No SSL. ssl = None @@ -41,7 +43,7 @@ from .util.ssl_ import ( resolve_ssl_version, assert_fingerprint, create_urllib3_context, - ssl_wrap_socket + ssl_wrap_socket, ) @@ -51,20 +53,18 @@ from ._collections import HTTPHeaderDict log = logging.getLogger(__name__) -port_by_scheme = { - 'http': 80, - 'https': 443, -} +port_by_scheme = {"http": 80, "https": 443} -# When updating RECENT_DATE, move it to within two years of the current date, -# and not less than 6 months ago. -# Example: if Today is 2018-01-01, then RECENT_DATE should be any date on or -# after 2016-01-01 (today - 2 years) AND before 2017-07-01 (today - 6 months) -RECENT_DATE = datetime.date(2017, 6, 30) +# When it comes time to update this value as a part of regular maintenance +# (ie test_recent_date is failing) update it to ~6 months before the current date. +RECENT_DATE = datetime.date(2019, 1, 1) + +_CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]") class DummyConnection(object): """Used to detect a failed ConnectionCls import.""" + pass @@ -92,7 +92,7 @@ class HTTPConnection(_HTTPConnection, object): Or you may want to disable the defaults by passing an empty list (e.g., ``[]``). """ - default_port = port_by_scheme['http'] + default_port = port_by_scheme["http"] #: Disable Nagle's algorithm by default. #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]`` @@ -102,15 +102,15 @@ class HTTPConnection(_HTTPConnection, object): is_verified = False def __init__(self, *args, **kw): - if six.PY3: - kw.pop('strict', None) + if not six.PY2: + kw.pop("strict", None) # Pre-set source_address. - self.source_address = kw.get('source_address') + self.source_address = kw.get("source_address") #: The socket options provided by the user. If no options are #: provided, we use the default options. - self.socket_options = kw.pop('socket_options', self.default_socket_options) + self.socket_options = kw.pop("socket_options", self.default_socket_options) _HTTPConnection.__init__(self, *args, **kw) @@ -131,7 +131,7 @@ class HTTPConnection(_HTTPConnection, object): those cases where it's appropriate (i.e., when doing DNS lookup to establish the actual TCP connection across which we're going to send HTTP requests). """ - return self._dns_host.rstrip('.') + return self._dns_host.rstrip(".") @host.setter def host(self, value): @@ -150,30 +150,34 @@ class HTTPConnection(_HTTPConnection, object): """ extra_kw = {} if self.source_address: - extra_kw['source_address'] = self.source_address + extra_kw["source_address"] = self.source_address if self.socket_options: - extra_kw['socket_options'] = self.socket_options + extra_kw["socket_options"] = self.socket_options try: conn = connection.create_connection( - (self._dns_host, self.port), self.timeout, **extra_kw) + (self._dns_host, self.port), self.timeout, **extra_kw + ) except SocketTimeout: raise ConnectTimeoutError( - self, "Connection to %s timed out. (connect timeout=%s)" % - (self.host, self.timeout)) + self, + "Connection to %s timed out. (connect timeout=%s)" + % (self.host, self.timeout), + ) except SocketError as e: raise NewConnectionError( - self, "Failed to establish a new connection: %s" % e) + self, "Failed to establish a new connection: %s" % e + ) return conn def _prepare_conn(self, conn): self.sock = conn # Google App Engine's httplib does not define _tunnel_host - if getattr(self, '_tunnel_host', None): + if getattr(self, "_tunnel_host", None): # TODO: Fix tunnel so it doesn't depend on self.sock state. self._tunnel() # Mark this connection as not reusable @@ -183,24 +187,32 @@ class HTTPConnection(_HTTPConnection, object): conn = self._new_conn() self._prepare_conn(conn) + def putrequest(self, method, url, *args, **kwargs): + """Send a request to the server""" + match = _CONTAINS_CONTROL_CHAR_RE.search(method) + if match: + raise ValueError( + "Method cannot contain non-token characters %r (found at least %r)" + % (method, match.group()) + ) + + return _HTTPConnection.putrequest(self, method, url, *args, **kwargs) + def request_chunked(self, method, url, body=None, headers=None): """ Alternative to the common request method, which sends the body with chunked encoding and not as one block """ headers = HTTPHeaderDict(headers if headers is not None else {}) - skip_accept_encoding = 'accept-encoding' in headers - skip_host = 'host' in headers + skip_accept_encoding = "accept-encoding" in headers + skip_host = "host" in headers self.putrequest( - method, - url, - skip_accept_encoding=skip_accept_encoding, - skip_host=skip_host + method, url, skip_accept_encoding=skip_accept_encoding, skip_host=skip_host ) for header, value in headers.items(): self.putheader(header, value) - if 'transfer-encoding' not in headers: - self.putheader('Transfer-Encoding', 'chunked') + if "transfer-encoding" not in headers: + self.putheader("Transfer-Encoding", "chunked") self.endheaders() if body is not None: @@ -211,29 +223,42 @@ class HTTPConnection(_HTTPConnection, object): if not chunk: continue if not isinstance(chunk, bytes): - chunk = chunk.encode('utf8') + chunk = chunk.encode("utf8") len_str = hex(len(chunk))[2:] - self.send(len_str.encode('utf-8')) - self.send(b'\r\n') + self.send(len_str.encode("utf-8")) + self.send(b"\r\n") self.send(chunk) - self.send(b'\r\n') + self.send(b"\r\n") # After the if clause, to always have a closed body - self.send(b'0\r\n\r\n') + self.send(b"0\r\n\r\n") class HTTPSConnection(HTTPConnection): - default_port = port_by_scheme['https'] + default_port = port_by_scheme["https"] + cert_reqs = None + ca_certs = None + ca_cert_dir = None + ca_cert_data = None ssl_version = None + assert_fingerprint = None - def __init__(self, host, port=None, key_file=None, cert_file=None, - key_password=None, strict=None, - timeout=socket._GLOBAL_DEFAULT_TIMEOUT, - ssl_context=None, server_hostname=None, **kw): + def __init__( + self, + host, + port=None, + key_file=None, + cert_file=None, + key_password=None, + strict=None, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + ssl_context=None, + server_hostname=None, + **kw + ): - HTTPConnection.__init__(self, host, port, strict=strict, - timeout=timeout, **kw) + HTTPConnection.__init__(self, host, port, strict=strict, timeout=timeout, **kw) self.key_file = key_file self.cert_file = cert_file @@ -243,54 +268,20 @@ class HTTPSConnection(HTTPConnection): # Required property for Google AppEngine 1.9.0 which otherwise causes # HTTPS requests to go out as HTTP. (See Issue #356) - self._protocol = 'https' + self._protocol = "https" - def connect(self): - conn = self._new_conn() - self._prepare_conn(conn) - - # Wrap socket using verification with the root certs in - # trusted_root_certs - default_ssl_context = False - if self.ssl_context is None: - default_ssl_context = True - self.ssl_context = create_urllib3_context( - ssl_version=resolve_ssl_version(self.ssl_version), - cert_reqs=resolve_cert_reqs(self.cert_reqs), - ) - - # Try to load OS default certs if none are given. - # Works well on Windows (requires Python3.4+) - context = self.ssl_context - if (not self.ca_certs and not self.ca_cert_dir and default_ssl_context - and hasattr(context, 'load_default_certs')): - context.load_default_certs() - - self.sock = ssl_wrap_socket( - sock=conn, - keyfile=self.key_file, - certfile=self.cert_file, - key_password=self.key_password, - ssl_context=self.ssl_context, - server_hostname=self.server_hostname - ) - - -class VerifiedHTTPSConnection(HTTPSConnection): - """ - Based on httplib.HTTPSConnection but wraps the socket with - SSL certification. - """ - cert_reqs = None - ca_certs = None - ca_cert_dir = None - ssl_version = None - assert_fingerprint = None - - def set_cert(self, key_file=None, cert_file=None, - cert_reqs=None, key_password=None, ca_certs=None, - assert_hostname=None, assert_fingerprint=None, - ca_cert_dir=None): + def set_cert( + self, + key_file=None, + cert_file=None, + cert_reqs=None, + key_password=None, + ca_certs=None, + assert_hostname=None, + assert_fingerprint=None, + ca_cert_dir=None, + ca_cert_data=None, + ): """ This method should only be called once, before the connection is used. """ @@ -310,6 +301,7 @@ class VerifiedHTTPSConnection(HTTPSConnection): self.assert_fingerprint = assert_fingerprint self.ca_certs = ca_certs and os.path.expanduser(ca_certs) self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir) + self.ca_cert_data = ca_cert_data def connect(self): # Add certificate verification @@ -317,7 +309,7 @@ class VerifiedHTTPSConnection(HTTPSConnection): hostname = self.host # Google App Engine's httplib does not define _tunnel_host - if getattr(self, '_tunnel_host', None): + if getattr(self, "_tunnel_host", None): self.sock = conn # Calls self._set_hostport(), so self.host is # self._tunnel_host below. @@ -334,10 +326,12 @@ class VerifiedHTTPSConnection(HTTPSConnection): is_time_off = datetime.date.today() < RECENT_DATE if is_time_off: - warnings.warn(( - 'System time is way off (before {0}). This will probably ' - 'lead to SSL verification errors').format(RECENT_DATE), - SystemTimeWarning + warnings.warn( + ( + "System time is way off (before {0}). This will probably " + "lead to SSL verification errors" + ).format(RECENT_DATE), + SystemTimeWarning, ) # Wrap socket using verification with the root certs in @@ -355,8 +349,13 @@ class VerifiedHTTPSConnection(HTTPSConnection): # Try to load OS default certs if none are given. # Works well on Windows (requires Python3.4+) - if (not self.ca_certs and not self.ca_cert_dir and default_ssl_context - and hasattr(context, 'load_default_certs')): + if ( + not self.ca_certs + and not self.ca_cert_dir + and not self.ca_cert_data + and default_ssl_context + and hasattr(context, "load_default_certs") + ): context.load_default_certs() self.sock = ssl_wrap_socket( @@ -366,32 +365,39 @@ class VerifiedHTTPSConnection(HTTPSConnection): key_password=self.key_password, ca_certs=self.ca_certs, ca_cert_dir=self.ca_cert_dir, + ca_cert_data=self.ca_cert_data, server_hostname=server_hostname, - ssl_context=context) + ssl_context=context, + ) if self.assert_fingerprint: - assert_fingerprint(self.sock.getpeercert(binary_form=True), - self.assert_fingerprint) - elif context.verify_mode != ssl.CERT_NONE \ - and not getattr(context, 'check_hostname', False) \ - and self.assert_hostname is not False: + assert_fingerprint( + self.sock.getpeercert(binary_form=True), self.assert_fingerprint + ) + elif ( + context.verify_mode != ssl.CERT_NONE + and not getattr(context, "check_hostname", False) + and self.assert_hostname is not False + ): # While urllib3 attempts to always turn off hostname matching from # the TLS library, this cannot always be done. So we check whether # the TLS Library still thinks it's matching hostnames. cert = self.sock.getpeercert() - if not cert.get('subjectAltName', ()): - warnings.warn(( - 'Certificate for {0} has no `subjectAltName`, falling back to check for a ' - '`commonName` for now. This feature is being removed by major browsers and ' - 'deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 ' - 'for details.)'.format(hostname)), - SubjectAltNameWarning + if not cert.get("subjectAltName", ()): + warnings.warn( + ( + "Certificate for {0} has no `subjectAltName`, falling back to check for a " + "`commonName` for now. This feature is being removed by major browsers and " + "deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 " + "for details.)".format(hostname) + ), + SubjectAltNameWarning, ) _match_hostname(cert, self.assert_hostname or server_hostname) self.is_verified = ( - context.verify_mode == ssl.CERT_REQUIRED or - self.assert_fingerprint is not None + context.verify_mode == ssl.CERT_REQUIRED + or self.assert_fingerprint is not None ) @@ -399,9 +405,10 @@ def _match_hostname(cert, asserted_hostname): try: match_hostname(cert, asserted_hostname) except CertificateError as e: - log.error( - 'Certificate did not match expected hostname: %s. ' - 'Certificate: %s', asserted_hostname, cert + log.warning( + "Certificate did not match expected hostname: %s. Certificate: %s", + asserted_hostname, + cert, ) # Add cert to exception and reraise so client code can inspect # the cert when catching the exception, if they want to @@ -409,9 +416,8 @@ def _match_hostname(cert, asserted_hostname): raise -if ssl: - # Make a copy for testing. - UnverifiedHTTPSConnection = HTTPSConnection - HTTPSConnection = VerifiedHTTPSConnection -else: - HTTPSConnection = DummyConnection +if not ssl: + HTTPSConnection = DummyConnection # noqa: F811 + + +VerifiedHTTPSConnection = HTTPSConnection diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/connectionpool.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/connectionpool.py index 157568a..5f044db 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/connectionpool.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/connectionpool.py @@ -26,12 +26,14 @@ from .exceptions import ( from .packages.ssl_match_hostname import CertificateError from .packages import six from .packages.six.moves import queue -from .packages.rfc3986.normalizers import normalize_host from .connection import ( port_by_scheme, DummyConnection, - HTTPConnection, HTTPSConnection, VerifiedHTTPSConnection, - HTTPException, BaseSSLError, + HTTPConnection, + HTTPSConnection, + VerifiedHTTPSConnection, + HTTPException, + BaseSSLError, ) from .request import RequestMethods from .response import HTTPResponse @@ -41,7 +43,13 @@ from .util.request import set_file_position from .util.response import assert_header_parsing from .util.retry import Retry from .util.timeout import Timeout -from .util.url import get_host, Url, NORMALIZABLE_SCHEMES +from .util.url import ( + get_host, + parse_url, + Url, + _normalize_host as normalize_host, + _encode_target, +) from .util.queue import LifoQueue @@ -57,6 +65,11 @@ class ConnectionPool(object): """ Base class for all connection pools, such as :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`. + + .. note:: + ConnectionPool.urlopen() does not normalize or percent-encode target URIs + which is useful if your target server doesn't support percent-encoded + target URIs. """ scheme = None @@ -71,8 +84,7 @@ class ConnectionPool(object): self.port = port def __str__(self): - return '%s(host=%r, port=%r)' % (type(self).__name__, - self.host, self.port) + return "%s(host=%r, port=%r)" % (type(self).__name__, self.host, self.port) def __enter__(self): return self @@ -153,15 +165,24 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): :class:`urllib3.connection.HTTPSConnection` instances. """ - scheme = 'http' + scheme = "http" ConnectionCls = HTTPConnection ResponseCls = HTTPResponse - def __init__(self, host, port=None, strict=False, - timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, block=False, - headers=None, retries=None, - _proxy=None, _proxy_headers=None, - **conn_kw): + def __init__( + self, + host, + port=None, + strict=False, + timeout=Timeout.DEFAULT_TIMEOUT, + maxsize=1, + block=False, + headers=None, + retries=None, + _proxy=None, + _proxy_headers=None, + **conn_kw + ): ConnectionPool.__init__(self, host, port) RequestMethods.__init__(self, headers) @@ -195,19 +216,27 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # Enable Nagle's algorithm for proxies, to avoid packet fragmentation. # We cannot know if the user has added default socket options, so we cannot replace the # list. - self.conn_kw.setdefault('socket_options', []) + self.conn_kw.setdefault("socket_options", []) def _new_conn(self): """ Return a fresh :class:`HTTPConnection`. """ self.num_connections += 1 - log.debug("Starting new HTTP connection (%d): %s:%s", - self.num_connections, self.host, self.port or "80") + log.debug( + "Starting new HTTP connection (%d): %s:%s", + self.num_connections, + self.host, + self.port or "80", + ) - conn = self.ConnectionCls(host=self.host, port=self.port, - timeout=self.timeout.connect_timeout, - strict=self.strict, **self.conn_kw) + conn = self.ConnectionCls( + host=self.host, + port=self.port, + timeout=self.timeout.connect_timeout, + strict=self.strict, + **self.conn_kw + ) return conn def _get_conn(self, timeout=None): @@ -231,16 +260,17 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): except queue.Empty: if self.block: - raise EmptyPoolError(self, - "Pool reached maximum size and no more " - "connections are allowed.") + raise EmptyPoolError( + self, + "Pool reached maximum size and no more connections are allowed.", + ) pass # Oh well, we'll create a new connection then # If this is a persistent connection, check if it got disconnected if conn and is_connection_dropped(conn): log.debug("Resetting dropped connection: %s", self.host) conn.close() - if getattr(conn, 'auto_open', 1) == 0: + if getattr(conn, "auto_open", 1) == 0: # This is a proxied connection that has been mutated by # httplib._tunnel() and cannot be reused (since it would # attempt to bypass the proxy) @@ -270,9 +300,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): pass except queue.Full: # This should never happen if self.block == True - log.warning( - "Connection pool is full, discarding connection: %s", - self.host) + log.warning("Connection pool is full, discarding connection: %s", self.host) # Connection never got put back into the pool, close it. if conn: @@ -304,21 +332,30 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): """Is the error actually a timeout? Will raise a ReadTimeout or pass""" if isinstance(err, SocketTimeout): - raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + raise ReadTimeoutError( + self, url, "Read timed out. (read timeout=%s)" % timeout_value + ) # See the above comment about EAGAIN in Python 3. In Python 2 we have # to specifically catch it and throw the timeout error - if hasattr(err, 'errno') and err.errno in _blocking_errnos: - raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + if hasattr(err, "errno") and err.errno in _blocking_errnos: + raise ReadTimeoutError( + self, url, "Read timed out. (read timeout=%s)" % timeout_value + ) # Catch possible read timeouts thrown as SSL errors. If not the # case, rethrow the original. We need to do this because of: # http://bugs.python.org/issue10272 - if 'timed out' in str(err) or 'did not complete (read)' in str(err): # Python < 2.7.4 - raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + if "timed out" in str(err) or "did not complete (read)" in str( + err + ): # Python < 2.7.4 + raise ReadTimeoutError( + self, url, "Read timed out. (read timeout=%s)" % timeout_value + ) - def _make_request(self, conn, method, url, timeout=_Default, chunked=False, - **httplib_request_kw): + def _make_request( + self, conn, method, url, timeout=_Default, chunked=False, **httplib_request_kw + ): """ Perform a request on a given urllib connection object taken from our pool. @@ -358,7 +395,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): read_timeout = timeout_obj.read_timeout # App Engine doesn't have a sock attr - if getattr(conn, 'sock', None): + if getattr(conn, "sock", None): # In Python 3 socket.py will catch EAGAIN and return None when you # try and read into the file pointer created by http.client, which # instead raises a BadStatusLine exception. Instead of catching @@ -366,7 +403,8 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # timeouts, check for a zero timeout before making the request. if read_timeout == 0: raise ReadTimeoutError( - self, url, "Read timed out. (read timeout=%s)" % read_timeout) + self, url, "Read timed out. (read timeout=%s)" % read_timeout + ) if read_timeout is Timeout.DEFAULT_TIMEOUT: conn.sock.settimeout(socket.getdefaulttimeout()) else: # None or a value @@ -381,26 +419,38 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # Python 3 try: httplib_response = conn.getresponse() - except Exception as e: - # Remove the TypeError from the exception chain in Python 3; - # otherwise it looks like a programming error was the cause. + except BaseException as e: + # Remove the TypeError from the exception chain in + # Python 3 (including for exceptions like SystemExit). + # Otherwise it looks like a bug in the code. six.raise_from(e, None) except (SocketTimeout, BaseSSLError, SocketError) as e: self._raise_timeout(err=e, url=url, timeout_value=read_timeout) raise # AppEngine doesn't have a version attr. - http_version = getattr(conn, '_http_vsn_str', 'HTTP/?') - log.debug("%s://%s:%s \"%s %s %s\" %s %s", self.scheme, self.host, self.port, - method, url, http_version, httplib_response.status, - httplib_response.length) + http_version = getattr(conn, "_http_vsn_str", "HTTP/?") + log.debug( + '%s://%s:%s "%s %s %s" %s %s', + self.scheme, + self.host, + self.port, + method, + url, + http_version, + httplib_response.status, + httplib_response.length, + ) try: assert_header_parsing(httplib_response.msg) except (HeaderParsingError, TypeError) as hpe: # Platform-specific: Python 3 log.warning( - 'Failed to parse headers (url=%s): %s', - self._absolute_url(url), hpe, exc_info=True) + "Failed to parse headers (url=%s): %s", + self._absolute_url(url), + hpe, + exc_info=True, + ) return httplib_response @@ -430,7 +480,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): Check if the given ``url`` is a member of the same host as this connection pool. """ - if url.startswith('/'): + if url.startswith("/"): return True # TODO: Add optional support for socket.gethostbyname checking. @@ -446,10 +496,22 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): return (scheme, host, port) == (self.scheme, self.host, self.port) - def urlopen(self, method, url, body=None, headers=None, retries=None, - redirect=True, assert_same_host=True, timeout=_Default, - pool_timeout=None, release_conn=None, chunked=False, - body_pos=None, **response_kw): + def urlopen( + self, + method, + url, + body=None, + headers=None, + retries=None, + redirect=True, + assert_same_host=True, + timeout=_Default, + pool_timeout=None, + release_conn=None, + chunked=False, + body_pos=None, + **response_kw + ): """ Get a connection from the pool and perform an HTTP request. This is the lowest level call for making a request, so you'll need to specify all @@ -547,12 +609,18 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if release_conn is None: - release_conn = response_kw.get('preload_content', True) + release_conn = response_kw.get("preload_content", True) # Check host if assert_same_host and not self.is_same_host(url): raise HostChangedError(self, url, retries) + # Ensure that the URL we're connecting to is properly encoded + if url.startswith("/"): + url = six.ensure_str(_encode_target(url)) + else: + url = six.ensure_str(parse_url(url).url) + conn = None # Track whether `conn` needs to be released before @@ -563,13 +631,13 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # # See issue #651 [1] for details. # - # [1] <https://github.com/shazow/urllib3/issues/651> + # [1] <https://github.com/urllib3/urllib3/issues/651> release_this_conn = release_conn # Merge the proxy headers. Only do this in HTTP. We have to copy the # headers dict so we can safely change it without those changes being # reflected in anyone else's copy. - if self.scheme == 'http': + if self.scheme == "http": headers = headers.copy() headers.update(self.proxy_headers) @@ -592,15 +660,22 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): conn.timeout = timeout_obj.connect_timeout - is_new_proxy_conn = self.proxy is not None and not getattr(conn, 'sock', None) + is_new_proxy_conn = self.proxy is not None and not getattr( + conn, "sock", None + ) if is_new_proxy_conn: self._prepare_proxy(conn) # Make the request on the httplib connection object. - httplib_response = self._make_request(conn, method, url, - timeout=timeout_obj, - body=body, headers=headers, - chunked=chunked) + httplib_response = self._make_request( + conn, + method, + url, + timeout=timeout_obj, + body=body, + headers=headers, + chunked=chunked, + ) # If we're going to release the connection in ``finally:``, then # the response doesn't need to know about the connection. Otherwise @@ -609,14 +684,16 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): response_conn = conn if not release_conn else None # Pass method to Response for length checking - response_kw['request_method'] = method + response_kw["request_method"] = method # Import httplib's response into our own wrapper object - response = self.ResponseCls.from_httplib(httplib_response, - pool=self, - connection=response_conn, - retries=retries, - **response_kw) + response = self.ResponseCls.from_httplib( + httplib_response, + pool=self, + connection=response_conn, + retries=retries, + **response_kw + ) # Everything went great! clean_exit = True @@ -625,20 +702,28 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): # Timed out by queue. raise EmptyPoolError(self, "No pool connections are available.") - except (TimeoutError, HTTPException, SocketError, ProtocolError, - BaseSSLError, SSLError, CertificateError) as e: + except ( + TimeoutError, + HTTPException, + SocketError, + ProtocolError, + BaseSSLError, + SSLError, + CertificateError, + ) as e: # Discard the connection for these exceptions. It will be # replaced during the next _get_conn() call. clean_exit = False if isinstance(e, (BaseSSLError, CertificateError)): e = SSLError(e) elif isinstance(e, (SocketError, NewConnectionError)) and self.proxy: - e = ProxyError('Cannot connect to proxy.', e) + e = ProxyError("Cannot connect to proxy.", e) elif isinstance(e, (SocketError, HTTPException)): - e = ProtocolError('Connection aborted.', e) + e = ProtocolError("Connection aborted.", e) - retries = retries.increment(method, url, error=e, _pool=self, - _stacktrace=sys.exc_info()[2]) + retries = retries.increment( + method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2] + ) retries.sleep() # Keep track of the error for the retry warning. @@ -661,77 +746,87 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): if not conn: # Try again - log.warning("Retrying (%r) after connection " - "broken by '%r': %s", retries, err, url) - return self.urlopen(method, url, body, headers, retries, - redirect, assert_same_host, - timeout=timeout, pool_timeout=pool_timeout, - release_conn=release_conn, body_pos=body_pos, - **response_kw) - - def drain_and_release_conn(response): - try: - # discard any remaining response body, the connection will be - # released back to the pool once the entire response is read - response.read() - except (TimeoutError, HTTPException, SocketError, ProtocolError, - BaseSSLError, SSLError): - pass + log.warning( + "Retrying (%r) after connection broken by '%r': %s", retries, err, url + ) + return self.urlopen( + method, + url, + body, + headers, + retries, + redirect, + assert_same_host, + timeout=timeout, + pool_timeout=pool_timeout, + release_conn=release_conn, + chunked=chunked, + body_pos=body_pos, + **response_kw + ) # Handle redirect? redirect_location = redirect and response.get_redirect_location() if redirect_location: if response.status == 303: - method = 'GET' + method = "GET" try: retries = retries.increment(method, url, response=response, _pool=self) except MaxRetryError: if retries.raise_on_redirect: - # Drain and release the connection for this response, since - # we're not returning it to be released manually. - drain_and_release_conn(response) + response.drain_conn() raise return response - # drain and return the connection to the pool before recursing - drain_and_release_conn(response) - + response.drain_conn() retries.sleep_for_retry(response) log.debug("Redirecting %s -> %s", url, redirect_location) return self.urlopen( - method, redirect_location, body, headers, - retries=retries, redirect=redirect, + method, + redirect_location, + body, + headers, + retries=retries, + redirect=redirect, assert_same_host=assert_same_host, - timeout=timeout, pool_timeout=pool_timeout, - release_conn=release_conn, body_pos=body_pos, - **response_kw) + timeout=timeout, + pool_timeout=pool_timeout, + release_conn=release_conn, + chunked=chunked, + body_pos=body_pos, + **response_kw + ) # Check if we should retry the HTTP response. - has_retry_after = bool(response.getheader('Retry-After')) + has_retry_after = bool(response.getheader("Retry-After")) if retries.is_retry(method, response.status, has_retry_after): try: retries = retries.increment(method, url, response=response, _pool=self) except MaxRetryError: if retries.raise_on_status: - # Drain and release the connection for this response, since - # we're not returning it to be released manually. - drain_and_release_conn(response) + response.drain_conn() raise return response - # drain and return the connection to the pool before recursing - drain_and_release_conn(response) - + response.drain_conn() retries.sleep(response) log.debug("Retry: %s", url) return self.urlopen( - method, url, body, headers, - retries=retries, redirect=redirect, + method, + url, + body, + headers, + retries=retries, + redirect=redirect, assert_same_host=assert_same_host, - timeout=timeout, pool_timeout=pool_timeout, + timeout=timeout, + pool_timeout=pool_timeout, release_conn=release_conn, - body_pos=body_pos, **response_kw) + chunked=chunked, + body_pos=body_pos, + **response_kw + ) return response @@ -754,21 +849,47 @@ class HTTPSConnectionPool(HTTPConnectionPool): the connection socket into an SSL socket. """ - scheme = 'https' + scheme = "https" ConnectionCls = HTTPSConnection - def __init__(self, host, port=None, - strict=False, timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, - block=False, headers=None, retries=None, - _proxy=None, _proxy_headers=None, - key_file=None, cert_file=None, cert_reqs=None, - key_password=None, ca_certs=None, ssl_version=None, - assert_hostname=None, assert_fingerprint=None, - ca_cert_dir=None, **conn_kw): + def __init__( + self, + host, + port=None, + strict=False, + timeout=Timeout.DEFAULT_TIMEOUT, + maxsize=1, + block=False, + headers=None, + retries=None, + _proxy=None, + _proxy_headers=None, + key_file=None, + cert_file=None, + cert_reqs=None, + key_password=None, + ca_certs=None, + ssl_version=None, + assert_hostname=None, + assert_fingerprint=None, + ca_cert_dir=None, + **conn_kw + ): - HTTPConnectionPool.__init__(self, host, port, strict, timeout, maxsize, - block, headers, retries, _proxy, _proxy_headers, - **conn_kw) + HTTPConnectionPool.__init__( + self, + host, + port, + strict, + timeout, + maxsize, + block, + headers, + retries, + _proxy, + _proxy_headers, + **conn_kw + ) self.key_file = key_file self.cert_file = cert_file @@ -787,14 +908,16 @@ class HTTPSConnectionPool(HTTPConnectionPool): """ if isinstance(conn, VerifiedHTTPSConnection): - conn.set_cert(key_file=self.key_file, - key_password=self.key_password, - cert_file=self.cert_file, - cert_reqs=self.cert_reqs, - ca_certs=self.ca_certs, - ca_cert_dir=self.ca_cert_dir, - assert_hostname=self.assert_hostname, - assert_fingerprint=self.assert_fingerprint) + conn.set_cert( + key_file=self.key_file, + key_password=self.key_password, + cert_file=self.cert_file, + cert_reqs=self.cert_reqs, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + assert_hostname=self.assert_hostname, + assert_fingerprint=self.assert_fingerprint, + ) conn.ssl_version = self.ssl_version return conn @@ -811,12 +934,17 @@ class HTTPSConnectionPool(HTTPConnectionPool): Return a fresh :class:`httplib.HTTPSConnection`. """ self.num_connections += 1 - log.debug("Starting new HTTPS connection (%d): %s:%s", - self.num_connections, self.host, self.port or "443") + log.debug( + "Starting new HTTPS connection (%d): %s:%s", + self.num_connections, + self.host, + self.port or "443", + ) if not self.ConnectionCls or self.ConnectionCls is DummyConnection: - raise SSLError("Can't connect to HTTPS URL because the SSL " - "module is not available.") + raise SSLError( + "Can't connect to HTTPS URL because the SSL module is not available." + ) actual_host = self.host actual_port = self.port @@ -824,11 +952,16 @@ class HTTPSConnectionPool(HTTPConnectionPool): actual_host = self.proxy.host actual_port = self.proxy.port - conn = self.ConnectionCls(host=actual_host, port=actual_port, - timeout=self.timeout.connect_timeout, - strict=self.strict, cert_file=self.cert_file, - key_file=self.key_file, key_password=self.key_password, - **self.conn_kw) + conn = self.ConnectionCls( + host=actual_host, + port=actual_port, + timeout=self.timeout.connect_timeout, + strict=self.strict, + cert_file=self.cert_file, + key_file=self.key_file, + key_password=self.key_password, + **self.conn_kw + ) return self._prepare_conn(conn) @@ -839,16 +972,19 @@ class HTTPSConnectionPool(HTTPConnectionPool): super(HTTPSConnectionPool, self)._validate_conn(conn) # Force connect early to allow us to validate the connection. - if not getattr(conn, 'sock', None): # AppEngine might not have `.sock` + if not getattr(conn, "sock", None): # AppEngine might not have `.sock` conn.connect() if not conn.is_verified: - warnings.warn(( - 'Unverified HTTPS request is being made. ' - 'Adding certificate verification is strongly advised. See: ' - 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' - '#ssl-warnings'), - InsecureRequestWarning) + warnings.warn( + ( + "Unverified HTTPS request is being made to host '%s'. " + "Adding certificate verification is strongly advised. See: " + "https://urllib3.readthedocs.io/en/latest/advanced-usage.html" + "#ssl-warnings" % conn.host + ), + InsecureRequestWarning, + ) def connection_from_url(url, **kw): @@ -873,7 +1009,7 @@ def connection_from_url(url, **kw): """ scheme, host, port = get_host(url) port = port or port_by_scheme.get(scheme, 80) - if scheme == 'https': + if scheme == "https": return HTTPSConnectionPool(host, port=port, **kw) else: return HTTPConnectionPool(host, port=port, **kw) @@ -884,14 +1020,14 @@ def _normalize_host(host, scheme): Normalize hosts for comparisons and use with sockets. """ + host = normalize_host(host, scheme) + # httplib doesn't like it when we include brackets in IPv6 addresses # Specifically, if we include brackets but also pass the port then # httplib crazily doubles up the square brackets on the Host header. # Instead, we need to make sure we never pass ``None`` as the port. # However, for backward compatibility reasons we can't actually # *assert* that. See http://bugs.python.org/issue28539 - if host.startswith('[') and host.endswith(']'): - host = host.strip('[]') - if scheme in NORMALIZABLE_SCHEMES: - host = normalize_host(host) + if host.startswith("[") and host.endswith("]"): + host = host[1:-1] return host diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-38.pyc index 3aaa3147fd982990f81a3a934231e2f9f6e6b49d..4bfd88653698468905a6523131d98bed48f77b2c 100644 GIT binary patch delta 91 zcmZ3$c$ASRl$V!_0SGkz?TVksW9^)!pOK%Ns$W!DTAG!qUtE-|pOToDnVOTFUsRG> ttXEN4rC*ksSEiqnnWSG(S(1^TXRK$TUz}Nzs#}nloSm4ST0Ak;8US3(AKU-{ delta 54 zcmX@gxPXx-l$V!_0SKO#ZHSx5V=d>ZUy@s(Uyxa#o0(T!l9-dDYm{M9T49`@2ojvw GWeotYoe^jN diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-38.pyc index 905d3071f3d27bb38bc84e4465d840a7f2295503..f205bc2cd6011a490493d59cfb51aeaf611686e8 100644 GIT binary patch literal 1421 zcmb_cPj3`A6!&;GyTc@DNraFpp~`9x)k<_Ml>-PN)U+&!L$_!XS}B*&Wc;$@WY!+p zo`u~j{UC7UD^%i(%#{;gfdlQcHzX^z$6E5gvFE+t`~BYY^WEK)U>kn=JAW4w^4@RO z8^z7f*zG+W1UV)m610wvBN2<<U*wpIEz!q076Xys+!NPCiu0D(7CSii1wACg-Q_Ro zQ6(*#Y0=ie8l&e@0PdksmO0G?I4B)+6|jS*VIwt_3K*!lG+NC-xh(yF2*|kf<9ds5 z^DB0{gM%ZlNRztg6+y4jcu2c_Y4ci_MV%K-1Ho*!hu;u_xcc;#m>&KfhL4U{dIsDq z+V)IxYf3H(C7~|0abUBTizS~UGG5CQ-Yi_D)t&4fx6;9nO;Mf~Q?R^|4bSnG(1y3B z#;bRDsg*PM&z0N!BEYO!bUO&@5@O;5^4yci^l{vX+Mk7}Z{Wg5t@mAYMn&`u5%k=1 z9v9yuH4|tMwPo@&aElHY%3xZhq?$6R!q-!2tYcG9U<xO-VzyA?M8C|^lwmtUQ7j;O zv3>__I5|TN3j++rtCU2R>jkq;*0ncXe719&owSZg7p(a#Xv>P#U=avdq@;9m4!4=r z7xulCg>IRxbXyDcgJTLn_%taiD9_ocHfSvi<}3iKoNMfT&dXZ2BAaSGtsyJ*j9>D} zg)S|(4&y3};GeMv3*FwqvuC66lc(cRK6ySqdivX_OIEu6baxmB{yVB|H@HyiDpgji zEtH_Uu`XYJL7-2`m5c+kjq42=ebNOPzr}@!965{5`}&rjUsFLv{D!{9LVFXTpj%@z zz+2tdhoi|Kqe*`F`{ScO4<@6IEO#Ek9BSS8Lg8<F<{I8JzOcJ^3a(2ra7=<1(pCS3 z-S}j>i9M7MiLOVK(0_WAehMf52WaD&FuOP`_n!oP*2<ilul(s{0ba3cVm!EoeG{2K z*+6#r7I<62lSY@@kDxJ777j%A_)90jXVCBF#+#7O<}>@9cOD9nnmt?(2i+jgF`M#y n#j>x?pl#qP01g+w^c0*V4^|K0Lk~2>)axa2(o52$pY;C)eEeF6 literal 1088 zcmZ`&K~LK-6t<l-4JF+Mn%H(2%C!fGG<Miwn$~Th;y^)dVG@T~rM5~SjU&gc7+3Z~ zwj;Owk^O;OcbN7Uc7VO-R!|9Q$?w^p6Tk0$@A;r!uMrr3CO^OYVubw0&HMn2yoXu5 z0VBu}5md009#P>4_ZvB4q9Q!-j;IPByepPO4SYo`ivYYQSeG>F7awZ9lcWeoN{mw( z=2}e>Az?53SrHl)3TfoPgyuws%{&j|Y?x#+l-VTFDjUhnY}Wn)1JWL#ogWl7A7K`& zU<|n=`4dB}WtXH&u4udAl&eX>Q#I(Pyr1XNUS6&M21LXhv~~~TqsgeaBHDw?t@*bX znNc3)NxqR}h3Tj1#;cRp<MS=mN6=0_k(p3B8tXJoj<=$L%8X8qqq|6amf2?hwG1HW zEh`^0u_d7%b#EARuQg(e(|$BdTLqYQ04ZxMT7%jDbOqLT?5C?LVCB>Ku)OGJ;#i&I zWd;6Ds9pklFRTNgRr@(C1U2N8o_T6bFkA`e1v&Ge-fp{GY3}dG?bc2^=ADCfZ)Z2Y z2tLV)OjVBMjLOH|xN{hHcz18R_qo}L8?0oiD62DN9^$MqI+nS>au8ah!HvZh(+uIe zTbk?hG}XF+20^`mu13i(R$EF9p*`<9Fw)C#&~S7BPS?>a5>&fz`V8i*d`ONl@7m(` z2;#?9$7$D|((epk)(<9}Gkh_ipx0`~{BU=>bd4U%c@CvBl;%N!klah;FsmW%8`ZMP pxljYnr)gk6+3H&DEWd?WmHyl5n|+7xtUwuD*LQr+cm0a*{RdHp-nak& diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-38.pyc index 5c7cf287f0edb12039c261e8e9bc31037ec7bc39..658d573d67c3ae287da71723c8fb1b8fdcdff35c 100644 GIT binary patch delta 1048 zcmZ8f&2JJx6yG=d!LlrrB2a-AifyV`?b=#XjYg{`n)sC(t0qRXLD*7S3eD`c7K3Rb z9=%Px>z`man0WB!RpXWT2lQa#NmHX1-vht*Wq$kK%$qlFe!qEl`ps<UdN626_~mw9 z+R5?fp)LLFvb9)SaV%b6TU#nyE-zTce6{RU3N`LI?!-p@zP0XD*R4wVuC-eC7HieR z6Gtt#>^TQl^M&Pn$#Gjze@Qtvi*-H8H9aUo6CQ%cp2|h$DbE;4p88a4NDUyrAvYx3 z*H94k23tMq`Iijz14ZeYl#|8V;FNe2dL1x%KNjQ(1X1Z*3uGxu6J$g-wJS4(ZUKk8 z8$t3Zz<_lW1^+Vpruf8I_)2CEuJD21K$&g7Z97%Z;kMlnB0LX!#8!9)He18}XJi-= zh3F)t#gph~$co3Y%ZTmROn8K9bUT<NZ%Sn2(FD0|)vI~=O1Iaxy5M+)MeOfNJO%02 zQv3oO@3yd?GUYX1;fHDa|J7(Uz#VtBR&^bF`5qsqEK7VGxVd>6-6jtA6@p}%j6oE- zm&FTfICL~++cY9D$Rc184UBzP)ZHwKQ3&YYn~Q4EpOGf9PMoOf&>-S8H3S+9Lx`E6 z;2AhCkzHaPLk{B+CK$}Xa>nn&**B)*R$yNgoo#Do2qI{h*UQ*J9ccAWMxd2Q3__MD zXv-^ZsmH?!40Fm~#GDW}k_S+UW^z78?A;0?ab0F@;)tIYACl8BM~^@~hU=eN$5J(j zrO@Sr1QCKG2stKBrjzOnx(V@qFrlg%+#eI0>9`0FahMd%p?d5NWrq;j`U0=5*yXCn zv!Xw}E8CU&-?BNGcLnV|1!`ev8n=!C3KT|1!rMns2BeQf(8PoE>;%13K1#5UAV_eV zfVAaw1x_t;s>BDVsMtySEjkFLjY-h8uSP<bb^RBo%C^DvQ9a0$n3mhii{elw)^`Jg qwy#nvmCDr;Pl@@=U9iN9Oa)Gf(cz15Rb1^$iH+eo|DuMkhwKLy1k2+9 delta 1225 zcmZuwO>7%Q6y7&G-mEwF#x!=~q;|YbQdNeOmL#S8RZ5YFD3BCN((>DtV{e>=^{zEL zE>u`lwBm+1FgGr=2kun9_0R(cBrYIMNGpNF1<I*6P6_6{b&-mMt@-A?H{Z;g_s!cM z)_yu`Z|C!thQB|qd~^BEqqpsQ=G^)T+3B9>`rYGx7|TWw9ADmB?R~fsH7GcEI@{)3 zo47@4aZW-DZoqYr?1m<0(POEn-{dV_W^OUiq;Yesul0fKzTVedv(FK;eb!x<)_db< z=UUq9TAi!k^UK#h*^WIYj6|mqI6V;r{?5wduSQX@(FhxDPdIcXuhDX%UFU4K`$E|E zL+`;_6gnfT<y_o|mz+lI^kP43JKGmtS@&df&+%hCS~{WE^y0W7uHtEq+{36BUhzc~ zc05(Izc=&Z5iC#4sHApS-Lre+^W@eD9Cf=od29~NCXU!a&=>~>Y{+$EG-uG)**-Va zmlK<?p#Gew!bfVXu!Z(Jh11r@w3E?J_0`1GU{F}lVNv}&`2^Hdw)hv!e^J_id9_(O z{pKQ)M4Ek>tQCa%e3En9o^*vLh400JR+5a2@TJmwCz)L;RyY(drPRhw90fh;xzg`= zQBR86;MdYi@azIo#AC$MQERbE?*F7r#)TJmqcHZ|_dgIz#5$>()0e8xqj?=i{2hYE zbBv)D<`D6KarNVL?HaJZxn5>P$bk(sqf!_v^5O%}(AaQFN5zITNJoR)V6Xz%EC-x1 zn1TYBxZh$Ho?!v<wDga8a0Yh3b#`DFHXM3r&A{CjlvDD*L?Z8V&h`ys@M*aMN2uUL z@5Jp<)o0MH^M_<OqrRP4!ne6UvsEIk-pZp)sk*3s+!ZgXH)dDiHR_4XGr0cC;Op54 zDit(EmEaJ;lL&PtQn6QvTYCy40H|9L4K1z7f+F3XVKrRsR6c`cb-!};++|!BHbP?V zim2oIp-lTB8EZx%_OVR3z|SFV0`cFxb$yg_)IOB==qWrXPkGB|jPjC_d}!#Yc9cD% zeygt4sl&xlf;vH-;9UZGazV8UDngu6ceCY-vuK{j5z`G!;FB6?L#u4+CLg^PA6jpl zi)Ky`vwlo?I3<?r?)GF)c&;lL2E-+bjs;O0KkBxqsJnAJa8ezq1+b<*uf1$sAktyX PIIXhIbJ_C-jQ;-s(-RNI diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-38.pyc index bc422ce4e0cb996a084d905429a555fa827bec82..cef79f69ee595cbb238aa82d8d85128b4a7a2fc0 100644 GIT binary patch delta 284 zcmbO&c}|iql$V!_0SGkz?TU90*vR*u**Qx;BR@A)zo@dbG%HiTxF}gaB{45EH77a0 zs3f&mucER_zbrMcOg|?xNxz`7BqKl1SkFSgII|>Gw;(Y&J25@Ac(XLiZq~d!kipD+ zj4X^yKn#R`SlBs0G?M@`8zakqE@mD^Aw~{H5DCOAY+$t<i~@{&j9frHeE(TkfqMUQ zFat>j7BFP`&jQp1(I><x!YBb`^8n2dVVdl~^-(zsXk)Pi$X+gxO&lO|7?9xqDyhkd gEW(o$xmzVffU1CsSXh{N_&D4d7@_dT<X_wi0h&fMx&QzG delta 204 zcmX>nIa`u1l$V!_0SKO#ZHUVj+{pKyS<Y3zB)34nAhSR>Gq1QLF(*gYD8r<*!Z<$> zB)HjuWjCu_7Dx{>A0rzh3j+}TXJO`GWMO1s5@6x`&&D)amP^Kfg^}w&8!HEp3seM# zOn+Edc^G*Zg%~-2ScFjm$mU_>U;?XTo}9_`Q92!HY_Sl?a3+v}9E<{tObkqnK=^lZ dHTNtL0iX;}f`x^NhmXU7ff304KUtS&AppxAB`p8| diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-38.pyc index 106654a21d0d3eaca197939cf749075aa9a2d90f..15cd4518d1f7e777a28a55ccc38cfec2c66d2aab 100644 GIT binary patch delta 1020 zcmXX_Uu+ab7@u!;ZaTMncU_yK|EOgtw&e=#mbSK~m8T{=ks6{#Bu&b)xAgXU-ZgW3 z4Q<W{k_az~W`c>v0F}_1C<$aSG5BJ9@PR<05nk}myFM5+CPsoiziHjg_xry2zTeDm zcIMj$(b?tnE9taJ@X2l7ng8}y`bu(U(JfS74_vuYs})1HDt$NamBXOqS7a1ahfc4o zy30X%*)4@9-KCYNP$`cNO}f=E3I>-vf6-eAs_JfX2qxlxlE=VWz{RT!fsuI5s<GXz zT8^iv4HRgDHKizr?O5){iVv!Je|t>r1qQJyX4kFjn60+xS($j}j`OtniB50?PAP~@ zb*t^&bVKL1WPp<RNP7s=-|5r{0!f%)vJ|6`1)B=gW!v^NBQP@PQ^q@!oZ6dQGaG`% zk2@R+Y4uFkS;(r-_jalqU6-Ieo_ThiLU;Vzu67C&%ILWUv++jHivUN}-+O-DF$bua z(u$~%Ld!Imq5gPILSE&2e}F<f**6OvQq$}$nn@Wjv=+k#zNt3)&%+tz?ybW)RDBQL zR)=!e_HfPbM!o>X%_hMF7agKa7{U?)N2Zxk#=s@G7=Ji0N?}di-+vl5)ZxJo;4}5} z;QMe>Rfg_ZxAihq%ThJn)u~=~kHVK~-Ccp4a)wLrm3n7*DwDvv?uZ$*>IL<1xc~6# zK%ErfDy>7Eu2CR$BTp8S^2l~JGU~=TSOXxhlJXcM5i2H&e9@F|0eOP~S#61$u8KTW zXS&;_=rNKfFOi%vD-WT-YJaWloh$`TRB=ibFYiRMR*izZ;|DSdPldjREjQ)#%3M+n z9_SmBAx@G-4UvYLhGm3YLe8Ok#C`8nSPHaX@}h$F>fWvn=MyY`t-n8u0RaK#mQl!{ z&*B|_eBe*`UR@kH0hiU|k=J@ZMVi#-AU8Bv2#=ce7U%WW=KX>fmhZ*oQ6H?!nxOkr zUQs`d{b)VVIu4GBP~SX%!CuoPy#aYc!x!r2!L~8kgYie2*@uC?Sivcn2E$JM-y3+r z2{UC{1h(EM>iYO3+*ZGgzW{&5J16eaB=)}z8QRL!?+2&%5e~dT|7E<@VE9uB!!$%1 Ud!$qB6XW)q1Qk*oD~5giKP`gl5dZ)H delta 805 zcmX|9T}V_>5WaKn+1uH3ch{@<*S3i+y6UF;<8B&ey+|Pi25F!VM)q%6ZtE&43nD=l zK@@`;^rIz7LX>eyqNnO1vL_*5B8VP>=t+9$=fT|OY~j7kH*;scJKtf>j18`&+=tw5 zsnPRwaN%(KQ}?v9WN$ciE)h=jBx-xk_ouphdu!`X#|MUDecdXFtIiPA+a<CC%oFrq zKPTW|kC_8J&!ajSF0ep2Twsv5E$b48M>v%~XHF}6o}#$zmV$AX^Iatj0s|O`41OxQ zmh(g9vOO8gjFjW&BA-1~ydQQgsX`rr=8zz{i!&178L3-LfB>$sjE8ezI$Pt0*Gb|T zgG(mYg(KOH%fWm*=9LUM?)Hs=i7$OmAjeK@onug77nK$>2w}uO3w!Jp{{es&EHD3- z+Xkd5lqPU+K_Q^OA_<*1QSlzS?4Cd?l$}zP;w(in4xG%Om#uTdlVQ5ChRc=XFpM2l zX-Jc*7gwtWVH8hR&$2%nnnCX-LvSHw9@YdWVBCHkj4_zRpEW~p8~bV}VFr!R4S0Yz zLoagYHx9)9sbE+5EG*zsco^ofInoO@E<_qV*#Xj_n#uZG@pq&W%c2FoeQE6s%&?T6 z)-S?60PVQerX}wZshZ<rG{DIHik8%<jYwv}RM9NKbETZUUmCW|nul;CfYEp%9<BQT zZ?GwL1g7y$tkay|Xz&mrz8PNGTjIwcy8%hH0m&J>vi+mEq?(q}x29uX{blREDk-(( zV+D(N!Cf5lQ+Qnw0~F9jJA}bN>YSF~zc+*~9MUO;Ml`Z@JlL=Up5fJoCir5%ZFt9= uv|tu^SfP%$8h3635ABEmBO@G~1}Su@3%4*uz6grAHL6JiT%0Pp)&3WsRjxb$ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-38.pyc index cd9b92cff84b0a6eb91c84c22809962a1e53407a..09fb526efb266c25ff88f6a9296e1a4edbc0ae1b 100644 GIT binary patch delta 2155 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 b?Po^AwDD;(Td}HI;XI?K!r*q$3L4t?m(2v* delta 2186 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 F+V3$B1pNR2 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-38.pyc index 7275b68d983a0756488623220539c61f2240d4a2..e4e94eb55c3def105be977c0a81619207dec0a73 100644 GIT binary patch delta 283 zcmZ3beO8+{l$V!_0SGkz?TWA2$lJx~oUWgdpPQ;*R9RY@m8oA`l&qhUn3tKFlbl~v zl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2(-keHmEn4VfZc`K(Dqu1sKob#9& z{U+D*nsPESF>?K9`p3aGc`vWHI0M^%HWnsECLk@sA_SBJvBX#=zvitGbOk!5m<>p9 zFtV`luoUr6?&X)AJe4n)v3K%IzUhn;CpYr<F;3kqAkfat<^pm$=j6G<N=!UVlaC7b zNY4am7lLSK0~-8~je~&^41aCT5|L(9WnyAs`o+S*!6d*WzzBjoj66(CK$4G<i&?-! Ih(!Ph0U(V;x&QzG delta 270 zcmX@By-J%ml$V!_0SKO#ZHP<R$lJv!=cHefTcBT%S)iMlS6q^qlcQ^tVNzOQoSz61 zoP3K@i_vE@E7v?`#(>F7cumb2m>9YKGyUga5n*OyWMkxFWCBB=*grNl5S#5E8!Lns zVHE<&F|hp?W1cL)S0m^Fw7HlKNN_N+F!Qh!@lSRX5SgsU&pCM)Uod0eWIq1sjFToW z<L_gfw%JsmotX`!fq`lAAz>w;(QN-&SSCLc?vb1YGDZMm49F^=g$#^9?*GlbBGQbi lj7%&{zggHhm;{&vn1PUyhmnVg2}trWaxn|I39$$OApkQ1Hy{82 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py index f3e0094..8765b90 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py @@ -6,25 +6,31 @@ import os def is_appengine(): - return (is_local_appengine() or - is_prod_appengine() or - is_prod_appengine_mvms()) + return is_local_appengine() or is_prod_appengine() def is_appengine_sandbox(): - return is_appengine() and not is_prod_appengine_mvms() + """Reports if the app is running in the first generation sandbox. + + The second generation runtimes are technically still in a sandbox, but it + is much less restrictive, so generally you shouldn't need to check for it. + see https://cloud.google.com/appengine/docs/standard/runtimes + """ + return is_appengine() and os.environ["APPENGINE_RUNTIME"] == "python27" def is_local_appengine(): - return ('APPENGINE_RUNTIME' in os.environ and - 'Development/' in os.environ['SERVER_SOFTWARE']) + return "APPENGINE_RUNTIME" in os.environ and os.environ.get( + "SERVER_SOFTWARE", "" + ).startswith("Development/") def is_prod_appengine(): - return ('APPENGINE_RUNTIME' in os.environ and - 'Google App Engine/' in os.environ['SERVER_SOFTWARE'] and - not is_prod_appengine_mvms()) + return "APPENGINE_RUNTIME" in os.environ and os.environ.get( + "SERVER_SOFTWARE", "" + ).startswith("Google App Engine/") def is_prod_appengine_mvms(): - return os.environ.get('GAE_VM', False) == 'true' + """Deprecated.""" + return False diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-38.pyc index 8d30833f02c254ce6ce5ebeef2fb0c412a3feb91..cf2d1522f587d62128656fc06c7167eedd6a583d 100644 GIT binary patch delta 91 zcmdnUc#V-Kl$V!_0SGkz?TVksW9?k6pOK%Ns$W!DTAG!qUtE-|pOToDnVOTFUsRG> ttXEN4rC*ksSEiqnnWSG(S(1^TXRK$TUz}Nzs#}nloSm4ST0Ak;2LNq%ARqt$ delta 54 zcmcb{xRH@3l$V!_0SKO#ZHSx5V=Wh^Uy@s(Uyxa#o0(T!l9-dDYm{M9T49`@2ojvw G<pTh?=@F~| diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-38.pyc index 6191aed670dab041c3bb36c3a3e3419f2318b012..d44d8677e2f94ca6b276ddc567367d5c94400b1b 100644 GIT binary patch delta 531 zcmY*VO-n*S6rFpW_n35iWEc@8tx|(>f;O#!sC_|1(5BQL`N~v$Dp?DmeQqA~5BdS( zu1&wA=ufl>it;rdPs+L6`M8{O?wR|x|GDQJCX;a@*UISW<YRl_lu|plqEf$dMYG#( zUwFcAmc?1I=DF2!z1ed8!gcpXblh4;RK1dDbX%2rZKJR$e6QuMHHziS;<@Vw{nS?S z9tiQN)Mh}f;Y;c{KL4OfeN&<oDMW$6VDS-Nhew$Mww^^o=n_W;999$Qn4|-Xb`EJ^ zfHIsALuzs07(iw=cwatFAP0tVnH+-C>_Si7V+w2kFpJ@g;t?b^u|rB7iBqXK|4+r2 zJ#?!3wAQeVhE%fwwc12|j2bbj8Co^3q$Mn}WULtSxS>Kwvv;{%&r;2z)TRwmBFqc$ no7u+dA4=NN!@w`b^jC~QgPl|vyO2YdLkR8I<QeSd=V0m=Kf6p2 delta 607 zcmezAe<y%1l$V!_0SKO#ZHQapvXL)IP%ccrB)34nAhSR>Gq1QLF(*gYD8r<*!Z<$> zBsh7qpdIfQMh1pr7N9l`Mi!RM{{;7QN&W!|^+AM~S(sQDVQ}&_nWc<Tn`>l)Ir!Ew zF)*;m^DuER@-XVKOunls!NbPD_MhcH3mXq357T5uHQ~uZYB8eBOpHwbI9NECnf`My z14%G%a;2JdJwk+$?Jox_2a^z^7)YLx3B*HXK}<lFLl=RW4phVThl35OAI65tvO#sR z0d1^@Si%Ok4p|Z^2UCtlLp=oZ7$a0C%n9gD!{+RN9GsvqfrN&&x_UhuG<+b2z>I=B z4sIpLFogdgA%&s`=r@oWMy6jJ955R|G*}c}C(H}~#SoFh0gQ1b2B!aP%zTWKZ>!5P GasU8HJ7XpQ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-38.pyc index eaf7a87f7e9064328ab95cb972ff398a2fa4d388..1b0d79b3d9f3b221732567557064f9ba124720a2 100644 GIT binary patch delta 345 zcmaE9)nv^V%FD~e00f%<cExYe+sOBb*||nPBR@A)zo@dbG%HiTxF}gaB{45EH77a0 zs3f&mucER_zbrMcOg|?xNxz`7BqKl1SkFSgII|>Gw;(Y&J25@Acrzc%GFDLrmj5iw z9E@CyER0MHAPC}bKFK+qkuhX*BDVn(Zz0g;Viq9522`<m9`9;K;Y^T_4Uk}9<6&ZB z<oM6Vyg7!SlaX=S<TQb^jPo{|2-Y*JF9WGk0I3q>Vw7MMV&q^F0a^vJhz)EN69Wgx zvRfjy%!(&LioHOJ*;#-}SeSSig_xK?ETB?0pt8vp5;8!+%`p<SOpGd<Z%M^7YBDea uHCcc(DF78R^8qz*F!BLC!^6S?WI=2K*)cgo<_oVRmnerW2M8#0m;(TH7)6-? delta 320 zcmZp&erd%Q%FD~e00hs=HpDgQZ{&N#EEld{l3So(kXfLcnO9trn3JPxlwnd@VVs`` z65MRevW!)fk>wu?3kM??BMT!F7_$6fVcYzUb2=kq#O5|`118>5prOSqK!S~l>Hp@# zysH_7b3sBjK!Smdhl!1e;~yK#=0<)_M#kBby9LfNF5Vm|SkJ7!8l*}Aq)L#BQG!v3 zk%LKunFDMQ8`Lt6Uo0G(|BKi%D_#aE4ge`;X8|f<Vd7yFVqyZZfJ)i^van8$m5|{8 zau}HYvoLS2mZ)W7G}`=ADxOiFj}fTV4y089sGOM(sEq?;K2RkGGZ!Nd3k#4BHinS{ VWKg5b7hYK|Q4T#05YXVT1^~77JL~`e diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py index be34215..d9b6733 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py @@ -34,29 +34,35 @@ from __future__ import absolute_import import platform from ctypes.util import find_library from ctypes import ( - c_void_p, c_int32, c_char_p, c_size_t, c_byte, c_uint32, c_ulong, c_long, - c_bool + c_void_p, + c_int32, + c_char_p, + c_size_t, + c_byte, + c_uint32, + c_ulong, + c_long, + c_bool, ) from ctypes import CDLL, POINTER, CFUNCTYPE -security_path = find_library('Security') +security_path = find_library("Security") if not security_path: - raise ImportError('The library Security could not be found') + raise ImportError("The library Security could not be found") -core_foundation_path = find_library('CoreFoundation') +core_foundation_path = find_library("CoreFoundation") if not core_foundation_path: - raise ImportError('The library CoreFoundation could not be found') + raise ImportError("The library CoreFoundation could not be found") version = platform.mac_ver()[0] -version_info = tuple(map(int, version.split('.'))) +version_info = tuple(map(int, version.split("."))) if version_info < (10, 8): raise OSError( - 'Only OS X 10.8 and newer are supported, not %s.%s' % ( - version_info[0], version_info[1] - ) + "Only OS X 10.8 and newer are supported, not %s.%s" + % (version_info[0], version_info[1]) ) Security = CDLL(security_path, use_errno=True) @@ -129,27 +135,19 @@ try: Security.SecKeyGetTypeID.argtypes = [] Security.SecKeyGetTypeID.restype = CFTypeID - Security.SecCertificateCreateWithData.argtypes = [ - CFAllocatorRef, - CFDataRef - ] + Security.SecCertificateCreateWithData.argtypes = [CFAllocatorRef, CFDataRef] Security.SecCertificateCreateWithData.restype = SecCertificateRef - Security.SecCertificateCopyData.argtypes = [ - SecCertificateRef - ] + Security.SecCertificateCopyData.argtypes = [SecCertificateRef] Security.SecCertificateCopyData.restype = CFDataRef - Security.SecCopyErrorMessageString.argtypes = [ - OSStatus, - c_void_p - ] + Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p] Security.SecCopyErrorMessageString.restype = CFStringRef Security.SecIdentityCreateWithCertificate.argtypes = [ CFTypeRef, SecCertificateRef, - POINTER(SecIdentityRef) + POINTER(SecIdentityRef), ] Security.SecIdentityCreateWithCertificate.restype = OSStatus @@ -159,201 +157,126 @@ try: c_void_p, Boolean, c_void_p, - POINTER(SecKeychainRef) + POINTER(SecKeychainRef), ] Security.SecKeychainCreate.restype = OSStatus - Security.SecKeychainDelete.argtypes = [ - SecKeychainRef - ] + Security.SecKeychainDelete.argtypes = [SecKeychainRef] Security.SecKeychainDelete.restype = OSStatus Security.SecPKCS12Import.argtypes = [ CFDataRef, CFDictionaryRef, - POINTER(CFArrayRef) + POINTER(CFArrayRef), ] Security.SecPKCS12Import.restype = OSStatus SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t)) - SSLWriteFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)) + SSLWriteFunc = CFUNCTYPE( + OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t) + ) - Security.SSLSetIOFuncs.argtypes = [ - SSLContextRef, - SSLReadFunc, - SSLWriteFunc - ] + Security.SSLSetIOFuncs.argtypes = [SSLContextRef, SSLReadFunc, SSLWriteFunc] Security.SSLSetIOFuncs.restype = OSStatus - Security.SSLSetPeerID.argtypes = [ - SSLContextRef, - c_char_p, - c_size_t - ] + Security.SSLSetPeerID.argtypes = [SSLContextRef, c_char_p, c_size_t] Security.SSLSetPeerID.restype = OSStatus - Security.SSLSetCertificate.argtypes = [ - SSLContextRef, - CFArrayRef - ] + Security.SSLSetCertificate.argtypes = [SSLContextRef, CFArrayRef] Security.SSLSetCertificate.restype = OSStatus - Security.SSLSetCertificateAuthorities.argtypes = [ - SSLContextRef, - CFTypeRef, - Boolean - ] + Security.SSLSetCertificateAuthorities.argtypes = [SSLContextRef, CFTypeRef, Boolean] Security.SSLSetCertificateAuthorities.restype = OSStatus - Security.SSLSetConnection.argtypes = [ - SSLContextRef, - SSLConnectionRef - ] + Security.SSLSetConnection.argtypes = [SSLContextRef, SSLConnectionRef] Security.SSLSetConnection.restype = OSStatus - Security.SSLSetPeerDomainName.argtypes = [ - SSLContextRef, - c_char_p, - c_size_t - ] + Security.SSLSetPeerDomainName.argtypes = [SSLContextRef, c_char_p, c_size_t] Security.SSLSetPeerDomainName.restype = OSStatus - Security.SSLHandshake.argtypes = [ - SSLContextRef - ] + Security.SSLHandshake.argtypes = [SSLContextRef] Security.SSLHandshake.restype = OSStatus - Security.SSLRead.argtypes = [ - SSLContextRef, - c_char_p, - c_size_t, - POINTER(c_size_t) - ] + Security.SSLRead.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)] Security.SSLRead.restype = OSStatus - Security.SSLWrite.argtypes = [ - SSLContextRef, - c_char_p, - c_size_t, - POINTER(c_size_t) - ] + Security.SSLWrite.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)] Security.SSLWrite.restype = OSStatus - Security.SSLClose.argtypes = [ - SSLContextRef - ] + Security.SSLClose.argtypes = [SSLContextRef] Security.SSLClose.restype = OSStatus - Security.SSLGetNumberSupportedCiphers.argtypes = [ - SSLContextRef, - POINTER(c_size_t) - ] + Security.SSLGetNumberSupportedCiphers.argtypes = [SSLContextRef, POINTER(c_size_t)] Security.SSLGetNumberSupportedCiphers.restype = OSStatus Security.SSLGetSupportedCiphers.argtypes = [ SSLContextRef, POINTER(SSLCipherSuite), - POINTER(c_size_t) + POINTER(c_size_t), ] Security.SSLGetSupportedCiphers.restype = OSStatus Security.SSLSetEnabledCiphers.argtypes = [ SSLContextRef, POINTER(SSLCipherSuite), - c_size_t + c_size_t, ] Security.SSLSetEnabledCiphers.restype = OSStatus - Security.SSLGetNumberEnabledCiphers.argtype = [ - SSLContextRef, - POINTER(c_size_t) - ] + Security.SSLGetNumberEnabledCiphers.argtype = [SSLContextRef, POINTER(c_size_t)] Security.SSLGetNumberEnabledCiphers.restype = OSStatus Security.SSLGetEnabledCiphers.argtypes = [ SSLContextRef, POINTER(SSLCipherSuite), - POINTER(c_size_t) + POINTER(c_size_t), ] Security.SSLGetEnabledCiphers.restype = OSStatus - Security.SSLGetNegotiatedCipher.argtypes = [ - SSLContextRef, - POINTER(SSLCipherSuite) - ] + Security.SSLGetNegotiatedCipher.argtypes = [SSLContextRef, POINTER(SSLCipherSuite)] Security.SSLGetNegotiatedCipher.restype = OSStatus Security.SSLGetNegotiatedProtocolVersion.argtypes = [ SSLContextRef, - POINTER(SSLProtocol) + POINTER(SSLProtocol), ] Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus - Security.SSLCopyPeerTrust.argtypes = [ - SSLContextRef, - POINTER(SecTrustRef) - ] + Security.SSLCopyPeerTrust.argtypes = [SSLContextRef, POINTER(SecTrustRef)] Security.SSLCopyPeerTrust.restype = OSStatus - Security.SecTrustSetAnchorCertificates.argtypes = [ - SecTrustRef, - CFArrayRef - ] + Security.SecTrustSetAnchorCertificates.argtypes = [SecTrustRef, CFArrayRef] Security.SecTrustSetAnchorCertificates.restype = OSStatus - Security.SecTrustSetAnchorCertificatesOnly.argstypes = [ - SecTrustRef, - Boolean - ] + Security.SecTrustSetAnchorCertificatesOnly.argstypes = [SecTrustRef, Boolean] Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus - Security.SecTrustEvaluate.argtypes = [ - SecTrustRef, - POINTER(SecTrustResultType) - ] + Security.SecTrustEvaluate.argtypes = [SecTrustRef, POINTER(SecTrustResultType)] Security.SecTrustEvaluate.restype = OSStatus - Security.SecTrustGetCertificateCount.argtypes = [ - SecTrustRef - ] + Security.SecTrustGetCertificateCount.argtypes = [SecTrustRef] Security.SecTrustGetCertificateCount.restype = CFIndex - Security.SecTrustGetCertificateAtIndex.argtypes = [ - SecTrustRef, - CFIndex - ] + Security.SecTrustGetCertificateAtIndex.argtypes = [SecTrustRef, CFIndex] Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef Security.SSLCreateContext.argtypes = [ CFAllocatorRef, SSLProtocolSide, - SSLConnectionType + SSLConnectionType, ] Security.SSLCreateContext.restype = SSLContextRef - Security.SSLSetSessionOption.argtypes = [ - SSLContextRef, - SSLSessionOption, - Boolean - ] + Security.SSLSetSessionOption.argtypes = [SSLContextRef, SSLSessionOption, Boolean] Security.SSLSetSessionOption.restype = OSStatus - Security.SSLSetProtocolVersionMin.argtypes = [ - SSLContextRef, - SSLProtocol - ] + Security.SSLSetProtocolVersionMin.argtypes = [SSLContextRef, SSLProtocol] Security.SSLSetProtocolVersionMin.restype = OSStatus - Security.SSLSetProtocolVersionMax.argtypes = [ - SSLContextRef, - SSLProtocol - ] + Security.SSLSetProtocolVersionMax.argtypes = [SSLContextRef, SSLProtocol] Security.SSLSetProtocolVersionMax.restype = OSStatus - Security.SecCopyErrorMessageString.argtypes = [ - OSStatus, - c_void_p - ] + Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p] Security.SecCopyErrorMessageString.restype = CFStringRef Security.SSLReadFunc = SSLReadFunc @@ -369,64 +292,47 @@ try: Security.OSStatus = OSStatus Security.kSecImportExportPassphrase = CFStringRef.in_dll( - Security, 'kSecImportExportPassphrase' + Security, "kSecImportExportPassphrase" ) Security.kSecImportItemIdentity = CFStringRef.in_dll( - Security, 'kSecImportItemIdentity' + Security, "kSecImportItemIdentity" ) # CoreFoundation time! - CoreFoundation.CFRetain.argtypes = [ - CFTypeRef - ] + CoreFoundation.CFRetain.argtypes = [CFTypeRef] CoreFoundation.CFRetain.restype = CFTypeRef - CoreFoundation.CFRelease.argtypes = [ - CFTypeRef - ] + CoreFoundation.CFRelease.argtypes = [CFTypeRef] CoreFoundation.CFRelease.restype = None - CoreFoundation.CFGetTypeID.argtypes = [ - CFTypeRef - ] + CoreFoundation.CFGetTypeID.argtypes = [CFTypeRef] CoreFoundation.CFGetTypeID.restype = CFTypeID CoreFoundation.CFStringCreateWithCString.argtypes = [ CFAllocatorRef, c_char_p, - CFStringEncoding + CFStringEncoding, ] CoreFoundation.CFStringCreateWithCString.restype = CFStringRef - CoreFoundation.CFStringGetCStringPtr.argtypes = [ - CFStringRef, - CFStringEncoding - ] + CoreFoundation.CFStringGetCStringPtr.argtypes = [CFStringRef, CFStringEncoding] CoreFoundation.CFStringGetCStringPtr.restype = c_char_p CoreFoundation.CFStringGetCString.argtypes = [ CFStringRef, c_char_p, CFIndex, - CFStringEncoding + CFStringEncoding, ] CoreFoundation.CFStringGetCString.restype = c_bool - CoreFoundation.CFDataCreate.argtypes = [ - CFAllocatorRef, - c_char_p, - CFIndex - ] + CoreFoundation.CFDataCreate.argtypes = [CFAllocatorRef, c_char_p, CFIndex] CoreFoundation.CFDataCreate.restype = CFDataRef - CoreFoundation.CFDataGetLength.argtypes = [ - CFDataRef - ] + CoreFoundation.CFDataGetLength.argtypes = [CFDataRef] CoreFoundation.CFDataGetLength.restype = CFIndex - CoreFoundation.CFDataGetBytePtr.argtypes = [ - CFDataRef - ] + CoreFoundation.CFDataGetBytePtr.argtypes = [CFDataRef] CoreFoundation.CFDataGetBytePtr.restype = c_void_p CoreFoundation.CFDictionaryCreate.argtypes = [ @@ -435,14 +341,11 @@ try: POINTER(CFTypeRef), CFIndex, CFDictionaryKeyCallBacks, - CFDictionaryValueCallBacks + CFDictionaryValueCallBacks, ] CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef - CoreFoundation.CFDictionaryGetValue.argtypes = [ - CFDictionaryRef, - CFTypeRef - ] + CoreFoundation.CFDictionaryGetValue.argtypes = [CFDictionaryRef, CFTypeRef] CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef CoreFoundation.CFArrayCreate.argtypes = [ @@ -456,36 +359,30 @@ try: CoreFoundation.CFArrayCreateMutable.argtypes = [ CFAllocatorRef, CFIndex, - CFArrayCallBacks + CFArrayCallBacks, ] CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef - CoreFoundation.CFArrayAppendValue.argtypes = [ - CFMutableArrayRef, - c_void_p - ] + CoreFoundation.CFArrayAppendValue.argtypes = [CFMutableArrayRef, c_void_p] CoreFoundation.CFArrayAppendValue.restype = None - CoreFoundation.CFArrayGetCount.argtypes = [ - CFArrayRef - ] + CoreFoundation.CFArrayGetCount.argtypes = [CFArrayRef] CoreFoundation.CFArrayGetCount.restype = CFIndex - CoreFoundation.CFArrayGetValueAtIndex.argtypes = [ - CFArrayRef, - CFIndex - ] + CoreFoundation.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex] CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll( - CoreFoundation, 'kCFAllocatorDefault' + CoreFoundation, "kCFAllocatorDefault" + ) + CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll( + CoreFoundation, "kCFTypeArrayCallBacks" ) - CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(CoreFoundation, 'kCFTypeArrayCallBacks') CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll( - CoreFoundation, 'kCFTypeDictionaryKeyCallBacks' + CoreFoundation, "kCFTypeDictionaryKeyCallBacks" ) CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll( - CoreFoundation, 'kCFTypeDictionaryValueCallBacks' + CoreFoundation, "kCFTypeDictionaryValueCallBacks" ) CoreFoundation.CFTypeRef = CFTypeRef @@ -494,7 +391,7 @@ try: CoreFoundation.CFDictionaryRef = CFDictionaryRef except (AttributeError): - raise ImportError('Error initializing ctypes') + raise ImportError("Error initializing ctypes") class CFConst(object): @@ -502,6 +399,7 @@ class CFConst(object): A class object that acts as essentially a namespace for CoreFoundation constants. """ + kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) @@ -509,6 +407,7 @@ class SecurityConst(object): """ A class object that acts as essentially a namespace for Security constants. """ + kSSLSessionOptionBreakOnServerAuth = 0 kSSLProtocol2 = 1 @@ -516,6 +415,7 @@ class SecurityConst(object): kTLSProtocol1 = 4 kTLSProtocol11 = 7 kTLSProtocol12 = 8 + # SecureTransport does not support TLS 1.3 even if there's a constant for it kTLSProtocol13 = 10 kTLSProtocolMaxSupported = 999 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py index b13cd9e..e60168c 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py @@ -66,22 +66,18 @@ def _cf_string_to_unicode(value): value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p)) string = CoreFoundation.CFStringGetCStringPtr( - value_as_void_p, - CFConst.kCFStringEncodingUTF8 + value_as_void_p, CFConst.kCFStringEncodingUTF8 ) if string is None: buffer = ctypes.create_string_buffer(1024) result = CoreFoundation.CFStringGetCString( - value_as_void_p, - buffer, - 1024, - CFConst.kCFStringEncodingUTF8 + value_as_void_p, buffer, 1024, CFConst.kCFStringEncodingUTF8 ) if not result: - raise OSError('Error copying C string from CFStringRef') + raise OSError("Error copying C string from CFStringRef") string = buffer.value if string is not None: - string = string.decode('utf-8') + string = string.decode("utf-8") return string @@ -97,8 +93,8 @@ def _assert_no_error(error, exception_class=None): output = _cf_string_to_unicode(cf_error_string) CoreFoundation.CFRelease(cf_error_string) - if output is None or output == u'': - output = u'OSStatus %s' % error + if output is None or output == u"": + output = u"OSStatus %s" % error if exception_class is None: exception_class = ssl.SSLError @@ -115,8 +111,7 @@ def _cert_array_from_pem(pem_bundle): pem_bundle = pem_bundle.replace(b"\r\n", b"\n") der_certs = [ - base64.b64decode(match.group(1)) - for match in _PEM_CERTS_RE.finditer(pem_bundle) + base64.b64decode(match.group(1)) for match in _PEM_CERTS_RE.finditer(pem_bundle) ] if not der_certs: raise ssl.SSLError("No root certificates specified") @@ -124,7 +119,7 @@ def _cert_array_from_pem(pem_bundle): cert_array = CoreFoundation.CFArrayCreateMutable( CoreFoundation.kCFAllocatorDefault, 0, - ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks) + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), ) if not cert_array: raise ssl.SSLError("Unable to allocate memory!") @@ -186,21 +181,16 @@ def _temporary_keychain(): # some random bytes to password-protect the keychain we're creating, so we # ask for 40 random bytes. random_bytes = os.urandom(40) - filename = base64.b16encode(random_bytes[:8]).decode('utf-8') + filename = base64.b16encode(random_bytes[:8]).decode("utf-8") password = base64.b16encode(random_bytes[8:]) # Must be valid UTF-8 tempdirectory = tempfile.mkdtemp() - keychain_path = os.path.join(tempdirectory, filename).encode('utf-8') + keychain_path = os.path.join(tempdirectory, filename).encode("utf-8") # We now want to create the keychain itself. keychain = Security.SecKeychainRef() status = Security.SecKeychainCreate( - keychain_path, - len(password), - password, - False, - None, - ctypes.byref(keychain) + keychain_path, len(password), password, False, None, ctypes.byref(keychain) ) _assert_no_error(status) @@ -219,14 +209,12 @@ def _load_items_from_file(keychain, path): identities = [] result_array = None - with open(path, 'rb') as f: + with open(path, "rb") as f: raw_filedata = f.read() try: filedata = CoreFoundation.CFDataCreate( - CoreFoundation.kCFAllocatorDefault, - raw_filedata, - len(raw_filedata) + CoreFoundation.kCFAllocatorDefault, raw_filedata, len(raw_filedata) ) result_array = CoreFoundation.CFArrayRef() result = Security.SecItemImport( @@ -237,7 +225,7 @@ def _load_items_from_file(keychain, path): 0, # import flags None, # key params, can include passphrase in the future keychain, # The keychain to insert into - ctypes.byref(result_array) # Results + ctypes.byref(result_array), # Results ) _assert_no_error(result) @@ -247,9 +235,7 @@ def _load_items_from_file(keychain, path): # keychain already has them! result_count = CoreFoundation.CFArrayGetCount(result_array) for index in range(result_count): - item = CoreFoundation.CFArrayGetValueAtIndex( - result_array, index - ) + item = CoreFoundation.CFArrayGetValueAtIndex(result_array, index) item = ctypes.cast(item, CoreFoundation.CFTypeRef) if _is_cert(item): @@ -307,9 +293,7 @@ def _load_client_cert_chain(keychain, *paths): try: for file_path in paths: - new_identities, new_certs = _load_items_from_file( - keychain, file_path - ) + new_identities, new_certs = _load_items_from_file(keychain, file_path) identities.extend(new_identities) certificates.extend(new_certs) @@ -318,9 +302,7 @@ def _load_client_cert_chain(keychain, *paths): if not identities: new_identity = Security.SecIdentityRef() status = Security.SecIdentityCreateWithCertificate( - keychain, - certificates[0], - ctypes.byref(new_identity) + keychain, certificates[0], ctypes.byref(new_identity) ) _assert_no_error(status) identities.append(new_identity) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/appengine.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/appengine.py index 9b42952..d09d2be 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/appengine.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/appengine.py @@ -50,7 +50,7 @@ from ..exceptions import ( MaxRetryError, ProtocolError, TimeoutError, - SSLError + SSLError, ) from ..request import RequestMethods @@ -96,23 +96,24 @@ class AppEngineManager(RequestMethods): Beyond those cases, it will raise normal urllib3 errors. """ - def __init__(self, headers=None, retries=None, validate_certificate=True, - urlfetch_retries=True): + def __init__( + self, + headers=None, + retries=None, + validate_certificate=True, + urlfetch_retries=True, + ): if not urlfetch: raise AppEnginePlatformError( - "URLFetch is not available in this environment.") - - if is_prod_appengine_mvms(): - raise AppEnginePlatformError( - "Use normal urllib3.PoolManager instead of AppEngineManager" - "on Managed VMs, as using URLFetch is not necessary in " - "this environment.") + "URLFetch is not available in this environment." + ) warnings.warn( "urllib3 is using URLFetch on Google App Engine sandbox instead " "of sockets. To use sockets directly instead of URLFetch see " "https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.", - AppEnginePlatformWarning) + AppEnginePlatformWarning, + ) RequestMethods.__init__(self, headers) self.validate_certificate = validate_certificate @@ -127,17 +128,22 @@ class AppEngineManager(RequestMethods): # Return False to re-raise any potential exceptions return False - def urlopen(self, method, url, body=None, headers=None, - retries=None, redirect=True, timeout=Timeout.DEFAULT_TIMEOUT, - **response_kw): + def urlopen( + self, + method, + url, + body=None, + headers=None, + retries=None, + redirect=True, + timeout=Timeout.DEFAULT_TIMEOUT, + **response_kw + ): retries = self._get_retries(retries, redirect) try: - follow_redirects = ( - redirect and - retries.redirect != 0 and - retries.total) + follow_redirects = redirect and retries.redirect != 0 and retries.total response = urlfetch.fetch( url, payload=body, @@ -152,44 +158,52 @@ class AppEngineManager(RequestMethods): raise TimeoutError(self, e) except urlfetch.InvalidURLError as e: - if 'too large' in str(e): + if "too large" in str(e): raise AppEnginePlatformError( "URLFetch request too large, URLFetch only " - "supports requests up to 10mb in size.", e) + "supports requests up to 10mb in size.", + e, + ) raise ProtocolError(e) except urlfetch.DownloadError as e: - if 'Too many redirects' in str(e): + if "Too many redirects" in str(e): raise MaxRetryError(self, url, reason=e) raise ProtocolError(e) except urlfetch.ResponseTooLargeError as e: raise AppEnginePlatformError( "URLFetch response too large, URLFetch only supports" - "responses up to 32mb in size.", e) + "responses up to 32mb in size.", + e, + ) except urlfetch.SSLCertificateError as e: raise SSLError(e) except urlfetch.InvalidMethodError as e: raise AppEnginePlatformError( - "URLFetch does not support method: %s" % method, e) + "URLFetch does not support method: %s" % method, e + ) http_response = self._urlfetch_response_to_http_response( - response, retries=retries, **response_kw) + response, retries=retries, **response_kw + ) # Handle redirect? redirect_location = redirect and http_response.get_redirect_location() if redirect_location: # Check for redirect response - if (self.urlfetch_retries and retries.raise_on_redirect): + if self.urlfetch_retries and retries.raise_on_redirect: raise MaxRetryError(self, url, "too many redirects") else: if http_response.status == 303: - method = 'GET' + method = "GET" try: - retries = retries.increment(method, url, response=http_response, _pool=self) + retries = retries.increment( + method, url, response=http_response, _pool=self + ) except MaxRetryError: if retries.raise_on_redirect: raise MaxRetryError(self, url, "too many redirects") @@ -199,22 +213,32 @@ class AppEngineManager(RequestMethods): log.debug("Redirecting %s -> %s", url, redirect_location) redirect_url = urljoin(url, redirect_location) return self.urlopen( - method, redirect_url, body, headers, - retries=retries, redirect=redirect, - timeout=timeout, **response_kw) + method, + redirect_url, + body, + headers, + retries=retries, + redirect=redirect, + timeout=timeout, + **response_kw + ) # Check if we should retry the HTTP response. - has_retry_after = bool(http_response.getheader('Retry-After')) + has_retry_after = bool(http_response.getheader("Retry-After")) if retries.is_retry(method, http_response.status, has_retry_after): - retries = retries.increment( - method, url, response=http_response, _pool=self) + retries = retries.increment(method, url, response=http_response, _pool=self) log.debug("Retry: %s", url) retries.sleep(http_response) return self.urlopen( - method, url, - body=body, headers=headers, - retries=retries, redirect=redirect, - timeout=timeout, **response_kw) + method, + url, + body=body, + headers=headers, + retries=retries, + redirect=redirect, + timeout=timeout, + **response_kw + ) return http_response @@ -223,18 +247,18 @@ class AppEngineManager(RequestMethods): if is_prod_appengine(): # Production GAE handles deflate encoding automatically, but does # not remove the encoding header. - content_encoding = urlfetch_resp.headers.get('content-encoding') + content_encoding = urlfetch_resp.headers.get("content-encoding") - if content_encoding == 'deflate': - del urlfetch_resp.headers['content-encoding'] + if content_encoding == "deflate": + del urlfetch_resp.headers["content-encoding"] - transfer_encoding = urlfetch_resp.headers.get('transfer-encoding') + transfer_encoding = urlfetch_resp.headers.get("transfer-encoding") # We have a full response's content, # so let's make sure we don't report ourselves as chunked data. - if transfer_encoding == 'chunked': + if transfer_encoding == "chunked": encodings = transfer_encoding.split(",") - encodings.remove('chunked') - urlfetch_resp.headers['transfer-encoding'] = ','.join(encodings) + encodings.remove("chunked") + urlfetch_resp.headers["transfer-encoding"] = ",".join(encodings) original_response = HTTPResponse( # In order for decoding to work, we must present the content as @@ -262,20 +286,21 @@ class AppEngineManager(RequestMethods): warnings.warn( "URLFetch does not support granular timeout settings, " "reverting to total or default URLFetch timeout.", - AppEnginePlatformWarning) + AppEnginePlatformWarning, + ) return timeout.total return timeout def _get_retries(self, retries, redirect): if not isinstance(retries, Retry): - retries = Retry.from_int( - retries, redirect=redirect, default=self.retries) + retries = Retry.from_int(retries, redirect=redirect, default=self.retries) if retries.connect or retries.read or retries.redirect: warnings.warn( "URLFetch only supports total retries and does not " "recognize connect, read, or redirect retry parameters.", - AppEnginePlatformWarning) + AppEnginePlatformWarning, + ) return retries diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py index 8ea127c..1fd242a 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py @@ -20,7 +20,7 @@ class NTLMConnectionPool(HTTPSConnectionPool): Implements an NTLM authentication version of an urllib3 connection pool """ - scheme = 'https' + scheme = "https" def __init__(self, user, pw, authurl, *args, **kwargs): """ @@ -31,7 +31,7 @@ class NTLMConnectionPool(HTTPSConnectionPool): super(NTLMConnectionPool, self).__init__(*args, **kwargs) self.authurl = authurl self.rawuser = user - user_parts = user.split('\\', 1) + user_parts = user.split("\\", 1) self.domain = user_parts[0].upper() self.user = user_parts[1] self.pw = pw @@ -40,72 +40,82 @@ class NTLMConnectionPool(HTTPSConnectionPool): # Performs the NTLM handshake that secures the connection. The socket # must be kept open while requests are performed. self.num_connections += 1 - log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s', - self.num_connections, self.host, self.authurl) + log.debug( + "Starting NTLM HTTPS connection no. %d: https://%s%s", + self.num_connections, + self.host, + self.authurl, + ) - headers = {'Connection': 'Keep-Alive'} - req_header = 'Authorization' - resp_header = 'www-authenticate' + headers = {"Connection": "Keep-Alive"} + req_header = "Authorization" + resp_header = "www-authenticate" conn = HTTPSConnection(host=self.host, port=self.port) # Send negotiation message - headers[req_header] = ( - 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.rawuser)) - log.debug('Request headers: %s', headers) - conn.request('GET', self.authurl, None, headers) + headers[req_header] = "NTLM %s" % ntlm.create_NTLM_NEGOTIATE_MESSAGE( + self.rawuser + ) + log.debug("Request headers: %s", headers) + conn.request("GET", self.authurl, None, headers) res = conn.getresponse() reshdr = dict(res.getheaders()) - log.debug('Response status: %s %s', res.status, res.reason) - log.debug('Response headers: %s', reshdr) - log.debug('Response data: %s [...]', res.read(100)) + log.debug("Response status: %s %s", res.status, res.reason) + log.debug("Response headers: %s", reshdr) + log.debug("Response data: %s [...]", res.read(100)) # Remove the reference to the socket, so that it can not be closed by # the response object (we want to keep the socket open) res.fp = None # Server should respond with a challenge message - auth_header_values = reshdr[resp_header].split(', ') + auth_header_values = reshdr[resp_header].split(", ") auth_header_value = None for s in auth_header_values: - if s[:5] == 'NTLM ': + if s[:5] == "NTLM ": auth_header_value = s[5:] if auth_header_value is None: - raise Exception('Unexpected %s response header: %s' % - (resp_header, reshdr[resp_header])) + raise Exception( + "Unexpected %s response header: %s" % (resp_header, reshdr[resp_header]) + ) # Send authentication message - ServerChallenge, NegotiateFlags = \ - ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value) - auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, - self.user, - self.domain, - self.pw, - NegotiateFlags) - headers[req_header] = 'NTLM %s' % auth_msg - log.debug('Request headers: %s', headers) - conn.request('GET', self.authurl, None, headers) + ServerChallenge, NegotiateFlags = ntlm.parse_NTLM_CHALLENGE_MESSAGE( + auth_header_value + ) + auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE( + ServerChallenge, self.user, self.domain, self.pw, NegotiateFlags + ) + headers[req_header] = "NTLM %s" % auth_msg + log.debug("Request headers: %s", headers) + conn.request("GET", self.authurl, None, headers) res = conn.getresponse() - log.debug('Response status: %s %s', res.status, res.reason) - log.debug('Response headers: %s', dict(res.getheaders())) - log.debug('Response data: %s [...]', res.read()[:100]) + log.debug("Response status: %s %s", res.status, res.reason) + log.debug("Response headers: %s", dict(res.getheaders())) + log.debug("Response data: %s [...]", res.read()[:100]) if res.status != 200: if res.status == 401: - raise Exception('Server rejected request: wrong ' - 'username or password') - raise Exception('Wrong server response: %s %s' % - (res.status, res.reason)) + raise Exception("Server rejected request: wrong username or password") + raise Exception("Wrong server response: %s %s" % (res.status, res.reason)) res.fp = None - log.debug('Connection established') + log.debug("Connection established") return conn - def urlopen(self, method, url, body=None, headers=None, retries=3, - redirect=True, assert_same_host=True): + def urlopen( + self, + method, + url, + body=None, + headers=None, + retries=3, + redirect=True, + assert_same_host=True, + ): if headers is None: headers = {} - headers['Connection'] = 'Keep-Alive' - return super(NTLMConnectionPool, self).urlopen(method, url, body, - headers, retries, - redirect, - assert_same_host) + headers["Connection"] = "Keep-Alive" + return super(NTLMConnectionPool, self).urlopen( + method, url, body, headers, retries, redirect, assert_same_host + ) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py index abfc319..d8fe062 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py @@ -47,6 +47,7 @@ import OpenSSL.SSL from cryptography import x509 from cryptography.hazmat.backends.openssl import backend as openssl_backend from cryptography.hazmat.backends.openssl.x509 import _Certificate + try: from cryptography.x509 import UnsupportedExtension except ImportError: @@ -54,6 +55,7 @@ except ImportError: class UnsupportedExtension(Exception): pass + from socket import timeout, error as SocketError from io import BytesIO @@ -71,7 +73,7 @@ import sys from .. import util -__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] +__all__ = ["inject_into_urllib3", "extract_from_urllib3"] # SNI always works. HAS_SNI = True @@ -82,25 +84,23 @@ _openssl_versions = { ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD, } -if hasattr(ssl, 'PROTOCOL_SSLv3') and hasattr(OpenSSL.SSL, 'SSLv3_METHOD'): +if hasattr(ssl, "PROTOCOL_SSLv3") and hasattr(OpenSSL.SSL, "SSLv3_METHOD"): _openssl_versions[ssl.PROTOCOL_SSLv3] = OpenSSL.SSL.SSLv3_METHOD -if hasattr(ssl, 'PROTOCOL_TLSv1_1') and hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'): +if hasattr(ssl, "PROTOCOL_TLSv1_1") and hasattr(OpenSSL.SSL, "TLSv1_1_METHOD"): _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD -if hasattr(ssl, 'PROTOCOL_TLSv1_2') and hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'): +if hasattr(ssl, "PROTOCOL_TLSv1_2") and hasattr(OpenSSL.SSL, "TLSv1_2_METHOD"): _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD _stdlib_to_openssl_verify = { ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE, ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER, - ssl.CERT_REQUIRED: - OpenSSL.SSL.VERIFY_PEER + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT, + ssl.CERT_REQUIRED: OpenSSL.SSL.VERIFY_PEER + + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT, } -_openssl_to_stdlib_verify = dict( - (v, k) for k, v in _stdlib_to_openssl_verify.items() -) +_openssl_to_stdlib_verify = dict((v, k) for k, v in _stdlib_to_openssl_verify.items()) # OpenSSL will only write 16K at a time SSL_WRITE_BLOCKSIZE = 16384 @@ -113,7 +113,7 @@ log = logging.getLogger(__name__) def inject_into_urllib3(): - 'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.' + "Monkey-patch urllib3 with PyOpenSSL-backed SSL-support." _validate_dependencies_met() @@ -126,7 +126,7 @@ def inject_into_urllib3(): def extract_from_urllib3(): - 'Undo monkey-patching by :func:`inject_into_urllib3`.' + "Undo monkey-patching by :func:`inject_into_urllib3`." util.SSLContext = orig_util_SSLContext util.ssl_.SSLContext = orig_util_SSLContext @@ -143,17 +143,23 @@ def _validate_dependencies_met(): """ # Method added in `cryptography==1.1`; not available in older versions from cryptography.x509.extensions import Extensions + if getattr(Extensions, "get_extension_for_class", None) is None: - raise ImportError("'cryptography' module missing required functionality. " - "Try upgrading to v1.3.4 or newer.") + raise ImportError( + "'cryptography' module missing required functionality. " + "Try upgrading to v1.3.4 or newer." + ) # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509 # attribute is only present on those versions. from OpenSSL.crypto import X509 + x509 = X509() if getattr(x509, "_x509", None) is None: - raise ImportError("'pyOpenSSL' module missing required functionality. " - "Try upgrading to v0.14 or newer.") + raise ImportError( + "'pyOpenSSL' module missing required functionality. " + "Try upgrading to v0.14 or newer." + ) def _dnsname_to_stdlib(name): @@ -169,6 +175,7 @@ def _dnsname_to_stdlib(name): If the name cannot be idna-encoded then we return None signalling that the name given should be skipped. """ + def idna_encode(name): """ Borrowed wholesale from the Python Cryptography Project. It turns out @@ -178,23 +185,23 @@ def _dnsname_to_stdlib(name): from pip._vendor import idna try: - for prefix in [u'*.', u'.']: + for prefix in [u"*.", u"."]: if name.startswith(prefix): - name = name[len(prefix):] - return prefix.encode('ascii') + idna.encode(name) + name = name[len(prefix) :] + return prefix.encode("ascii") + idna.encode(name) return idna.encode(name) except idna.core.IDNAError: return None # Don't send IPv6 addresses through the IDNA encoder. - if ':' in name: + if ":" in name: return name name = idna_encode(name) if name is None: return None elif sys.version_info >= (3, 0): - name = name.decode('utf-8') + name = name.decode("utf-8") return name @@ -213,14 +220,16 @@ def get_subj_alt_name(peer_cert): # We want to find the SAN extension. Ask Cryptography to locate it (it's # faster than looping in Python) try: - ext = cert.extensions.get_extension_for_class( - x509.SubjectAlternativeName - ).value + ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName).value except x509.ExtensionNotFound: # No such extension, return the empty list. return [] - except (x509.DuplicateExtension, UnsupportedExtension, - x509.UnsupportedGeneralNameType, UnicodeError) as e: + except ( + x509.DuplicateExtension, + UnsupportedExtension, + x509.UnsupportedGeneralNameType, + UnicodeError, + ) as e: # A problem has been found with the quality of the certificate. Assume # no SAN field is present. log.warning( @@ -239,23 +248,23 @@ def get_subj_alt_name(peer_cert): # does with certificates, and so we need to attempt to do the same. # We also want to skip over names which cannot be idna encoded. names = [ - ('DNS', name) for name in map(_dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName)) + ("DNS", name) + for name in map(_dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName)) if name is not None ] names.extend( - ('IP Address', str(name)) - for name in ext.get_values_for_type(x509.IPAddress) + ("IP Address", str(name)) for name in ext.get_values_for_type(x509.IPAddress) ) return names class WrappedSocket(object): - '''API-compatibility wrapper for Python OpenSSL's Connection-class. + """API-compatibility wrapper for Python OpenSSL's Connection-class. Note: _makefile_refs, _drop() and _reuse() are needed for the garbage collector of pypy. - ''' + """ def __init__(self, connection, socket, suppress_ragged_eofs=True): self.connection = connection @@ -278,18 +287,18 @@ class WrappedSocket(object): try: data = self.connection.recv(*args, **kwargs) except OpenSSL.SSL.SysCallError as e: - if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): - return b'' + if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"): + return b"" else: raise SocketError(str(e)) except OpenSSL.SSL.ZeroReturnError: if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: - return b'' + return b"" else: raise except OpenSSL.SSL.WantReadError: if not util.wait_for_read(self.socket, self.socket.gettimeout()): - raise timeout('The read operation timed out') + raise timeout("The read operation timed out") else: return self.recv(*args, **kwargs) @@ -303,7 +312,7 @@ class WrappedSocket(object): try: return self.connection.recv_into(*args, **kwargs) except OpenSSL.SSL.SysCallError as e: - if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): + if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"): return 0 else: raise SocketError(str(e)) @@ -314,7 +323,7 @@ class WrappedSocket(object): raise except OpenSSL.SSL.WantReadError: if not util.wait_for_read(self.socket, self.socket.gettimeout()): - raise timeout('The read operation timed out') + raise timeout("The read operation timed out") else: return self.recv_into(*args, **kwargs) @@ -339,7 +348,9 @@ class WrappedSocket(object): def sendall(self, data): total_sent = 0 while total_sent < len(data): - sent = self._send_until_done(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) + sent = self._send_until_done( + data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE] + ) total_sent += sent def shutdown(self): @@ -363,15 +374,11 @@ class WrappedSocket(object): return x509 if binary_form: - return OpenSSL.crypto.dump_certificate( - OpenSSL.crypto.FILETYPE_ASN1, - x509) + return OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_ASN1, x509) return { - 'subject': ( - (('commonName', x509.get_subject().CN),), - ), - 'subjectAltName': get_subj_alt_name(x509) + "subject": ((("commonName", x509.get_subject().CN),),), + "subjectAltName": get_subj_alt_name(x509), } def version(self): @@ -388,9 +395,12 @@ class WrappedSocket(object): if _fileobject: # Platform-specific: Python 2 + def makefile(self, mode, bufsize=-1): self._makefile_refs += 1 return _fileobject(self, mode, bufsize, close=True) + + else: # Platform-specific: Python 3 makefile = backport_makefile @@ -403,6 +413,7 @@ class PyOpenSSLContext(object): for translating the interface of the standard library ``SSLContext`` object to calls into PyOpenSSL. """ + def __init__(self, protocol): self.protocol = _openssl_versions[protocol] self._ctx = OpenSSL.SSL.Context(self.protocol) @@ -424,43 +435,48 @@ class PyOpenSSLContext(object): @verify_mode.setter def verify_mode(self, value): - self._ctx.set_verify( - _stdlib_to_openssl_verify[value], - _verify_callback - ) + self._ctx.set_verify(_stdlib_to_openssl_verify[value], _verify_callback) def set_default_verify_paths(self): self._ctx.set_default_verify_paths() def set_ciphers(self, ciphers): if isinstance(ciphers, six.text_type): - ciphers = ciphers.encode('utf-8') + ciphers = ciphers.encode("utf-8") self._ctx.set_cipher_list(ciphers) def load_verify_locations(self, cafile=None, capath=None, cadata=None): if cafile is not None: - cafile = cafile.encode('utf-8') + cafile = cafile.encode("utf-8") if capath is not None: - capath = capath.encode('utf-8') - self._ctx.load_verify_locations(cafile, capath) - if cadata is not None: - self._ctx.load_verify_locations(BytesIO(cadata)) + capath = capath.encode("utf-8") + try: + self._ctx.load_verify_locations(cafile, capath) + if cadata is not None: + self._ctx.load_verify_locations(BytesIO(cadata)) + except OpenSSL.SSL.Error as e: + raise ssl.SSLError("unable to load trusted certificates: %r" % e) def load_cert_chain(self, certfile, keyfile=None, password=None): self._ctx.use_certificate_chain_file(certfile) if password is not None: if not isinstance(password, six.binary_type): - password = password.encode('utf-8') + password = password.encode("utf-8") self._ctx.set_passwd_cb(lambda *_: password) self._ctx.use_privatekey_file(keyfile or certfile) - def wrap_socket(self, sock, server_side=False, - do_handshake_on_connect=True, suppress_ragged_eofs=True, - server_hostname=None): + def wrap_socket( + self, + sock, + server_side=False, + do_handshake_on_connect=True, + suppress_ragged_eofs=True, + server_hostname=None, + ): cnx = OpenSSL.SSL.Connection(self._ctx, sock) if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3 - server_hostname = server_hostname.encode('utf-8') + server_hostname = server_hostname.encode("utf-8") if server_hostname is not None: cnx.set_tlsext_host_name(server_hostname) @@ -472,10 +488,10 @@ class PyOpenSSLContext(object): cnx.do_handshake() except OpenSSL.SSL.WantReadError: if not util.wait_for_read(sock, sock.gettimeout()): - raise timeout('select timed out') + raise timeout("select timed out") continue except OpenSSL.SSL.Error as e: - raise ssl.SSLError('bad handshake: %r' % e) + raise ssl.SSLError("bad handshake: %r" % e) break return WrappedSocket(cnx, sock) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/securetransport.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/securetransport.py index 4dc4848..a6b7e94 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/securetransport.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/securetransport.py @@ -62,12 +62,12 @@ import threading import weakref from .. import util -from ._securetransport.bindings import ( - Security, SecurityConst, CoreFoundation -) +from ._securetransport.bindings import Security, SecurityConst, CoreFoundation from ._securetransport.low_level import ( - _assert_no_error, _cert_array_from_pem, _temporary_keychain, - _load_client_cert_chain + _assert_no_error, + _cert_array_from_pem, + _temporary_keychain, + _load_client_cert_chain, ) try: # Platform-specific: Python 2 @@ -76,7 +76,7 @@ except ImportError: # Platform-specific: Python 3 _fileobject = None from ..packages.backports.makefile import backport_makefile -__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] +__all__ = ["inject_into_urllib3", "extract_from_urllib3"] # SNI always works HAS_SNI = True @@ -144,31 +144,36 @@ CIPHER_SUITES = [ ] # Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of -# TLSv1 and a high of TLSv1.3. For everything else, we pin to that version. -# TLSv1 to 1.2 are supported on macOS 10.8+ and TLSv1.3 is macOS 10.13+ +# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version. +# TLSv1 to 1.2 are supported on macOS 10.8+ _protocol_to_min_max = { - util.PROTOCOL_TLS: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocolMaxSupported), + util.PROTOCOL_TLS: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12) } if hasattr(ssl, "PROTOCOL_SSLv2"): _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = ( - SecurityConst.kSSLProtocol2, SecurityConst.kSSLProtocol2 + SecurityConst.kSSLProtocol2, + SecurityConst.kSSLProtocol2, ) if hasattr(ssl, "PROTOCOL_SSLv3"): _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = ( - SecurityConst.kSSLProtocol3, SecurityConst.kSSLProtocol3 + SecurityConst.kSSLProtocol3, + SecurityConst.kSSLProtocol3, ) if hasattr(ssl, "PROTOCOL_TLSv1"): _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = ( - SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol1 + SecurityConst.kTLSProtocol1, + SecurityConst.kTLSProtocol1, ) if hasattr(ssl, "PROTOCOL_TLSv1_1"): _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = ( - SecurityConst.kTLSProtocol11, SecurityConst.kTLSProtocol11 + SecurityConst.kTLSProtocol11, + SecurityConst.kTLSProtocol11, ) if hasattr(ssl, "PROTOCOL_TLSv1_2"): _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = ( - SecurityConst.kTLSProtocol12, SecurityConst.kTLSProtocol12 + SecurityConst.kTLSProtocol12, + SecurityConst.kTLSProtocol12, ) @@ -218,7 +223,7 @@ def _read_callback(connection_id, data_buffer, data_length_pointer): while read_count < requested_length: if timeout is None or timeout >= 0: if not util.wait_for_read(base_socket, timeout): - raise socket.error(errno.EAGAIN, 'timed out') + raise socket.error(errno.EAGAIN, "timed out") remaining = requested_length - read_count buffer = (ctypes.c_char * remaining).from_address( @@ -274,7 +279,7 @@ def _write_callback(connection_id, data_buffer, data_length_pointer): while sent < bytes_to_write: if timeout is None or timeout >= 0: if not util.wait_for_write(base_socket, timeout): - raise socket.error(errno.EAGAIN, 'timed out') + raise socket.error(errno.EAGAIN, "timed out") chunk_sent = base_socket.send(data) sent += chunk_sent @@ -316,6 +321,7 @@ class WrappedSocket(object): Note: _makefile_refs, _drop(), and _reuse() are needed for the garbage collector of PyPy. """ + def __init__(self, socket): self.socket = socket self.context = None @@ -380,7 +386,7 @@ class WrappedSocket(object): # We want data in memory, so load it up. if os.path.isfile(trust_bundle): - with open(trust_bundle, 'rb') as f: + with open(trust_bundle, "rb") as f: trust_bundle = f.read() cert_array = None @@ -394,9 +400,7 @@ class WrappedSocket(object): # created for this connection, shove our CAs into it, tell ST to # ignore everything else it knows, and then ask if it can build a # chain. This is a buuuunch of code. - result = Security.SSLCopyPeerTrust( - self.context, ctypes.byref(trust) - ) + result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust)) _assert_no_error(result) if not trust: raise ssl.SSLError("Failed to copy trust reference") @@ -408,9 +412,7 @@ class WrappedSocket(object): _assert_no_error(result) trust_result = Security.SecTrustResultType() - result = Security.SecTrustEvaluate( - trust, ctypes.byref(trust_result) - ) + result = Security.SecTrustEvaluate(trust, ctypes.byref(trust_result)) _assert_no_error(result) finally: if trust: @@ -422,23 +424,24 @@ class WrappedSocket(object): # Ok, now we can look at what the result was. successes = ( SecurityConst.kSecTrustResultUnspecified, - SecurityConst.kSecTrustResultProceed + SecurityConst.kSecTrustResultProceed, ) if trust_result.value not in successes: raise ssl.SSLError( - "certificate verify failed, error code: %d" % - trust_result.value + "certificate verify failed, error code: %d" % trust_result.value ) - def handshake(self, - server_hostname, - verify, - trust_bundle, - min_version, - max_version, - client_cert, - client_key, - client_key_passphrase): + def handshake( + self, + server_hostname, + verify, + trust_bundle, + min_version, + max_version, + client_cert, + client_key, + client_key_passphrase, + ): """ Actually performs the TLS handshake. This is run automatically by wrapped socket, and shouldn't be needed in user code. @@ -468,7 +471,7 @@ class WrappedSocket(object): # If we have a server hostname, we should set that too. if server_hostname: if not isinstance(server_hostname, bytes): - server_hostname = server_hostname.encode('utf-8') + server_hostname = server_hostname.encode("utf-8") result = Security.SSLSetPeerDomainName( self.context, server_hostname, len(server_hostname) @@ -482,13 +485,7 @@ class WrappedSocket(object): result = Security.SSLSetProtocolVersionMin(self.context, min_version) _assert_no_error(result) - # TLS 1.3 isn't necessarily enabled by the OS - # so we have to detect when we error out and try - # setting TLS 1.3 if it's allowed. kTLSProtocolMaxSupported - # was added in macOS 10.13 along with kTLSProtocol13. result = Security.SSLSetProtocolVersionMax(self.context, max_version) - if result != 0 and max_version == SecurityConst.kTLSProtocolMaxSupported: - result = Security.SSLSetProtocolVersionMax(self.context, SecurityConst.kTLSProtocol12) _assert_no_error(result) # If there's a trust DB, we need to use it. We do that by telling @@ -497,9 +494,7 @@ class WrappedSocket(object): # authing in that case. if not verify or trust_bundle is not None: result = Security.SSLSetSessionOption( - self.context, - SecurityConst.kSSLSessionOptionBreakOnServerAuth, - True + self.context, SecurityConst.kSSLSessionOptionBreakOnServerAuth, True ) _assert_no_error(result) @@ -509,9 +504,7 @@ class WrappedSocket(object): self._client_cert_chain = _load_client_cert_chain( self._keychain, client_cert, client_key ) - result = Security.SSLSetCertificate( - self.context, self._client_cert_chain - ) + result = Security.SSLSetCertificate(self.context, self._client_cert_chain) _assert_no_error(result) while True: @@ -562,7 +555,7 @@ class WrappedSocket(object): # There are some result codes that we want to treat as "not always # errors". Specifically, those are errSSLWouldBlock, # errSSLClosedGraceful, and errSSLClosedNoNotify. - if (result == SecurityConst.errSSLWouldBlock): + if result == SecurityConst.errSSLWouldBlock: # If we didn't process any bytes, then this was just a time out. # However, we can get errSSLWouldBlock in situations when we *did* # read some data, and in those cases we should just read "short" @@ -570,7 +563,10 @@ class WrappedSocket(object): if processed_bytes.value == 0: # Timed out, no data read. raise socket.timeout("recv timed out") - elif result in (SecurityConst.errSSLClosedGraceful, SecurityConst.errSSLClosedNoNotify): + elif result in ( + SecurityConst.errSSLClosedGraceful, + SecurityConst.errSSLClosedNoNotify, + ): # The remote peer has closed this connection. We should do so as # well. Note that we don't actually return here because in # principle this could actually be fired along with return data. @@ -609,7 +605,7 @@ class WrappedSocket(object): def sendall(self, data): total_sent = 0 while total_sent < len(data): - sent = self.send(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) + sent = self.send(data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE]) total_sent += sent def shutdown(self): @@ -656,18 +652,14 @@ class WrappedSocket(object): # instead to just flag to urllib3 that it shouldn't do its own hostname # validation when using SecureTransport. if not binary_form: - raise ValueError( - "SecureTransport only supports dumping binary certs" - ) + raise ValueError("SecureTransport only supports dumping binary certs") trust = Security.SecTrustRef() certdata = None der_bytes = None try: # Grab the trust store. - result = Security.SSLCopyPeerTrust( - self.context, ctypes.byref(trust) - ) + result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust)) _assert_no_error(result) if not trust: # Probably we haven't done the handshake yet. No biggie. @@ -699,22 +691,24 @@ class WrappedSocket(object): def version(self): protocol = Security.SSLProtocol() - result = Security.SSLGetNegotiatedProtocolVersion(self.context, ctypes.byref(protocol)) + result = Security.SSLGetNegotiatedProtocolVersion( + self.context, ctypes.byref(protocol) + ) _assert_no_error(result) if protocol.value == SecurityConst.kTLSProtocol13: - return 'TLSv1.3' + raise ssl.SSLError("SecureTransport does not support TLS 1.3") elif protocol.value == SecurityConst.kTLSProtocol12: - return 'TLSv1.2' + return "TLSv1.2" elif protocol.value == SecurityConst.kTLSProtocol11: - return 'TLSv1.1' + return "TLSv1.1" elif protocol.value == SecurityConst.kTLSProtocol1: - return 'TLSv1' + return "TLSv1" elif protocol.value == SecurityConst.kSSLProtocol3: - return 'SSLv3' + return "SSLv3" elif protocol.value == SecurityConst.kSSLProtocol2: - return 'SSLv2' + return "SSLv2" else: - raise ssl.SSLError('Unknown TLS version: %r' % protocol) + raise ssl.SSLError("Unknown TLS version: %r" % protocol) def _reuse(self): self._makefile_refs += 1 @@ -727,16 +721,21 @@ class WrappedSocket(object): if _fileobject: # Platform-specific: Python 2 + def makefile(self, mode, bufsize=-1): self._makefile_refs += 1 return _fileobject(self, mode, bufsize, close=True) + + else: # Platform-specific: Python 3 + def makefile(self, mode="r", buffering=None, *args, **kwargs): # We disable buffering with SecureTransport because it conflicts with # the buffering that ST does internally (see issue #1153 for more). buffering = 0 return backport_makefile(self, mode, buffering, *args, **kwargs) + WrappedSocket.makefile = makefile @@ -746,6 +745,7 @@ class SecureTransportContext(object): interface of the standard library ``SSLContext`` object to calls into SecureTransport. """ + def __init__(self, protocol): self._min_version, self._max_version = _protocol_to_min_max[protocol] self._options = 0 @@ -812,16 +812,17 @@ class SecureTransportContext(object): def set_ciphers(self, ciphers): # For now, we just require the default cipher string. if ciphers != util.ssl_.DEFAULT_CIPHERS: - raise ValueError( - "SecureTransport doesn't support custom cipher strings" - ) + raise ValueError("SecureTransport doesn't support custom cipher strings") def load_verify_locations(self, cafile=None, capath=None, cadata=None): # OK, we only really support cadata and cafile. if capath is not None: - raise ValueError( - "SecureTransport does not support cert directories" - ) + raise ValueError("SecureTransport does not support cert directories") + + # Raise if cafile does not exist. + if cafile is not None: + with open(cafile): + pass self._trust_bundle = cafile or cadata @@ -830,9 +831,14 @@ class SecureTransportContext(object): self._client_key = keyfile self._client_cert_passphrase = password - def wrap_socket(self, sock, server_side=False, - do_handshake_on_connect=True, suppress_ragged_eofs=True, - server_hostname=None): + def wrap_socket( + self, + sock, + server_side=False, + do_handshake_on_connect=True, + suppress_ragged_eofs=True, + server_hostname=None, + ): # So, what do we do here? Firstly, we assert some properties. This is a # stripped down shim, so there is some functionality we don't support. # See PEP 543 for the real deal. @@ -846,8 +852,13 @@ class SecureTransportContext(object): # Now we can handshake wrapped_socket.handshake( - server_hostname, self._verify, self._trust_bundle, - self._min_version, self._max_version, self._client_cert, - self._client_key, self._client_key_passphrase + server_hostname, + self._verify, + self._trust_bundle, + self._min_version, + self._max_version, + self._client_cert, + self._client_key, + self._client_key_passphrase, ) return wrapped_socket diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/socks.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/socks.py index 636d261..9e97f7a 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/socks.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/contrib/socks.py @@ -42,23 +42,20 @@ except ImportError: import warnings from ..exceptions import DependencyWarning - warnings.warn(( - 'SOCKS support in urllib3 requires the installation of optional ' - 'dependencies: specifically, PySocks. For more information, see ' - 'https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies' + warnings.warn( + ( + "SOCKS support in urllib3 requires the installation of optional " + "dependencies: specifically, PySocks. For more information, see " + "https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies" ), - DependencyWarning + DependencyWarning, ) raise from socket import error as SocketError, timeout as SocketTimeout -from ..connection import ( - HTTPConnection, HTTPSConnection -) -from ..connectionpool import ( - HTTPConnectionPool, HTTPSConnectionPool -) +from ..connection import HTTPConnection, HTTPSConnection +from ..connectionpool import HTTPConnectionPool, HTTPSConnectionPool from ..exceptions import ConnectTimeoutError, NewConnectionError from ..poolmanager import PoolManager from ..util.url import parse_url @@ -73,8 +70,9 @@ class SOCKSConnection(HTTPConnection): """ A plain-text HTTP connection that connects via a SOCKS proxy. """ + def __init__(self, *args, **kwargs): - self._socks_options = kwargs.pop('_socks_options') + self._socks_options = kwargs.pop("_socks_options") super(SOCKSConnection, self).__init__(*args, **kwargs) def _new_conn(self): @@ -83,28 +81,30 @@ class SOCKSConnection(HTTPConnection): """ extra_kw = {} if self.source_address: - extra_kw['source_address'] = self.source_address + extra_kw["source_address"] = self.source_address if self.socket_options: - extra_kw['socket_options'] = self.socket_options + extra_kw["socket_options"] = self.socket_options try: conn = socks.create_connection( (self.host, self.port), - proxy_type=self._socks_options['socks_version'], - proxy_addr=self._socks_options['proxy_host'], - proxy_port=self._socks_options['proxy_port'], - proxy_username=self._socks_options['username'], - proxy_password=self._socks_options['password'], - proxy_rdns=self._socks_options['rdns'], + proxy_type=self._socks_options["socks_version"], + proxy_addr=self._socks_options["proxy_host"], + proxy_port=self._socks_options["proxy_port"], + proxy_username=self._socks_options["username"], + proxy_password=self._socks_options["password"], + proxy_rdns=self._socks_options["rdns"], timeout=self.timeout, **extra_kw ) except SocketTimeout: raise ConnectTimeoutError( - self, "Connection to %s timed out. (connect timeout=%s)" % - (self.host, self.timeout)) + self, + "Connection to %s timed out. (connect timeout=%s)" + % (self.host, self.timeout), + ) except socks.ProxyError as e: # This is fragile as hell, but it seems to be the only way to raise @@ -114,23 +114,22 @@ class SOCKSConnection(HTTPConnection): if isinstance(error, SocketTimeout): raise ConnectTimeoutError( self, - "Connection to %s timed out. (connect timeout=%s)" % - (self.host, self.timeout) + "Connection to %s timed out. (connect timeout=%s)" + % (self.host, self.timeout), ) else: raise NewConnectionError( - self, - "Failed to establish a new connection: %s" % error + self, "Failed to establish a new connection: %s" % error ) else: raise NewConnectionError( - self, - "Failed to establish a new connection: %s" % e + self, "Failed to establish a new connection: %s" % e ) except SocketError as e: # Defensive: PySocks should catch all these. raise NewConnectionError( - self, "Failed to establish a new connection: %s" % e) + self, "Failed to establish a new connection: %s" % e + ) return conn @@ -156,47 +155,53 @@ class SOCKSProxyManager(PoolManager): A version of the urllib3 ProxyManager that routes connections via the defined SOCKS proxy. """ + pool_classes_by_scheme = { - 'http': SOCKSHTTPConnectionPool, - 'https': SOCKSHTTPSConnectionPool, + "http": SOCKSHTTPConnectionPool, + "https": SOCKSHTTPSConnectionPool, } - def __init__(self, proxy_url, username=None, password=None, - num_pools=10, headers=None, **connection_pool_kw): + def __init__( + self, + proxy_url, + username=None, + password=None, + num_pools=10, + headers=None, + **connection_pool_kw + ): parsed = parse_url(proxy_url) if username is None and password is None and parsed.auth is not None: - split = parsed.auth.split(':') + split = parsed.auth.split(":") if len(split) == 2: username, password = split - if parsed.scheme == 'socks5': + if parsed.scheme == "socks5": socks_version = socks.PROXY_TYPE_SOCKS5 rdns = False - elif parsed.scheme == 'socks5h': + elif parsed.scheme == "socks5h": socks_version = socks.PROXY_TYPE_SOCKS5 rdns = True - elif parsed.scheme == 'socks4': + elif parsed.scheme == "socks4": socks_version = socks.PROXY_TYPE_SOCKS4 rdns = False - elif parsed.scheme == 'socks4a': + elif parsed.scheme == "socks4a": socks_version = socks.PROXY_TYPE_SOCKS4 rdns = True else: - raise ValueError( - "Unable to determine SOCKS version from %s" % proxy_url - ) + raise ValueError("Unable to determine SOCKS version from %s" % proxy_url) self.proxy_url = proxy_url socks_options = { - 'socks_version': socks_version, - 'proxy_host': parsed.host, - 'proxy_port': parsed.port, - 'username': username, - 'password': password, - 'rdns': rdns + "socks_version": socks_version, + "proxy_host": parsed.host, + "proxy_port": parsed.port, + "username": username, + "password": password, + "rdns": rdns, } - connection_pool_kw['_socks_options'] = socks_options + connection_pool_kw["_socks_options"] = socks_options super(SOCKSProxyManager, self).__init__( num_pools, headers, **connection_pool_kw diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/exceptions.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/exceptions.py index 7bbaa98..5cc4d8a 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/exceptions.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/exceptions.py @@ -1,7 +1,6 @@ from __future__ import absolute_import -from .packages.six.moves.http_client import ( - IncompleteRead as httplib_IncompleteRead -) +from .packages.six.moves.http_client import IncompleteRead as httplib_IncompleteRead + # Base Exceptions @@ -17,6 +16,7 @@ class HTTPWarning(Warning): class PoolError(HTTPError): "Base exception for errors caused within a pool." + def __init__(self, pool, message): self.pool = pool HTTPError.__init__(self, "%s: %s" % (pool, message)) @@ -28,6 +28,7 @@ class PoolError(HTTPError): class RequestError(PoolError): "Base exception for PoolErrors that have associated URLs." + def __init__(self, pool, url, message): self.url = url PoolError.__init__(self, pool, message) @@ -44,7 +45,10 @@ class SSLError(HTTPError): class ProxyError(HTTPError): "Raised when the connection to a proxy fails." - pass + + def __init__(self, message, error, *args): + super(ProxyError, self).__init__(message, error, *args) + self.original_error = error class DecodeError(HTTPError): @@ -63,6 +67,7 @@ ConnectionError = ProtocolError # Leaf Exceptions + class MaxRetryError(RequestError): """Raised when the maximum number of retries is exceeded. @@ -76,8 +81,7 @@ class MaxRetryError(RequestError): def __init__(self, pool, url, reason=None): self.reason = reason - message = "Max retries exceeded with url: %s (Caused by %r)" % ( - url, reason) + message = "Max retries exceeded with url: %s (Caused by %r)" % (url, reason) RequestError.__init__(self, pool, url, message) @@ -93,6 +97,7 @@ class HostChangedError(RequestError): class TimeoutStateError(HTTPError): """ Raised when passing an invalid state to a timeout """ + pass @@ -102,6 +107,7 @@ class TimeoutError(HTTPError): Catching this error will catch both :exc:`ReadTimeoutErrors <ReadTimeoutError>` and :exc:`ConnectTimeoutErrors <ConnectTimeoutError>`. """ + pass @@ -149,8 +155,8 @@ class LocationParseError(LocationValueError): class ResponseError(HTTPError): "Used as a container for an error reason supplied in a MaxRetryError." - GENERIC_ERROR = 'too many error responses' - SPECIFIC_ERROR = 'too many {status_code} error responses' + GENERIC_ERROR = "too many error responses" + SPECIFIC_ERROR = "too many {status_code} error responses" class SecurityWarning(HTTPWarning): @@ -188,6 +194,21 @@ class DependencyWarning(HTTPWarning): Warned when an attempt is made to import a module with missing optional dependencies. """ + + pass + + +class InvalidProxyConfigurationWarning(HTTPWarning): + """ + Warned when using an HTTPS proxy and an HTTPS URL. Currently + urllib3 doesn't support HTTPS proxies and the proxy will be + contacted via HTTP instead. This warning can be fixed by + changing your HTTPS proxy URL into an HTTP proxy URL. + + If you encounter this warning read this: + https://github.com/urllib3/urllib3/issues/1850 + """ + pass @@ -201,6 +222,7 @@ class BodyNotHttplibCompatible(HTTPError): Body should be httplib.HTTPResponse like (have an fp attribute which returns raw chunks) for read_chunked(). """ + pass @@ -212,12 +234,15 @@ class IncompleteRead(HTTPError, httplib_IncompleteRead): for `partial` to avoid creating large objects on streamed reads. """ + def __init__(self, partial, expected): super(IncompleteRead, self).__init__(partial, expected) def __repr__(self): - return ('IncompleteRead(%i bytes read, ' - '%i more expected)' % (self.partial, self.expected)) + return "IncompleteRead(%i bytes read, %i more expected)" % ( + self.partial, + self.expected, + ) class InvalidHeader(HTTPError): @@ -236,8 +261,9 @@ class ProxySchemeUnknown(AssertionError, ValueError): class HeaderParsingError(HTTPError): "Raised by assert_header_parsing, but we convert it to a log.warning statement." + def __init__(self, defects, unparsed_data): - message = '%s, unparsed data: %r' % (defects or 'Unknown', unparsed_data) + message = "%s, unparsed data: %r" % (defects or "Unknown", unparsed_data) super(HeaderParsingError, self).__init__(message) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/fields.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/fields.py index 6a9a5a7..8715b22 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/fields.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/fields.py @@ -6,7 +6,7 @@ import re from .packages import six -def guess_content_type(filename, default='application/octet-stream'): +def guess_content_type(filename, default="application/octet-stream"): """ Guess the "Content-Type" of a file. @@ -41,22 +41,22 @@ def format_header_param_rfc2231(name, value): if not any(ch in value for ch in '"\\\r\n'): result = u'%s="%s"' % (name, value) try: - result.encode('ascii') + result.encode("ascii") except (UnicodeEncodeError, UnicodeDecodeError): pass else: return result - if not six.PY3: # Python 2: - value = value.encode('utf-8') + if six.PY2: # Python 2: + value = value.encode("utf-8") # encode_rfc2231 accepts an encoded string and returns an ascii-encoded # string in Python 2 but accepts and returns unicode strings in Python 3 - value = email.utils.encode_rfc2231(value, 'utf-8') - value = '%s*=%s' % (name, value) + value = email.utils.encode_rfc2231(value, "utf-8") + value = "%s*=%s" % (name, value) - if not six.PY3: # Python 2: - value = value.decode('utf-8') + if six.PY2: # Python 2: + value = value.decode("utf-8") return value @@ -69,23 +69,21 @@ _HTML5_REPLACEMENTS = { } # All control characters from 0x00 to 0x1F *except* 0x1B. -_HTML5_REPLACEMENTS.update({ - six.unichr(cc): u"%{:02X}".format(cc) - for cc - in range(0x00, 0x1F+1) - if cc not in (0x1B,) -}) +_HTML5_REPLACEMENTS.update( + { + six.unichr(cc): u"%{:02X}".format(cc) + for cc in range(0x00, 0x1F + 1) + if cc not in (0x1B,) + } +) def _replace_multiple(value, needles_and_replacements): - def replacer(match): return needles_and_replacements[match.group(0)] pattern = re.compile( - r"|".join([ - re.escape(needle) for needle in needles_and_replacements.keys() - ]) + r"|".join([re.escape(needle) for needle in needles_and_replacements.keys()]) ) result = pattern.sub(replacer, value) @@ -140,13 +138,15 @@ class RequestField(object): An optional callable that is used to encode and format the headers. By default, this is :func:`format_header_param_html5`. """ + def __init__( - self, - name, - data, - filename=None, - headers=None, - header_formatter=format_header_param_html5): + self, + name, + data, + filename=None, + headers=None, + header_formatter=format_header_param_html5, + ): self._name = name self._filename = filename self.data = data @@ -156,11 +156,7 @@ class RequestField(object): self.header_formatter = header_formatter @classmethod - def from_tuples( - cls, - fieldname, - value, - header_formatter=format_header_param_html5): + def from_tuples(cls, fieldname, value, header_formatter=format_header_param_html5): """ A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters. @@ -189,7 +185,8 @@ class RequestField(object): data = value request_param = cls( - fieldname, data, filename=filename, header_formatter=header_formatter) + fieldname, data, filename=filename, header_formatter=header_formatter + ) request_param.make_multipart(content_type=content_type) return request_param @@ -227,7 +224,7 @@ class RequestField(object): if value is not None: parts.append(self._render_part(name, value)) - return u'; '.join(parts) + return u"; ".join(parts) def render_headers(self): """ @@ -235,21 +232,22 @@ class RequestField(object): """ lines = [] - sort_keys = ['Content-Disposition', 'Content-Type', 'Content-Location'] + sort_keys = ["Content-Disposition", "Content-Type", "Content-Location"] for sort_key in sort_keys: if self.headers.get(sort_key, False): - lines.append(u'%s: %s' % (sort_key, self.headers[sort_key])) + lines.append(u"%s: %s" % (sort_key, self.headers[sort_key])) for header_name, header_value in self.headers.items(): if header_name not in sort_keys: if header_value: - lines.append(u'%s: %s' % (header_name, header_value)) + lines.append(u"%s: %s" % (header_name, header_value)) - lines.append(u'\r\n') - return u'\r\n'.join(lines) + lines.append(u"\r\n") + return u"\r\n".join(lines) - def make_multipart(self, content_disposition=None, content_type=None, - content_location=None): + def make_multipart( + self, content_disposition=None, content_type=None, content_location=None + ): """ Makes this request field into a multipart request field. @@ -262,11 +260,14 @@ class RequestField(object): The 'Content-Location' of the request body. """ - self.headers['Content-Disposition'] = content_disposition or u'form-data' - self.headers['Content-Disposition'] += u'; '.join([ - u'', self._render_parts( - ((u'name', self._name), (u'filename', self._filename)) - ) - ]) - self.headers['Content-Type'] = content_type - self.headers['Content-Location'] = content_location + self.headers["Content-Disposition"] = content_disposition or u"form-data" + self.headers["Content-Disposition"] += u"; ".join( + [ + u"", + self._render_parts( + ((u"name", self._name), (u"filename", self._filename)) + ), + ] + ) + self.headers["Content-Type"] = content_type + self.headers["Content-Location"] = content_location diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/filepost.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/filepost.py index 78f1e19..b7b0099 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/filepost.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/filepost.py @@ -9,7 +9,7 @@ from .packages import six from .packages.six import b from .fields import RequestField -writer = codecs.lookup('utf-8')[3] +writer = codecs.lookup("utf-8")[3] def choose_boundary(): @@ -17,8 +17,8 @@ def choose_boundary(): Our embarrassingly-simple replacement for mimetools.choose_boundary. """ boundary = binascii.hexlify(os.urandom(16)) - if six.PY3: - boundary = boundary.decode('ascii') + if not six.PY2: + boundary = boundary.decode("ascii") return boundary @@ -76,7 +76,7 @@ def encode_multipart_formdata(fields, boundary=None): boundary = choose_boundary() for field in iter_field_objects(fields): - body.write(b('--%s\r\n' % (boundary))) + body.write(b("--%s\r\n" % (boundary))) writer(body).write(field.render_headers()) data = field.data @@ -89,10 +89,10 @@ def encode_multipart_formdata(fields, boundary=None): else: body.write(data) - body.write(b'\r\n') + body.write(b"\r\n") - body.write(b('--%s--\r\n' % (boundary))) + body.write(b("--%s--\r\n" % (boundary))) - content_type = str('multipart/form-data; boundary=%s' % boundary) + content_type = str("multipart/form-data; boundary=%s" % boundary) return body.getvalue(), content_type diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/__init__.py index 170e974..fce4caa 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/__init__.py @@ -2,4 +2,4 @@ from __future__ import absolute_import from . import ssl_match_hostname -__all__ = ('ssl_match_hostname', ) +__all__ = ("ssl_match_hostname",) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-38.pyc index 67a4aa1a652c9b75a69bb315cb77fd0df4919688..2742d60ad547dc272e9f1d2ec5ae12deca36ffda 100644 GIT binary patch delta 92 zcmbQlw4I4Jl$V!_0SGkz?TXKt$h+J*TR$T|H&wr=va~cSQ@^+<SwAH)FEceKIlrhR uwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*k^B?kbPgCP$9 delta 55 zcmdnaG>M5fl$V!_0SKO#ZHUXA$h%z5O}`|!K))cfKsPh5xFj(rN7pFBq_n~~KM^E2 H@w)>6&cG6! diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-38.pyc index fb74ae093e5d39c5d1e347fc1ebe22b9e515ad03..33242ecf701c1992eb17c538c63b390013628cc2 100644 GIT binary patch delta 8472 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 KUGiWu^#27648nu} delta 6494 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-38.pyc index 04cbd7aa84b7e8a5779de9c0e0a59f1a418b5e8e..4965668282f72b63d414d83cff325b08cb5ff885 100644 GIT binary patch delta 91 zcmZ3@c!7~8l$V!_0SGkz?TVksW9?k3pOK%Ns$W!DTAG!qUtE-|pOToDnVOTFUsRG> ttXEN4rC*ksSEiqnnWSG(S(1^TXRK$TUz}Nzs#}nloSm4ST0Ak;4FG4AAP4{e delta 54 zcmcb>xSEkCl$V!_0SKO#ZHSx5V=Wh;Uy@s(Uyxa#o0(T!l9-dDYm{M9T49`@2ojvw G<puz?p%Ih- diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-38.pyc index b724c9af2010d383f528d993c57b169051e933c0..4e45dca2a5426f3b1dddf9fb154366cef3711c3f 100644 GIT binary patch delta 130 zcmey(xqyo|l$V!_0SGkz?TYW($a{m?xl}(RKQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+H_-GBb-emjlRHHX%kn Y#>p`({UQQD9t%4M6AueW91Q*g0OpS*Y5)KL delta 93 zcmZ3$^_!D7l$V!_0SKO#ZHU{jk@p6(T!4N_Zh?M5W`S;IUU5lcPL8fohDm9Kaeg95 paIyxAH=heg2dfYx6C=le7Us#dEd2sJKoJ&p4kjLE21X$BKL7<m7d`+0 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py index 740db37..a3156a6 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py @@ -11,15 +11,14 @@ import io from socket import SocketIO -def backport_makefile(self, mode="r", buffering=None, encoding=None, - errors=None, newline=None): +def backport_makefile( + self, mode="r", buffering=None, encoding=None, errors=None, newline=None +): """ Backport of ``socket.makefile`` from Python 3.5. """ if not set(mode) <= {"r", "w", "b"}: - raise ValueError( - "invalid mode %r (only r, w, b allowed)" % (mode,) - ) + raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,)) writing = "w" in mode reading = "r" in mode or not writing assert reading or writing diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__init__.py deleted file mode 100644 index 371c6dd..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__init__.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -An implementation of semantics and validations described in RFC 3986. - -See http://rfc3986.readthedocs.io/ for detailed documentation. - -:copyright: (c) 2014 Rackspace -:license: Apache v2.0, see LICENSE for details -""" - -from .api import iri_reference -from .api import IRIReference -from .api import is_valid_uri -from .api import normalize_uri -from .api import uri_reference -from .api import URIReference -from .api import urlparse -from .parseresult import ParseResult - -__title__ = 'rfc3986' -__author__ = 'Ian Stapleton Cordasco' -__author_email__ = 'graffatcolmingov@gmail.com' -__license__ = 'Apache v2.0' -__copyright__ = 'Copyright 2014 Rackspace' -__version__ = '1.3.2' - -__all__ = ( - 'ParseResult', - 'URIReference', - 'IRIReference', - 'is_valid_uri', - 'normalize_uri', - 'uri_reference', - 'iri_reference', - 'urlparse', - '__title__', - '__author__', - '__author_email__', - '__license__', - '__copyright__', - '__version__', -) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/__init__.cpython-38.pyc deleted file mode 100644 index 2357f499dbc85f052a7f4306c9330fbd772c5b15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1008 zcmZva&uiN-6vv(4i5;hDVPo_#bX;Jy+oY5&jL{N02#hikdeLD*wUk8Ewu~f))#v>) zyX~*pA=e$o{)L_P<hCIlv+$SCdqUFFSMS>QT?f8j>+hcrn~w9-2D@Jsf^+!wR}ki4 zhgDcLt|V1ltyr!B*Kn=mI&dA=OKt!+aHHfVa1%F6ZUMJ&tK>Ft8@EgD#GS;&F0hL| z=HV{uVxRfA$9i~=?cqM_<9)V2cLoQ=5BDNPBFSQ&@YGNvWQybhX`ay3h)5%vGPI_# zVC9@fjO$2=8_tkO(d@$njo!XF3tV^3Ia(Q$jl)naqB5yCWoE^hjC3Gmh!#@8azjN7 zt09|jkA(H(NM?6RELUcXUPS{mJU%%^GaB9Mj7HoY$0FjX=3{gL@rtAMFgSh<b#nA^ zI=Q@>U+!$L-QN|kcu?8+LJ6Yyf-9az91`8>Y&zSGg(l_oNUnrkkV=)nbqoHOfc(=P zuAlDE&Q+XIrS0zCCkr#K^Vn=!4?Yynr!+-#L&0PN_D-Z?R7bKnTq?R)P!q{G5$RH{ z&zA|96GSp8yq#+nFD8%P{9{YeI0;6<aL`j7xUXtisadI8X;^_qbd>Ep)dtyg2r<IM zoRE!62+hq(D&YQ>;o(IL8IO<$%OUUy**?$x+?p#5y+X*<;9%1t1fCNnYBUq~hyAaL zvb?eiuQW`RKHZn@*$TT>d@DUGdsg}&_5d0~Ro@)-%qFe;xe85^g_+2XM5+zU9}QQh z`InKTHd+2;%~K{-2u~D?n^6d@b4!<8KelK{h)9JYB*^YI?RSY}dCcG2BlSy=dZ$}? LGOG2;c2xfY<T@I# diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/_mixin.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/_mixin.cpython-38.pyc deleted file mode 100644 index 0ef2cda7878b0e620d5f3e77d1d77e5c320d8890..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10609 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 SfEFbnfEZAiIbZ^R`u_mR_ZU|I diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/abnf_regexp.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/abnf_regexp.cpython-38.pyc deleted file mode 100644 index 63392ef2bf6c01e70ac4077a5a48c3785e49b048..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4112 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/api.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/api.cpython-38.pyc deleted file mode 100644 index 599bfc54a880e3f8de806b5b297a26565c9c6af1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3673 zcmc&%O>Y}T7~Zwh#PLU)LR&yw=0+?LTcQYxg%DLyr3g_){Wy?A?eWeyo_4=FGn<eq zaN-KTA?4N^zsJ`e5PzX3o_E%}UZ)?VYO1ca>)H8uKc9K#-Fux*)5G=8{@?fe7d-D7 zy;QF{UcSd|?&Bf6T~GL;7Wz?bx8_s39@e9k-4)kf3C~5VyQ^ql6suzGcYk+Hd>|TP z9j%7=P&7pgt#xrpv_%K4rnoH5iwkJA#Ks-3d*$(8&7TsHg^~qHY`Kb6yvOWRGNYmt zy*w6dlEr~lNz6lbeP^3Z63z4^xcbetuX@eq-KjDx%0&n{QL!}T0^^paI@wnO-8=}S zG0Y}TL7I(26)<kCR^!Y{(<EI%$c@3=WU|olua7`<{aJha_V#T#ky^%q#CvOpYa?$< zlZBRs?^TAMpUdoI>snC5(&D1_3ho=YO&bsE9s5V#k^iKIQ22ZdJx(O!46>MkWr&7~ zVX^BemBVj_%lQuXIR$TD#)=Fpz3;J~lMEwSDB${3$$gnemPe9F_&PphnSll;Yc#5w z-<#+p8s-LUW?FSeqq)vO$~BM3HirHIY>>{_gQ*IpES6HZ2#+PhL?cCEzAggSbLuK$ zV00p2MlP#(qYOA4<UyDxQRIuYw3&|0fL$-N!1(!)Jxt|*4O}7zOHPg4jBZU+5@xN6 zi%)B_I=q=R3hhrlO`GKTcHc&6KUL|LijC!Axb?;K%j}n{38zkX4-t5g=zgZdP>rwl zQyx6zd(!mh813^^_0q#x2MUH|6h0*kIB>KyLE(*n5>$W!OfCZ@W>uKJ6QnFDsDyD- zy#gud&$CO`zGtMsgqI?v>Qspo%8*{gqYH$<3%yPq1daUBLTlE+z#_9<bQPIBkM>e# z>*yf#{YaB8;jy5A2epZJRQuC+RPYQFe~?z{2!zH|z7>cQ_7vd8u;=%AsKgs*H#6A! z3j0dC7>q_spmaOEr_9g^-^8Y8Nip%Y?6ACs=;|cjXvdQO!y#A*-f+sfmGF*8?(LW& zXRC3NgiOmvnbLA-f~kx^5qG4evtTs3t1}5#5#>V==7BO(>Yq<15^{EsEh*e^99xi+ z69tZq(j=C#U9xydDbMUQ(aIj4iQZD$X;i1&PR~Ru2|A6!N14=T<EN8!8kG~x_aY?V zO#Cc_y`Z=}cB+`6LyC50u_r$VqHglg5Tp{?X#kX*14HMB6CuN4s#|wwkz<%yqu6-p zZGaja*UVNQ9&o*9PI6AWm^{P|{+igt9VS=wMYLZ^IX7t1$9OC#=eYL7`?YpdJFY+R z9PPw7SZ*ac0=GQQi-nwT;NLr;nz+!l+3jVqNke7dgmqrEoX%>=3wEp!2x7IUSaP;0 zWt<7!lnA*CR4hajK$anZ`YA`iN(BMy<%-$bJRD0{xKxgd#d&iQ8J%(xL1TxqPA87n z-thHh{4arnKywba1IGp$)_dSeQmXm?r~?#rKB!b1B^+F3oqNkTb5(0z2)}?6FtAl9 z-L*_Z9)NjcyQu9@a&s*h3Mb9=;b#UlW$5b0MHQQuy01^7Tk@6(Eb?>e((<?BBgAQ+ zA8<R1PlCLNxQQ==RVt(di^>zndR|ZHHENwGBpQYHBMjynx~V@x`&QT2l&07IwP$O? zp-6(^P<Jp_Q*LLiigCGiM=gX1S9fYEQ5<PFa5!xhvz&ph$Z33=e`I}!Pe#uWR94p7 OK7RG)dHg<UZu|#UEH~5u diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/builder.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/builder.cpython-38.pyc deleted file mode 100644 index 30929b6a2305415449e2d01341d648270796e439..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8115 zcmd5>&2JmW72gkjtf<dea-29tunmxqY%S8YWWiM<!AVf0K12-?J3!eFV#ygwD=oR~ z>{6~M3Mgt{dI);xwFmi_TTlHzdS#CVS_JtElta|to8fYo6cx)2Yjg?D%<j(4&b;?~ zzxU?tqxt!qhU4FdfBlX7wx<1)PLf9oC-?CW-bKN*ipF$iczV;Q7&^60w9Ses+bOhD zm6Wc1sIfH5Jk?l+r=OUW49kA16|L^ZM?UL#+^+kr&~aOCYu66<xb6A7ZryJ9LY_VP z<iYzL*JE7Rer=!E!_t>JUR~7tnY!O>J0V)LEnhSp&+T#%;MD90w~js|M;2%I@elS< zaIK<a@&?l@CVQQkEcH~cq|_uUX_jTyQw`IcVL8-UHp}KvTWp>!pq^oiYzcLay~3`c zo@L8y1@#=e&R#`5&u*~SP%kh8%e>jo#Y=GJG54R#W!Rx_J1(=`mR+Ou(ds*G+p*Ex z{)9KU;H^5h8^UkeZAXMbDVMWxluCBX5BcV%I;Bew_uOD096Q+aJ07!Z90LcT(+XWD z<TyW)!t4ZG+`{`p+YR%9EjUEj<SoXT9GeCU_Z+%wV@SNmZVUg=#eMs+8}8YT*zKS{ zCSyOq@Z4dyY>X+#b`Blab7~$R4%Ou0p3i8ZZNJ^|FcI0Y;c|~f%h{=0&_{Go+ra+= z{DTsTp5D`{TF*eK_e_*VFNM<VrBSAO8I<W>7G;L%5Vqm`9s+*Qa<OcJgY9>O6sQz2 z7Xum6IyWIyr)dYFu!H&@Z}QFIyy<qqZ-=hma=ha3a^eY+quXluFY?TuAB0!!@3tU$ zUtGCAtpcX7ch&K!|8F~79KFZ`4dLvP@}K+6&KKE!MhUfVMWX7bNC5p5Eej<k+fU0W z^sQ*%qSa3Y+-nH3RY6z~GgJ^GiCHS<sF+9bg(enJef?26Y_`j7x4kOi?s=<s_SQSU zTk{>dDF4+%0NfYlj_^FUwpMOC^#f;@2W8Qyul@MmMmfSp`>1bKtKgxqTD38Fuz*5a z&gk*4yByncDe7A%K8g-PuZh1z@DdtKKhb;ozSh&2@i}4C?B4!Z85N8j)Q9Q0kg9#? z^2fH{kdPfrDPp|tALG{+lwh}xYbDh>ktQhNNEah{<1z`HE>VqBl02PKO{Y+SJVlLD zsS7%n4P1z{Lf4}9NfGp_*NA+<&rOi8AxKJ<8FdO=Nxi6omQNxTye+ELpWrMY_n{dn zb4-w`N1cQh9n>c6OF`a3Bh*eI$Y&5|Xb>&zgAVpV2K%6beGtJuXkg!B`sd_a4Cl|# z%6p7K#!5^?L&OGSqK#Sfy+#Nh6L}KQ@hz|wSn#pydG;=EaX|#;*e$3jR>y#5!PG>M zL#`k{7PNWY1=+D^22Kmp!C*e_3fl=o;ev{JAXzbRnmj>Ip!vGb_-f7b>j#^gcKZli z+KOjO9JRf@otR0XSaKMvs?`?qKYRG_<4^N3d(i{&v?CPd_rkCp<P#9u@mqWV9o3Yu zk<H=iXsqavFj74ggj731%od#%<9Uk=R9T!6CaV5YByB#Jwn*dhw_E-Iaf%~|0}@!v z#R7OAcY+lZ+I&to@Jq$Nv+ng+5(%NzX;RTaNFCzuGo18vrXN^hDTE<E(f^=_`YCV- zJeobk5eGA3otdX*&&2gq&v>RkGfvD<VUv(5(TREn{~Z3aEG3becD@=QwJtaV5x{c= zwxd818MCxqxFg~Rf)=Jf4Xh;ISjY?C4*`UHu!hSae=c;Co}(FV$>%qthm#1J3>zXN zHN*=dh=4Z{`IA<o&=+Bq>R9uU4NO`H1R>c|-kZ(>qDky@Z#+Wy(1N|&b*Du^7NRwJ zQ8#^jvUz->Ok}Q~`^@n={HH?rLYd38*jz~LG=f+LGW&@eZ6^pG`+_M;l8*E;A6iUF z?p7|E2J2hHr={~9v#v$5u7r>)cy;g=3T@ufEj?#gFfl{7zDcFY+!7{t*1Z{vT^d|s zn9EtefT2S;&V6EgBQ#-Gus5_PGd?yTlJQA#Qo3OLDH;n6TgdPF{;tPMh?`&3Kora* zs*<DJnhv^#qeKKNnKTZhB;PK?0HS$J3alb}m7o~|fJFeH2aief*GTg@rDf8*{GE+B z_Nf1eifJZ8V*M3Ppkn=requ-()x?`2c9fu2P$<zXu9^oav5u>$_-Z)f{8?Jv0W^j* z%QBK)v(8@zupmE1LBJFtK|>bq-F}{v9V3_o5L8oo*!;cQ`Ae`sftu=h6%R{1Gm#(V zY}eP<rZZg(G@bc=NjU1>rP;yn2`;yt2$THBh@7A=kYkJQI-z^WOZG4PPP`>OK5@^_ z@$B}uJ?ml5if9Yl+Lpa>_wL%=3xjlxh;ws&6FV<)0~3<Onjq15H!`{rDVmZ*r73|w zu?XxS!V5t#Spwbs6NU~bn$;GFGbK-+8|SICY#YWmXlEnl99Y#wo1&3MY-%J}rp!!F zKgG`DnI5dbmg2B^ENBk1r`CW{Wmv*YX)`J3AH(38ob$A;216F|fxFvu4qed+?yL{C zVt2m-r6w#%Hivu|xm~Jdq>(RAc=ZMx{&zDjxu`NS3H1ZN6PDV0?U%Hgkyl=A6<_P+ zu33&yKikhCQv~ay9n9spm%H$BH$oDPcjb}ukR~$8c~JMikqNviO(2J$Ap&~}<^UHm z0ql5Y1neUY<PHX+ondGo_6Fb)j~n5IT_GI93?-5FbHn}NzX0(Mhr2r3naRzf1cB|? z%&p7(k2tcCi1gebl(BcG?eQpeMTq*Zw`uY{Rm$!aj`L1_)6UoIdj4c8-25B^NV<}| zvsL?H9pJxgzebCk=uHv}_+<erz|MhIQ2h1(-4awpG^=9h#W)0#D-cAT{TU>OkZ#3> zdm`n>2`I`v4Jf}dt3=?2ycsAP7=!!*v3@M4zvEf8C0$rbz+OhmXWiGwBINkF5%7;N z{b+y;cn_nZFmsw6FngR5S&CU*@Ku$ufsd7MqC}`nz)v+ml0yR>TeWxUTkNF};yAkH zi!aCbCE@beo{1<&<f)JVP)V<eI-eQp{3}v-GDub-GFa}cyD~}H7xYZ9`+!EdT+h&X zCi3D#YFilUIkM_0d+=yjcyWA?L0)3@PHCg`qnEB<rR!)mTNh?C3<9pEWtm+jRVO#p z(ddzHBLIwtcXOols3RiMNqUEWJHyU@_%%yzgQI6gQpnJrM&YJZ{V?+x?SK=z--ao7 z!<O`J@NLi1$b9O~HaOw~!Bw^rFC6=rlt_Y3BZm~_8&x7v<sb)JWrP!*n%pW66`_1) zi7H$5rI27^G`Nv3mKrX;z~DO$a+{r2(DvN0FzQ}Z{&KTi-W|Sda(EYKAnDZ;J=*_t zC4`Vf(xWg@A|pXDc~m5aRt3NBy^tu9;q9gx;qCR?-u<hKs5mPq{n?*OqDN(1rFksJ zPSoijFD=~g=s8(iU2T)bJfsyVcp0EqWVxtla^c)CCu9_&{>AK$I*N<*g@MvN)oMRi ztv2N+Wwht2aJ`N<xRb3`nP11Jh*z*KL3v?8A*lEs6>n1U78UPMQKaGrRFLtBG8OT> zWsAOS$VlNj8i9=hw4T$*ay9Kd_lA|VUbDV$typ>M4eKWA71?{Im=$a2(br_yAtMqc d>5Tfet)h<!FY8<Hs+Dci&4B13rO(mN{14C19i;#O diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/compat.cpython-38.pyc deleted file mode 100644 index c6e32c1724f739c3f3656a87bfa986ace71f1f99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1110 zcmb_bL2uJA6t<JJNxQZyV_bHaEN&HAJGE#U(u9zv9gq;3gb*wTsx)@jtf?JrXIiIn z8V7y`aO1Y0!Ef-D1L|MciRXk)<&G;qe|euj>%GtJ+h((lVEn$k{jjVc^viy%j{rVi zz*IjWP!uAHsgvRmU$+6dsWWp!52JU86A!V<v@VY@vcH0@mh2hg&U;iSJW%+d|Br&- zE4;K?vZaDn!hlv8zNmS~MN=%kP=AWJ=fL@4od#>ncUrq=HdtNWvPRgXn{<OVKI5=O z+q6krfHtY~26Y}>?;nd<7U^V^q=}xBnV@;f$XG~nI@c4yNuNZVk^xb9mI<l5OXwfH z?qE~-m<!DS)N+|J9t+Ako(Z%Vj^>&vQw5~7Gy%}XR_TJW<1FnWaf!V(>;PU?i@dB^ zY(2lL<a)e!7+Z2REVhRn!&HwUXtV&IZydR+@d9b*#!<Tq^wnM9Z}<~%(5Z91f5KHR z8PStSlMzW2(d<f-ghPfAm9aP(CybJ!m4u&nO_j30UHOwpMH-r^Co17eM?7Z6&v{~b z*@O~0j=>`nti(T%d<faQS3Nz;dRda~6|ywl>rbBMR|65*WHE=Aj8h?dU{jim2E8nb zr_ni6JvojC&khfIadAW4Y%bwpq9-twbqP7!xQ>h5e{knu-5q7!i3Pu8QiCH}km5?o zSc+NU)~ZeLXm#_l1trN%2&Pi(mX82iTa?_gl=Y(w+ZNfI@55a0#pXI#HrAH5@rOey z;^EM^YOYM9w5gj#QZZ>?g0yCsjh8d~JWr$)(p1Y$#e=i@C{01%fOb?O_%PvPVcgTR zfen2)S4-KpCs}`s!q$o{%C;4o;Hdm}Jhx3M0>Q(9<KQ-K;jR1C^LOx$>tWBW`+oqN CqX`}W diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/exceptions.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/exceptions.cpython-38.pyc deleted file mode 100644 index 8c74ddaf8353d09435aafd2df9153f8f89e231b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4749 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 Rvo(XC+q&Gk)S7Qy{vRF>R<-~D diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/iri.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/iri.cpython-38.pyc deleted file mode 100644 index bcd65871a289694660e8434e773b97b63c6fa63a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4464 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 Ky8SA5j{gH~(28mR diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/misc.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/misc.cpython-38.pyc deleted file mode 100644 index aa065636f8c4be354e105b731d1fbca43bf31516..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2229 zcmZuz-E!MR6xN?@#eey8;sy#B>d+Y4IBh}-ola8MQ5rF^9AvpO6(t(QySA0uvRT<7 zbrWuYx8S0=<c{~?4Rp%|lSd#krJUW^s#B2Wtk3z*w`b3uJ*%XeNJKe!{yO@7|DQ>Y z`;!{uj||2`5bsBx;}B<Zh(|(;H+du?sU@^UQ{*`mLSYm^GMZ?FObLsJA&@Xg1Vjdz zK+#`AW)!rTNqupXdJ|?6#z~Vhrp#%~znTGU_KY`ER7bH_b70Sdq(QEoiQrjao;cX= zr8$&HbAY`cVAlie1BTJ~9|AVXcpour3b4#Po%b=d!TJRB8$&${`XXL5KV{r$mch+4 z9?&I*P<{?13-VcAWN|)co>@R{q0j;czqcs^DwO&~Sm1`N<>3mmm_N*)3FZo$b-Bko zz`qLudmMUK(HxrpnKRe$7e8_4Iua^eE<N}oTI!&F3ukH_w`V)9<2FETcbyhS8G;-A zmQ6DFxJ$6-IUU!_*e;@6uV=eGZ#fz@nvR!gUy0#moOZWEDB~^lR;FwBdYHK0tznF- zi$up4sdos_iAS@c3m(}m2iZMpR(16<iCz;sgyq_CG0WwgwwZPgZN=qyKV~1ebqlrt zf&H*oYvMNcC+vQ&*&$Bvg)c!qO+WN~ACnipTqky;4PkO2f2M(5Oq`m9aLZ{skhA9} zz5c<tJx#Fn4m8zwp-7k<VPw^ski4G&(pzw_zQ442e`#~?K_6I-TkmYVTsh4>%xzMv z+3|WCFYlb@?lY5?Z{y|N)7)nEg5SU3vjcJe*|!7n*>~B24BDbcwa`99$PT9W7rmut zn~NTVx<SY6APLa@0L`Aifu|<W`V1clenpTXh_?g733muL@wrT{gT{k4L9Qd=gimu7 z=IcWDoeC$yD**{-{Hb^%ApS(8-H3!VcgaIM^prGMEn(8Y89Q@edzc>BO^+UaGxLK3 zgAHxfg0nmtcP(odeBS4BA_+q-Bm{#WB6Y__Imwr49IH<pTG7j?7LCWaeh5hT_&1KE zVbaCd`Chx5?>gPv4(-ua>-OE|TK{;pV^ffcb%b5iA^AROwVZ?1eAli$w;R~YlX`9S zt1s8{ZO5xEcVGCiHr)qX$|DfmV;?pl#mhpJkMd*zu-rXAVp*tDvn*dAn9Kl1Xkq;% zY}_iAOM7Ka(Ts{e^H|XoT`gK$%C1^c4Mnf`$x8LnxIKN<wsggxs%pAYQS>LumQ~y- zz@)?&0)$j>*;w1zHP*26|6R?hD26}t&I$~>x&Y%PuVQ{`Y*Cg5W6f%1&Dtv(mZBBQ zTaY0QH~9|eM}{91T9RFB5B8vHkLliGv_z$XQQT2<KMa??ZTA3#-KyGlnKI%#<%$7Q z3@Df8NA}9PLE#kaqEIz<%DQSi4I)GsIhZvH98vd<)>ts6jNm!2)~&+UmTp@5c5!WG z<=%+29)wJclN3MAObt>SP8bD?K#DtTI#Wil{7qHSpHe(=sf`>{+j`+~3Hl;fX`%vE zC@GYi9I63XS9S}A`b43%WBZQ<(`hjRx2|jl@#cfp8<o%6Qi}#uR8{mKP^$2#Qr@i^ ziZy-|k*cQB^Ymlt*a5}W@sp9&QMKpP|2qwKJN$6x;1Jj7p?X+3c0BqCXBTyBxJGY_ z{NVC$$Oin&z<Dhgq=+oUrKBkFlECEea6HVzD}o4dz=St~1Rh?x2v4MVc)=sR35Vhl f@QO16SoD1@N5Z@eTKu&fow_nl2ul}IRF3`&Uk!|j diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/normalizers.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/normalizers.cpython-38.pyc deleted file mode 100644 index efac6db274de215c45f86172f7aee55d398dd2c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3542 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 L@0BdS?5}(eWOsWk diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/parseresult.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/parseresult.cpython-38.pyc deleted file mode 100644 index 47da6734216defe961e5f57ff1a90e02b387e2f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9856 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/uri.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/uri.cpython-38.pyc deleted file mode 100644 index 8e2f6233ef8c43a3e1bcad523cac1e64e0fca97c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4237 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/validators.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/__pycache__/validators.cpython-38.pyc deleted file mode 100644 index 2e14f570f2b14a03f6341c126b820373753c2ea0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12997 zcmd^F$!{E2datd!i>>A&YWG^B(O7JoZc3J7dpMTHv?N+eEJ`6M*+Y+~S?pINOYH7y zy{gvI(?kZLkr+W11UUo&27z?QK?o2`E;;6uOMv_Zb;%(C0^I`SG)5rh_q|tZv+0rI zu_r*-?ANut_4|GMdpAZ$%L@Mf<IXRB^2*za@^5sL{VU++eSH0YLBW(2g{e$ysx56r zQ|VgAwZ5W@YXjHDilHhWDy+bYpDV2B6n6BLA}cZTb7iH(MpzlYCfmm<_#I)RYz)6; zc9QL9lb@?A``8pazz*W7!m8{LJB+JQ_BuPlj^b*Jy}^#L7jQMsrrC?^C0tFgm)R@m zW4|-%j5*`Z1bg-8#>%8~fLZK2?D&Shqploe-(@FI=MeiIdkw#b+4z!DeY1Dws>ixb z$7*=(z;@eid&3Gg9qW$WbeSEvUfXJV8*al|_qfH^8)v@%?%TD;D(FyE!?JU);dH2y zk2|B~`VIW<YkRzf<~@h|4OGninYeo&U%!pQQC3u@tY}PK(H(<nOlJlWjYzdo!lVlk zv5FC~N)fS4HqIunh!H_DA|4S;0qKZb3J6EUQb0B$l>(x@h{e7Xj@*>X^0@tHx}scL zyX7<jtLr<=3Opjgy1UWkxz&5?mfdVxo~Y_uZabkuxoqLDR<rJ4p`d}yn8Rjgt<$wr z^3|n#cB=!@c71!pnVppnsf~61{CR7gd#$)H%WZW$9$0qAosLQGabFCOH0W~II!9G% zxT<q!-QiBV;Y^*}41$h7J2SK42AkcrTElD2oUG>CMsNbdbD92Y2|1>!HSXN*y4<OE zxZ_j5b#Hwt?WBfv;_sy2*mPRX$!Y84rsoIr+p&YqlhgT{)f#B#-L1>o{*ZoX&Y~BZ z`(Djyh+&OSzx7V-6h5b^hji7ux=ANR1W#yCi>{n05ORP}Zd<&pOJc_iKR|G|Wp_aD zmhCoc8=kk(bcpDC(mWk6(|cyzWo|c|HM_B8O|`IMi#rXc9as(GyQb|2)!B3*z#+Yf zr<aOh?W*hhkl_m+7^;n4E^+ShS!+tbWZkuW^e%8_)>=16yMpXeI}r57;+4gOw<Lh) zx+iJLcxiWoO^>_5eLNameuf8#C(bQk0@K#*uEXy~*X!KgXkk*~wmNNnDw*fAsuYc| zD2EG8NF;aL>t1LO3xoy<2TJrB7DR`k8TZv7T@?S(HEEa&`1%)71j>%mSL$l?t3|&$ zQ}L8EPWGe!yo9HPzH+PZp!ks5m6!p&QRsd5O4|)wq0=m{%Pr=t+uddmvlJ=7+VXt0 z#ETe{m#Cm=@DVD=w(xyaR8TBb%~1E9ARHGW;;>jq!qNDFVEgoz7Vn2+QldJx@89(} z3lGFN*1>ubYd<s^Ugv&zFy?QTdG`nk+IO1kj}(3c)A;iGOwj7gbllFHZrcyg`I~QT zp6%W{<Jt63eCv0dHuLyQmp7a4+L@USSQMJfpNaTxCXpz=hGETm9rh!r*Jshc{{jj{ zGgbN&HBHTYerb;MCU3@?xE43dAqnlQ5HUZ**SApg)r-n!hqpDLqdZUp?SbCc9;y#j zRk>~S6`-WrBY=NVa<{NylAB1guQ?W&(Sj}~+t%UU9T&RViqumr)y!X^%}M>uc5H69 z;&vIa#JeS-8U1PNF4VBs4Xo8w=!n%-3~58N!>UC1rUE?6ouJFxe!ipS)citU3v{54 zv#o;r9Vg!=p=Kh{RfCU#Y@rUb#0|QdNbGXNa#fulrWd7%4w8F`I|PgHqx4d8Wz3|% zgGWB$qEt-vpxQf<44l{aUl+^Xe`bLsf%pm-g}gjBh@w@VikHdW{O0f)2U$7Ejl^p# z#f#<|qg4<Sm-=M@t9?>Ohzg&gpDa>`29XlAaySu}kgF?X?mRAp%$?na*6hPaW7?l+ z+d9+xx}oUGmddA?fzoKh*(Djgr9RL|CKHJ)<WUqJ&fdZ()ZBBUC|c!FyiWS^H-zG2 zQud^3*KFT;jBDlb)2Hy2^-y=)0iVDFfiR>~h+aX=U)YJzq-&_qKuVv$R)}B(tEjq# z9()n4KmaT1QFTo1?SfX+%t1?rQNvdlMrtk$AWR$-r`G$sIr7%5*tURpLS;%%Fd(0o z)FvE*=YZ!MRBg+TRK6c;;D@Lfkby%|2H-)!fvv|&+D1*E_**F#)!wUvvM^BlIY{>p z*SP~T8Dxkj9Q!qgA}P1sXm-ic{9hyCJb#^NH;jOX5$UbDtUf@KKgv<iN+~$JdX9u- z%oD}(+qfZR^0`niJL<M7)XYmT?ZUWkmH1?Um|7~69rgFs+mlc(`U8W4!?+cx8Nt0p zdk)NfVbg*8oCL0LP-A1CdPj-f&v5bbrt8DeZj*=Lcbta1?gB0DbR0WySo40S>M+;f zbm}=ou0c9nUMVfuEyt%hr4?iZIBN$1pIuGqdEwgC>(>@8EiBg;=B{2^TFn~%Z_ZuF z;YFH)gk=d|{~(GD(E76qA@x9csQkHh8*Z@>JgB+?RENVKX`xm-6{?Lvc`U!zbp3!< zeg1E#JL<OxUDTUNmkiITu~olA9wCr}+}7S}dI*2~^SFpxfBEw9pKc$wfLGgtKP7$d zl$?7nU=ky`w16@#fGK|=rvFG?mMhTsDO3nY5@2?(fVmC1g1@B|ko!|qwdYtv(!N>< z#|Q8Y%b-Ko5ph~rgfO-2fD_HbVz+|~jPoe+(#pvMeU2p6F2%Qh7Zv}KW=mZuV`K2b z%kaU?r$xP@YEMnQ_u^O3KS#`OR(j72IPK{wzX5rT5;O4DV^=;M?*E0n@;8ZdW~j*9 zP5u_1{Ug4qfSyhnB#Je&xuIbq%Fm#K9Pi{b$#6mBXOr3dR&td%Kl~j$`zL&}V)x85 z%LpESmpcDG6%?OxnhgH|74K1zr$!Q8XIK0S)Z1H}Uj9mIHHZ-LAE`k43TNzRxS*KU z9}A$Jc3{>b<EY$1jQdczsK7*0W|R!3a?41bA^znTgF;{JYdc6o_jSG)6mh51U4Tr+ zEfd<#*wLfA5!@jW9o?02SEM^uf(vNcJD8v}qBc2tBHfF8DD*KUH!`*n3E_Z@=A9&d zPi^2Z6S-UDkW9<V+I5>#29}0};~90F4R|TuwRSa&vtM{o%O<Uo5O|i`t`Dm_JSUb^ zBW>{UrqhN^iE}EcSs{B9<;JpxSay7)-Enx!4d5zVh?6if;Wn)EMAgJLEJ;at{?O!r z9OQbG@tGHH8FSis;zcu$9bM{sz;BO}X_-YK^@obNNs>`bR%5N*M{Su67n=aP*M3DN zN|SZ_&$4jJKdyV-wn(?b<%;s5Y417ZL57FqM7SXo2?;l3;>X%HBm&%T^wo?jBCWYD zthq3dp&7$DAl*XO{VV#DIz=n0#*^M_sr)7!IK&J2x)bE@W87i$`S<*MWG*I2A}&<- ziI688lU6>4Td1+H;08|1mtKSAw0&%0V1GcSc{3@%x^oZCRQO_4BjHECj_j0lzrxYz zC3q8lm`EXUk(Z#*HI7<!h@4cQ<XsG`CNyLE{WC4;6%@*WqH1bI&3sZU$kKo}g0D74 z@oOd*7&l$0j#ECd4X?Rg56ks>OYBnNx>B#-?%K`hO{rdIUIULu5Owu1cPEgF{uoW{ zWhyKxs#Lr|#WWR^+~7Z?;xZMf@=xs!#VZsZ`LCfcRpW(B0+W)Nzbux`{pJKdljbNs z$IN4#+6-k7q3Ov0k)|gv)E{H&5(1zH2!xpaP(zLd9KD0E2N{*u>0N+;r>{Ij_(OM9 zqjz@BM^+qpFiIyP(m_H|_`*r#xl8V$7Z<)%XE_D`)q+S%hXudWbc0ZDI&DriDcrwH zzaY^>86a7IUxPc)Ih6eNGjt+p<R75;FMNGUG%6%U_*C#QRPnAs0v!L5AQOEADahkS zQc0MuZ6uVKx;4V5`#`6!_Z38d(}74P(cMEmB7xRBH$Vci2`7DvA}ALsO%Nnes)<S^ zi_&%c+5)mLr41*b>T>PJ_Eg|iBTBd<KQEgLnuH_CSYbgtAEe1VR`vwnh$dwuNevMz zXiqu4%Q*tEf}>x*h9Xe@P+14yF!nIsWctbYL)E<=sJFB)@UE}@wf3h9D549d_(7H; z$b1a3V4x3JWxys-E+@yS#0vz^0h$WQtkAWGx3P2b1%TSon6hQ28n>!0R8>xjnUm9o zgp6RBRD8&tq<nm&Vl{Q_N$>2hQcc5rN<yvZBQxeO3EH8d<~(Lva_hp$$YN)7pTy}C zny}#Ai?}M${3scwXcbL+Viv%+^gPG6gbjT!;OkGJ02+t;aMHF$yn_@ElaNA`>518S zEqzke?0p#Eq7#shfZYcdJIRt4NpOXxvnWl-us0!67s<W^LO`f_9wi^*O^1NX)~Wr! zNsPVQXNnp`y`<I2R=Z7+-`MCjZEiXDh%IREnmU1>knKxMN$|Kd&rz?DT}gX|147!! z!d?aW5K#^W^THxyBP4qO%Y+3nE1>l;NEw!*IfkXE=72bbrt3??G?`#kHfT@jsb=sx zx>%Ucp+#DTz6n~;G78BKl&emfhM$1rOWNi{piBJ&>`0b0yFG{&EhX9Tw0tNTO6f(= z?FJ{Qn$l)D*TXL7HiIl><I{Fio;X!uH>(zPK`$*z>Jn1XCRQ?97PA~uYo3?rgP~n7 ziG<gE!I<&BuGQ*dECLel8SUUkUG7TfuC6ZguCuyItpzVnW5a76R)U^+ARWI8=Ucd# zvpm0HMH3S*7T{12h@1p0Jh*h@gSi{am#-~eS^iP|>fG{$%a<0zQCfUGW&`Nuk!0m^ z59BA*c0^2pa(06pG?`RSIyphSM6MO(MJn(_IK%Z&%`Et61#c5RQo%>0k!w;1@EW)) zGS#@o=J5_`1C8H|-rvOgqBP~4u1oToc#!G|&eMl+o&fz<GF_f;5@y+p)t-kZ#00)w zb}%#SP`P|<X*pqo%9ZPP&c=8A$3P@JA~3JJ9lQ`sLOY#MXCc*nJFXiZ5qAsM>WlLi z&Yn8;PW%EoNVwO;KfFOj>IMoEVdL4m#45CHuT;jc*<#{5p>leYV;8cXiP|A=D9bK@ zShe362641Oy|+q{6;k0Pe4|DYXZ-JhcEpxyBF5+_(!r4}lBa-3-PqBX&!P$-`0)&r zWermdabJ6A27r?)hOs4Rf~%Jj;4~Q=3E=XWh2xSsiKu@>_z^lvh11sAuLCtYhLVY; zlV!?0NJghq#XNSR>9>j;jTqB<aQ7g=9x9x06SGT}^L0_HT%TLMoWYD7Ej|phQ5rWv z?9&Wlt>;JV)G#>{M~0pWGEp;+nQZ*6f+mK1R@CJDer>Rg{_c%Si;4NIYVzdLFx<w( z$O&+_GQfGy58Mxj0T&<gdM51R%6a(Wr?LO`?I_H6)Mo`TuAjP>UswDl<`?Hayh_`M zktYQx$&d{d!Ts_037YpaXx=6?ai9FrbrQ>ytqhW+H4+;7!zgkU5$f4o07PnL!^MWV z^l8Dh@kSomcPp~syF=3w2BB!vr}T{oO;2oNE01yr@?eTQlHwhw1WMb`6gAqVgok+o zP55`HIF91+Qxu3@DXjyNP$mMWHSQxw%bOCBB>ZEd0vUF(WBJA&4#%*tHB@U=4TrCq zO@2)dD4dOfF*fk(3mQY1D1*~IW?aP2z_G!BLxnjzMiZpog|qqxxad{-3T@PGYac7^ zqlO58w#poSFMWOlu$Gihh;-VP#%B=-;S}UC>9|q`O6T)*?y)x!7<i-8n{6FE9Y#+D z^wUiGL9I`4%)K9-2=ac$id*QL$Pe&Kz1`r)$>?dp060*JTrfp8B1s|WTbq}D8J(S6 zmf(F4m(?ONGI5lGQ!>~oC8C8BQ6hRSekZ&$0dF|6jEw`4mj+Qqf`T?q!~K4DE$xc- zh~z=dJUHR2xoSzaG!c=%BH-jPM-5@bglZaeBnP=d9Cw^h$8=NUJ&c#bio_-nolV>X zU}ur!fzW*R0fnf6x>ZCdfx{5Am*ZFZbk-3<g>zLEAObwLjlMyl2EE@=^ED89u%LJg z`#+gv5ir3qpHqX$qGU}nM<mFfJ*tAUs(h3vcC?<0&2G+pbmijQ^0mb!u|RR6DLhn9 zceXPXM2<)xb$Ixe0Wy;U8nNd+8SMyUGdBXWIKcDxpqyU91pl6(paWI$iPN%L1_~y! z%M}e-9ja5+7UrvJ{{IO72ya3~u#$*E<<YyMJnk<Nx+0Y+a(5y*B>hr`W|Gm!tK{UU za58$Fbfpku-lr>~9{(v7#0g>^nfVKbBmEhg@5u!BdCIl>q?BYPwW3e_o>DjWnIrg4 VmJi}HE<dIjC8YnmSOTjZ{U55&^5*~m diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/_mixin.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/_mixin.py deleted file mode 100644 index 543925c..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/_mixin.py +++ /dev/null @@ -1,353 +0,0 @@ -"""Module containing the implementation of the URIMixin class.""" -import warnings - -from . import exceptions as exc -from . import misc -from . import normalizers -from . import validators - - -class URIMixin(object): - """Mixin with all shared methods for URIs and IRIs.""" - - __hash__ = tuple.__hash__ - - def authority_info(self): - """Return a dictionary with the ``userinfo``, ``host``, and ``port``. - - If the authority is not valid, it will raise a - :class:`~rfc3986.exceptions.InvalidAuthority` Exception. - - :returns: - ``{'userinfo': 'username:password', 'host': 'www.example.com', - 'port': '80'}`` - :rtype: dict - :raises rfc3986.exceptions.InvalidAuthority: - If the authority is not ``None`` and can not be parsed. - """ - if not self.authority: - return {'userinfo': None, 'host': None, 'port': None} - - match = self._match_subauthority() - - if match is None: - # In this case, we have an authority that was parsed from the URI - # Reference, but it cannot be further parsed by our - # misc.SUBAUTHORITY_MATCHER. In this case it must not be a valid - # authority. - raise exc.InvalidAuthority(self.authority.encode(self.encoding)) - - # We had a match, now let's ensure that it is actually a valid host - # address if it is IPv4 - matches = match.groupdict() - host = matches.get('host') - - if (host and misc.IPv4_MATCHER.match(host) and not - validators.valid_ipv4_host_address(host)): - # If we have a host, it appears to be IPv4 and it does not have - # valid bytes, it is an InvalidAuthority. - raise exc.InvalidAuthority(self.authority.encode(self.encoding)) - - return matches - - def _match_subauthority(self): - return misc.SUBAUTHORITY_MATCHER.match(self.authority) - - @property - def host(self): - """If present, a string representing the host.""" - try: - authority = self.authority_info() - except exc.InvalidAuthority: - return None - return authority['host'] - - @property - def port(self): - """If present, the port extracted from the authority.""" - try: - authority = self.authority_info() - except exc.InvalidAuthority: - return None - return authority['port'] - - @property - def userinfo(self): - """If present, the userinfo extracted from the authority.""" - try: - authority = self.authority_info() - except exc.InvalidAuthority: - return None - return authority['userinfo'] - - def is_absolute(self): - """Determine if this URI Reference is an absolute URI. - - See http://tools.ietf.org/html/rfc3986#section-4.3 for explanation. - - :returns: ``True`` if it is an absolute URI, ``False`` otherwise. - :rtype: bool - """ - return bool(misc.ABSOLUTE_URI_MATCHER.match(self.unsplit())) - - def is_valid(self, **kwargs): - """Determine if the URI is valid. - - .. deprecated:: 1.1.0 - - Use the :class:`~rfc3986.validators.Validator` object instead. - - :param bool require_scheme: Set to ``True`` if you wish to require the - presence of the scheme component. - :param bool require_authority: Set to ``True`` if you wish to require - the presence of the authority component. - :param bool require_path: Set to ``True`` if you wish to require the - presence of the path component. - :param bool require_query: Set to ``True`` if you wish to require the - presence of the query component. - :param bool require_fragment: Set to ``True`` if you wish to require - the presence of the fragment component. - :returns: ``True`` if the URI is valid. ``False`` otherwise. - :rtype: bool - """ - warnings.warn("Please use rfc3986.validators.Validator instead. " - "This method will be eventually removed.", - DeprecationWarning) - validators = [ - (self.scheme_is_valid, kwargs.get('require_scheme', False)), - (self.authority_is_valid, kwargs.get('require_authority', False)), - (self.path_is_valid, kwargs.get('require_path', False)), - (self.query_is_valid, kwargs.get('require_query', False)), - (self.fragment_is_valid, kwargs.get('require_fragment', False)), - ] - return all(v(r) for v, r in validators) - - def authority_is_valid(self, require=False): - """Determine if the authority component is valid. - - .. deprecated:: 1.1.0 - - Use the :class:`~rfc3986.validators.Validator` object instead. - - :param bool require: - Set to ``True`` to require the presence of this component. - :returns: - ``True`` if the authority is valid. ``False`` otherwise. - :rtype: - bool - """ - warnings.warn("Please use rfc3986.validators.Validator instead. " - "This method will be eventually removed.", - DeprecationWarning) - try: - self.authority_info() - except exc.InvalidAuthority: - return False - - return validators.authority_is_valid( - self.authority, - host=self.host, - require=require, - ) - - def scheme_is_valid(self, require=False): - """Determine if the scheme component is valid. - - .. deprecated:: 1.1.0 - - Use the :class:`~rfc3986.validators.Validator` object instead. - - :param str require: Set to ``True`` to require the presence of this - component. - :returns: ``True`` if the scheme is valid. ``False`` otherwise. - :rtype: bool - """ - warnings.warn("Please use rfc3986.validators.Validator instead. " - "This method will be eventually removed.", - DeprecationWarning) - return validators.scheme_is_valid(self.scheme, require) - - def path_is_valid(self, require=False): - """Determine if the path component is valid. - - .. deprecated:: 1.1.0 - - Use the :class:`~rfc3986.validators.Validator` object instead. - - :param str require: Set to ``True`` to require the presence of this - component. - :returns: ``True`` if the path is valid. ``False`` otherwise. - :rtype: bool - """ - warnings.warn("Please use rfc3986.validators.Validator instead. " - "This method will be eventually removed.", - DeprecationWarning) - return validators.path_is_valid(self.path, require) - - def query_is_valid(self, require=False): - """Determine if the query component is valid. - - .. deprecated:: 1.1.0 - - Use the :class:`~rfc3986.validators.Validator` object instead. - - :param str require: Set to ``True`` to require the presence of this - component. - :returns: ``True`` if the query is valid. ``False`` otherwise. - :rtype: bool - """ - warnings.warn("Please use rfc3986.validators.Validator instead. " - "This method will be eventually removed.", - DeprecationWarning) - return validators.query_is_valid(self.query, require) - - def fragment_is_valid(self, require=False): - """Determine if the fragment component is valid. - - .. deprecated:: 1.1.0 - - Use the Validator object instead. - - :param str require: Set to ``True`` to require the presence of this - component. - :returns: ``True`` if the fragment is valid. ``False`` otherwise. - :rtype: bool - """ - warnings.warn("Please use rfc3986.validators.Validator instead. " - "This method will be eventually removed.", - DeprecationWarning) - return validators.fragment_is_valid(self.fragment, require) - - def normalized_equality(self, other_ref): - """Compare this URIReference to another URIReference. - - :param URIReference other_ref: (required), The reference with which - we're comparing. - :returns: ``True`` if the references are equal, ``False`` otherwise. - :rtype: bool - """ - return tuple(self.normalize()) == tuple(other_ref.normalize()) - - def resolve_with(self, base_uri, strict=False): - """Use an absolute URI Reference to resolve this relative reference. - - Assuming this is a relative reference that you would like to resolve, - use the provided base URI to resolve it. - - See http://tools.ietf.org/html/rfc3986#section-5 for more information. - - :param base_uri: Either a string or URIReference. It must be an - absolute URI or it will raise an exception. - :returns: A new URIReference which is the result of resolving this - reference using ``base_uri``. - :rtype: :class:`URIReference` - :raises rfc3986.exceptions.ResolutionError: - If the ``base_uri`` is not an absolute URI. - """ - if not isinstance(base_uri, URIMixin): - base_uri = type(self).from_string(base_uri) - - if not base_uri.is_absolute(): - raise exc.ResolutionError(base_uri) - - # This is optional per - # http://tools.ietf.org/html/rfc3986#section-5.2.1 - base_uri = base_uri.normalize() - - # The reference we're resolving - resolving = self - - if not strict and resolving.scheme == base_uri.scheme: - resolving = resolving.copy_with(scheme=None) - - # http://tools.ietf.org/html/rfc3986#page-32 - if resolving.scheme is not None: - target = resolving.copy_with( - path=normalizers.normalize_path(resolving.path) - ) - else: - if resolving.authority is not None: - target = resolving.copy_with( - scheme=base_uri.scheme, - path=normalizers.normalize_path(resolving.path) - ) - else: - if resolving.path is None: - if resolving.query is not None: - query = resolving.query - else: - query = base_uri.query - target = resolving.copy_with( - scheme=base_uri.scheme, - authority=base_uri.authority, - path=base_uri.path, - query=query - ) - else: - if resolving.path.startswith('/'): - path = normalizers.normalize_path(resolving.path) - else: - path = normalizers.normalize_path( - misc.merge_paths(base_uri, resolving.path) - ) - target = resolving.copy_with( - scheme=base_uri.scheme, - authority=base_uri.authority, - path=path, - query=resolving.query - ) - return target - - def unsplit(self): - """Create a URI string from the components. - - :returns: The URI Reference reconstituted as a string. - :rtype: str - """ - # See http://tools.ietf.org/html/rfc3986#section-5.3 - result_list = [] - if self.scheme: - result_list.extend([self.scheme, ':']) - if self.authority: - result_list.extend(['//', self.authority]) - if self.path: - result_list.append(self.path) - if self.query is not None: - result_list.extend(['?', self.query]) - if self.fragment is not None: - result_list.extend(['#', self.fragment]) - return ''.join(result_list) - - def copy_with(self, scheme=misc.UseExisting, authority=misc.UseExisting, - path=misc.UseExisting, query=misc.UseExisting, - fragment=misc.UseExisting): - """Create a copy of this reference with the new components. - - :param str scheme: - (optional) The scheme to use for the new reference. - :param str authority: - (optional) The authority to use for the new reference. - :param str path: - (optional) The path to use for the new reference. - :param str query: - (optional) The query to use for the new reference. - :param str fragment: - (optional) The fragment to use for the new reference. - :returns: - New URIReference with provided components. - :rtype: - URIReference - """ - attributes = { - 'scheme': scheme, - 'authority': authority, - 'path': path, - 'query': query, - 'fragment': fragment, - } - for key, value in list(attributes.items()): - if value is misc.UseExisting: - del attributes[key] - uri = self._replace(**attributes) - uri.encoding = self.encoding - return uri diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/abnf_regexp.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/abnf_regexp.py deleted file mode 100644 index 24c9c3d..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/abnf_regexp.py +++ /dev/null @@ -1,267 +0,0 @@ -# -*- coding: utf-8 -*- -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Module for the regular expressions crafted from ABNF.""" - -import sys - -# https://tools.ietf.org/html/rfc3986#page-13 -GEN_DELIMS = GENERIC_DELIMITERS = ":/?#[]@" -GENERIC_DELIMITERS_SET = set(GENERIC_DELIMITERS) -# https://tools.ietf.org/html/rfc3986#page-13 -SUB_DELIMS = SUB_DELIMITERS = "!$&'()*+,;=" -SUB_DELIMITERS_SET = set(SUB_DELIMITERS) -# Escape the '*' for use in regular expressions -SUB_DELIMITERS_RE = r"!$&'()\*+,;=" -RESERVED_CHARS_SET = GENERIC_DELIMITERS_SET.union(SUB_DELIMITERS_SET) -ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' -DIGIT = '0123456789' -# https://tools.ietf.org/html/rfc3986#section-2.3 -UNRESERVED = UNRESERVED_CHARS = ALPHA + DIGIT + r'._!-' -UNRESERVED_CHARS_SET = set(UNRESERVED_CHARS) -NON_PCT_ENCODED_SET = RESERVED_CHARS_SET.union(UNRESERVED_CHARS_SET) -# We need to escape the '-' in this case: -UNRESERVED_RE = r'A-Za-z0-9._~\-' - -# Percent encoded character values -PERCENT_ENCODED = PCT_ENCODED = '%[A-Fa-f0-9]{2}' -PCHAR = '([' + UNRESERVED_RE + SUB_DELIMITERS_RE + ':@]|%s)' % PCT_ENCODED - -# NOTE(sigmavirus24): We're going to use more strict regular expressions -# than appear in Appendix B for scheme. This will prevent over-eager -# consuming of items that aren't schemes. -SCHEME_RE = '[a-zA-Z][a-zA-Z0-9+.-]*' -_AUTHORITY_RE = '[^/?#]*' -_PATH_RE = '[^?#]*' -_QUERY_RE = '[^#]*' -_FRAGMENT_RE = '.*' - -# Extracted from http://tools.ietf.org/html/rfc3986#appendix-B -COMPONENT_PATTERN_DICT = { - 'scheme': SCHEME_RE, - 'authority': _AUTHORITY_RE, - 'path': _PATH_RE, - 'query': _QUERY_RE, - 'fragment': _FRAGMENT_RE, -} - -# See http://tools.ietf.org/html/rfc3986#appendix-B -# In this case, we name each of the important matches so we can use -# SRE_Match#groupdict to parse the values out if we so choose. This is also -# modified to ignore other matches that are not important to the parsing of -# the reference so we can also simply use SRE_Match#groups. -URL_PARSING_RE = ( - r'(?:(?P<scheme>{scheme}):)?(?://(?P<authority>{authority}))?' - r'(?P<path>{path})(?:\?(?P<query>{query}))?' - r'(?:#(?P<fragment>{fragment}))?' -).format(**COMPONENT_PATTERN_DICT) - - -# ######################### -# Authority Matcher Section -# ######################### - -# Host patterns, see: http://tools.ietf.org/html/rfc3986#section-3.2.2 -# The pattern for a regular name, e.g., www.google.com, api.github.com -REGULAR_NAME_RE = REG_NAME = '((?:{0}|[{1}])*)'.format( - '%[0-9A-Fa-f]{2}', SUB_DELIMITERS_RE + UNRESERVED_RE -) -# The pattern for an IPv4 address, e.g., 192.168.255.255, 127.0.0.1, -IPv4_RE = r'([0-9]{1,3}\.){3}[0-9]{1,3}' -# Hexadecimal characters used in each piece of an IPv6 address -HEXDIG_RE = '[0-9A-Fa-f]{1,4}' -# Least-significant 32 bits of an IPv6 address -LS32_RE = '({hex}:{hex}|{ipv4})'.format(hex=HEXDIG_RE, ipv4=IPv4_RE) -# Substitutions into the following patterns for IPv6 patterns defined -# http://tools.ietf.org/html/rfc3986#page-20 -_subs = {'hex': HEXDIG_RE, 'ls32': LS32_RE} - -# Below: h16 = hexdig, see: https://tools.ietf.org/html/rfc5234 for details -# about ABNF (Augmented Backus-Naur Form) use in the comments -variations = [ - # 6( h16 ":" ) ls32 - '(%(hex)s:){6}%(ls32)s' % _subs, - # "::" 5( h16 ":" ) ls32 - '::(%(hex)s:){5}%(ls32)s' % _subs, - # [ h16 ] "::" 4( h16 ":" ) ls32 - '(%(hex)s)?::(%(hex)s:){4}%(ls32)s' % _subs, - # [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 - '((%(hex)s:)?%(hex)s)?::(%(hex)s:){3}%(ls32)s' % _subs, - # [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 - '((%(hex)s:){0,2}%(hex)s)?::(%(hex)s:){2}%(ls32)s' % _subs, - # [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 - '((%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s' % _subs, - # [ *4( h16 ":" ) h16 ] "::" ls32 - '((%(hex)s:){0,4}%(hex)s)?::%(ls32)s' % _subs, - # [ *5( h16 ":" ) h16 ] "::" h16 - '((%(hex)s:){0,5}%(hex)s)?::%(hex)s' % _subs, - # [ *6( h16 ":" ) h16 ] "::" - '((%(hex)s:){0,6}%(hex)s)?::' % _subs, -] - -IPv6_RE = '(({0})|({1})|({2})|({3})|({4})|({5})|({6})|({7})|({8}))'.format( - *variations -) - -IPv_FUTURE_RE = r'v[0-9A-Fa-f]+\.[%s]+' % ( - UNRESERVED_RE + SUB_DELIMITERS_RE + ':' -) - -# RFC 6874 Zone ID ABNF -ZONE_ID = '(?:[' + UNRESERVED_RE + ']|' + PCT_ENCODED + ')+' - -IPv6_ADDRZ_RFC4007_RE = IPv6_RE + '(?:(?:%25|%)' + ZONE_ID + ')?' -IPv6_ADDRZ_RE = IPv6_RE + '(?:%25' + ZONE_ID + ')?' - -IP_LITERAL_RE = r'\[({0}|{1})\]'.format( - IPv6_ADDRZ_RFC4007_RE, - IPv_FUTURE_RE, -) - -# Pattern for matching the host piece of the authority -HOST_RE = HOST_PATTERN = '({0}|{1}|{2})'.format( - REG_NAME, - IPv4_RE, - IP_LITERAL_RE, -) -USERINFO_RE = '^([' + UNRESERVED_RE + SUB_DELIMITERS_RE + ':]|%s)+' % ( - PCT_ENCODED -) -PORT_RE = '[0-9]{1,5}' - -# #################### -# Path Matcher Section -# #################### - -# See http://tools.ietf.org/html/rfc3986#section-3.3 for more information -# about the path patterns defined below. -segments = { - 'segment': PCHAR + '*', - # Non-zero length segment - 'segment-nz': PCHAR + '+', - # Non-zero length segment without ":" - 'segment-nz-nc': PCHAR.replace(':', '') + '+' -} - -# Path types taken from Section 3.3 (linked above) -PATH_EMPTY = '^$' -PATH_ROOTLESS = '%(segment-nz)s(/%(segment)s)*' % segments -PATH_NOSCHEME = '%(segment-nz-nc)s(/%(segment)s)*' % segments -PATH_ABSOLUTE = '/(%s)?' % PATH_ROOTLESS -PATH_ABEMPTY = '(/%(segment)s)*' % segments -PATH_RE = '^(%s|%s|%s|%s|%s)$' % ( - PATH_ABEMPTY, PATH_ABSOLUTE, PATH_NOSCHEME, PATH_ROOTLESS, PATH_EMPTY -) - -FRAGMENT_RE = QUERY_RE = ( - '^([/?:@' + UNRESERVED_RE + SUB_DELIMITERS_RE + ']|%s)*$' % PCT_ENCODED -) - -# ########################## -# Relative reference matcher -# ########################## - -# See http://tools.ietf.org/html/rfc3986#section-4.2 for details -RELATIVE_PART_RE = '(//%s%s|%s|%s|%s)' % ( - COMPONENT_PATTERN_DICT['authority'], - PATH_ABEMPTY, - PATH_ABSOLUTE, - PATH_NOSCHEME, - PATH_EMPTY, -) - -# See http://tools.ietf.org/html/rfc3986#section-3 for definition -HIER_PART_RE = '(//%s%s|%s|%s|%s)' % ( - COMPONENT_PATTERN_DICT['authority'], - PATH_ABEMPTY, - PATH_ABSOLUTE, - PATH_ROOTLESS, - PATH_EMPTY, -) - -# ############### -# IRIs / RFC 3987 -# ############### - -# Only wide-unicode gets the high-ranges of UCSCHAR -if sys.maxunicode > 0xFFFF: # pragma: no cover - IPRIVATE = u'\uE000-\uF8FF\U000F0000-\U000FFFFD\U00100000-\U0010FFFD' - UCSCHAR_RE = ( - u'\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF' - u'\U00010000-\U0001FFFD\U00020000-\U0002FFFD' - u'\U00030000-\U0003FFFD\U00040000-\U0004FFFD' - u'\U00050000-\U0005FFFD\U00060000-\U0006FFFD' - u'\U00070000-\U0007FFFD\U00080000-\U0008FFFD' - u'\U00090000-\U0009FFFD\U000A0000-\U000AFFFD' - u'\U000B0000-\U000BFFFD\U000C0000-\U000CFFFD' - u'\U000D0000-\U000DFFFD\U000E1000-\U000EFFFD' - ) -else: # pragma: no cover - IPRIVATE = u'\uE000-\uF8FF' - UCSCHAR_RE = ( - u'\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF' - ) - -IUNRESERVED_RE = u'A-Za-z0-9\\._~\\-' + UCSCHAR_RE -IPCHAR = u'([' + IUNRESERVED_RE + SUB_DELIMITERS_RE + u':@]|%s)' % PCT_ENCODED - -isegments = { - 'isegment': IPCHAR + u'*', - # Non-zero length segment - 'isegment-nz': IPCHAR + u'+', - # Non-zero length segment without ":" - 'isegment-nz-nc': IPCHAR.replace(':', '') + u'+' -} - -IPATH_ROOTLESS = u'%(isegment-nz)s(/%(isegment)s)*' % isegments -IPATH_NOSCHEME = u'%(isegment-nz-nc)s(/%(isegment)s)*' % isegments -IPATH_ABSOLUTE = u'/(?:%s)?' % IPATH_ROOTLESS -IPATH_ABEMPTY = u'(?:/%(isegment)s)*' % isegments -IPATH_RE = u'^(?:%s|%s|%s|%s|%s)$' % ( - IPATH_ABEMPTY, IPATH_ABSOLUTE, IPATH_NOSCHEME, IPATH_ROOTLESS, PATH_EMPTY -) - -IREGULAR_NAME_RE = IREG_NAME = u'(?:{0}|[{1}])*'.format( - u'%[0-9A-Fa-f]{2}', SUB_DELIMITERS_RE + IUNRESERVED_RE -) - -IHOST_RE = IHOST_PATTERN = u'({0}|{1}|{2})'.format( - IREG_NAME, - IPv4_RE, - IP_LITERAL_RE, -) - -IUSERINFO_RE = u'^(?:[' + IUNRESERVED_RE + SUB_DELIMITERS_RE + u':]|%s)+' % ( - PCT_ENCODED -) - -IFRAGMENT_RE = (u'^(?:[/?:@' + IUNRESERVED_RE + SUB_DELIMITERS_RE - + u']|%s)*$' % PCT_ENCODED) -IQUERY_RE = (u'^(?:[/?:@' + IUNRESERVED_RE + SUB_DELIMITERS_RE - + IPRIVATE + u']|%s)*$' % PCT_ENCODED) - -IRELATIVE_PART_RE = u'(//%s%s|%s|%s|%s)' % ( - COMPONENT_PATTERN_DICT['authority'], - IPATH_ABEMPTY, - IPATH_ABSOLUTE, - IPATH_NOSCHEME, - PATH_EMPTY, -) - -IHIER_PART_RE = u'(//%s%s|%s|%s|%s)' % ( - COMPONENT_PATTERN_DICT['authority'], - IPATH_ABEMPTY, - IPATH_ABSOLUTE, - IPATH_ROOTLESS, - PATH_EMPTY, -) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/api.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/api.py deleted file mode 100644 index ddc4a1c..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/api.py +++ /dev/null @@ -1,106 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Module containing the simple and functional API for rfc3986. - -This module defines functions and provides access to the public attributes -and classes of rfc3986. -""" - -from .iri import IRIReference -from .parseresult import ParseResult -from .uri import URIReference - - -def uri_reference(uri, encoding='utf-8'): - """Parse a URI string into a URIReference. - - This is a convenience function. You could achieve the same end by using - ``URIReference.from_string(uri)``. - - :param str uri: The URI which needs to be parsed into a reference. - :param str encoding: The encoding of the string provided - :returns: A parsed URI - :rtype: :class:`URIReference` - """ - return URIReference.from_string(uri, encoding) - - -def iri_reference(iri, encoding='utf-8'): - """Parse a IRI string into an IRIReference. - - This is a convenience function. You could achieve the same end by using - ``IRIReference.from_string(iri)``. - - :param str iri: The IRI which needs to be parsed into a reference. - :param str encoding: The encoding of the string provided - :returns: A parsed IRI - :rtype: :class:`IRIReference` - """ - return IRIReference.from_string(iri, encoding) - - -def is_valid_uri(uri, encoding='utf-8', **kwargs): - """Determine if the URI given is valid. - - This is a convenience function. You could use either - ``uri_reference(uri).is_valid()`` or - ``URIReference.from_string(uri).is_valid()`` to achieve the same result. - - :param str uri: The URI to be validated. - :param str encoding: The encoding of the string provided - :param bool require_scheme: Set to ``True`` if you wish to require the - presence of the scheme component. - :param bool require_authority: Set to ``True`` if you wish to require the - presence of the authority component. - :param bool require_path: Set to ``True`` if you wish to require the - presence of the path component. - :param bool require_query: Set to ``True`` if you wish to require the - presence of the query component. - :param bool require_fragment: Set to ``True`` if you wish to require the - presence of the fragment component. - :returns: ``True`` if the URI is valid, ``False`` otherwise. - :rtype: bool - """ - return URIReference.from_string(uri, encoding).is_valid(**kwargs) - - -def normalize_uri(uri, encoding='utf-8'): - """Normalize the given URI. - - This is a convenience function. You could use either - ``uri_reference(uri).normalize().unsplit()`` or - ``URIReference.from_string(uri).normalize().unsplit()`` instead. - - :param str uri: The URI to be normalized. - :param str encoding: The encoding of the string provided - :returns: The normalized URI. - :rtype: str - """ - normalized_reference = URIReference.from_string(uri, encoding).normalize() - return normalized_reference.unsplit() - - -def urlparse(uri, encoding='utf-8'): - """Parse a given URI and return a ParseResult. - - This is a partial replacement of the standard library's urlparse function. - - :param str uri: The URI to be parsed. - :param str encoding: The encoding of the string provided. - :returns: A parsed URI - :rtype: :class:`~rfc3986.parseresult.ParseResult` - """ - return ParseResult.from_string(uri, encoding, strict=False) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/builder.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/builder.py deleted file mode 100644 index 7934279..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/builder.py +++ /dev/null @@ -1,298 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2017 Ian Stapleton Cordasco -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Module containing the logic for the URIBuilder object.""" -from . import compat -from . import normalizers -from . import uri - - -class URIBuilder(object): - """Object to aid in building up a URI Reference from parts. - - .. note:: - - This object should be instantiated by the user, but it's recommended - that it is not provided with arguments. Instead, use the available - method to populate the fields. - - """ - - def __init__(self, scheme=None, userinfo=None, host=None, port=None, - path=None, query=None, fragment=None): - """Initialize our URI builder. - - :param str scheme: - (optional) - :param str userinfo: - (optional) - :param str host: - (optional) - :param int port: - (optional) - :param str path: - (optional) - :param str query: - (optional) - :param str fragment: - (optional) - """ - self.scheme = scheme - self.userinfo = userinfo - self.host = host - self.port = port - self.path = path - self.query = query - self.fragment = fragment - - def __repr__(self): - """Provide a convenient view of our builder object.""" - formatstr = ('URIBuilder(scheme={b.scheme}, userinfo={b.userinfo}, ' - 'host={b.host}, port={b.port}, path={b.path}, ' - 'query={b.query}, fragment={b.fragment})') - return formatstr.format(b=self) - - def add_scheme(self, scheme): - """Add a scheme to our builder object. - - After normalizing, this will generate a new URIBuilder instance with - the specified scheme and all other attributes the same. - - .. code-block:: python - - >>> URIBuilder().add_scheme('HTTPS') - URIBuilder(scheme='https', userinfo=None, host=None, port=None, - path=None, query=None, fragment=None) - - """ - scheme = normalizers.normalize_scheme(scheme) - return URIBuilder( - scheme=scheme, - userinfo=self.userinfo, - host=self.host, - port=self.port, - path=self.path, - query=self.query, - fragment=self.fragment, - ) - - def add_credentials(self, username, password): - """Add credentials as the userinfo portion of the URI. - - .. code-block:: python - - >>> URIBuilder().add_credentials('root', 's3crete') - URIBuilder(scheme=None, userinfo='root:s3crete', host=None, - port=None, path=None, query=None, fragment=None) - - >>> URIBuilder().add_credentials('root', None) - URIBuilder(scheme=None, userinfo='root', host=None, - port=None, path=None, query=None, fragment=None) - """ - if username is None: - raise ValueError('Username cannot be None') - userinfo = normalizers.normalize_username(username) - - if password is not None: - userinfo = '{}:{}'.format( - userinfo, - normalizers.normalize_password(password), - ) - - return URIBuilder( - scheme=self.scheme, - userinfo=userinfo, - host=self.host, - port=self.port, - path=self.path, - query=self.query, - fragment=self.fragment, - ) - - def add_host(self, host): - """Add hostname to the URI. - - .. code-block:: python - - >>> URIBuilder().add_host('google.com') - URIBuilder(scheme=None, userinfo=None, host='google.com', - port=None, path=None, query=None, fragment=None) - - """ - return URIBuilder( - scheme=self.scheme, - userinfo=self.userinfo, - host=normalizers.normalize_host(host), - port=self.port, - path=self.path, - query=self.query, - fragment=self.fragment, - ) - - def add_port(self, port): - """Add port to the URI. - - .. code-block:: python - - >>> URIBuilder().add_port(80) - URIBuilder(scheme=None, userinfo=None, host=None, port='80', - path=None, query=None, fragment=None) - - >>> URIBuilder().add_port(443) - URIBuilder(scheme=None, userinfo=None, host=None, port='443', - path=None, query=None, fragment=None) - - """ - port_int = int(port) - if port_int < 0: - raise ValueError( - 'ports are not allowed to be negative. You provided {}'.format( - port_int, - ) - ) - if port_int > 65535: - raise ValueError( - 'ports are not allowed to be larger than 65535. ' - 'You provided {}'.format( - port_int, - ) - ) - - return URIBuilder( - scheme=self.scheme, - userinfo=self.userinfo, - host=self.host, - port='{}'.format(port_int), - path=self.path, - query=self.query, - fragment=self.fragment, - ) - - def add_path(self, path): - """Add a path to the URI. - - .. code-block:: python - - >>> URIBuilder().add_path('sigmavirus24/rfc3985') - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path='/sigmavirus24/rfc3986', query=None, fragment=None) - - >>> URIBuilder().add_path('/checkout.php') - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path='/checkout.php', query=None, fragment=None) - - """ - if not path.startswith('/'): - path = '/{}'.format(path) - - return URIBuilder( - scheme=self.scheme, - userinfo=self.userinfo, - host=self.host, - port=self.port, - path=normalizers.normalize_path(path), - query=self.query, - fragment=self.fragment, - ) - - def add_query_from(self, query_items): - """Generate and add a query a dictionary or list of tuples. - - .. code-block:: python - - >>> URIBuilder().add_query_from({'a': 'b c'}) - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path=None, query='a=b+c', fragment=None) - - >>> URIBuilder().add_query_from([('a', 'b c')]) - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path=None, query='a=b+c', fragment=None) - - """ - query = normalizers.normalize_query(compat.urlencode(query_items)) - - return URIBuilder( - scheme=self.scheme, - userinfo=self.userinfo, - host=self.host, - port=self.port, - path=self.path, - query=query, - fragment=self.fragment, - ) - - def add_query(self, query): - """Add a pre-formated query string to the URI. - - .. code-block:: python - - >>> URIBuilder().add_query('a=b&c=d') - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path=None, query='a=b&c=d', fragment=None) - - """ - return URIBuilder( - scheme=self.scheme, - userinfo=self.userinfo, - host=self.host, - port=self.port, - path=self.path, - query=normalizers.normalize_query(query), - fragment=self.fragment, - ) - - def add_fragment(self, fragment): - """Add a fragment to the URI. - - .. code-block:: python - - >>> URIBuilder().add_fragment('section-2.6.1') - URIBuilder(scheme=None, userinfo=None, host=None, port=None, - path=None, query=None, fragment='section-2.6.1') - - """ - return URIBuilder( - scheme=self.scheme, - userinfo=self.userinfo, - host=self.host, - port=self.port, - path=self.path, - query=self.query, - fragment=normalizers.normalize_fragment(fragment), - ) - - def finalize(self): - """Create a URIReference from our builder. - - .. code-block:: python - - >>> URIBuilder().add_scheme('https').add_host('github.com' - ... ).add_path('sigmavirus24/rfc3986').finalize().unsplit() - 'https://github.com/sigmavirus24/rfc3986' - - >>> URIBuilder().add_scheme('https').add_host('github.com' - ... ).add_path('sigmavirus24/rfc3986').add_credentials( - ... 'sigmavirus24', 'not-re@l').finalize().unsplit() - 'https://sigmavirus24:not-re%40l@github.com/sigmavirus24/rfc3986' - - """ - return uri.URIReference( - self.scheme, - normalizers.normalize_authority( - (self.userinfo, self.host, self.port) - ), - self.path, - self.query, - self.fragment, - ) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/compat.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/compat.py deleted file mode 100644 index 8968c38..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/compat.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Compatibility module for Python 2 and 3 support.""" -import sys - -try: - from urllib.parse import quote as urlquote -except ImportError: # Python 2.x - from urllib import quote as urlquote - -try: - from urllib.parse import urlencode -except ImportError: # Python 2.x - from urllib import urlencode - -__all__ = ( - 'to_bytes', - 'to_str', - 'urlquote', - 'urlencode', -) - -PY3 = (3, 0) <= sys.version_info < (4, 0) -PY2 = (2, 6) <= sys.version_info < (2, 8) - - -if PY3: - unicode = str # Python 3.x - - -def to_str(b, encoding='utf-8'): - """Ensure that b is text in the specified encoding.""" - if hasattr(b, 'decode') and not isinstance(b, unicode): - b = b.decode(encoding) - return b - - -def to_bytes(s, encoding='utf-8'): - """Ensure that s is converted to bytes from the encoding.""" - if hasattr(s, 'encode') and not isinstance(s, bytes): - s = s.encode(encoding) - return s diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/exceptions.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/exceptions.py deleted file mode 100644 index da8ca7c..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/exceptions.py +++ /dev/null @@ -1,118 +0,0 @@ -# -*- coding: utf-8 -*- -"""Exceptions module for rfc3986.""" - -from . import compat - - -class RFC3986Exception(Exception): - """Base class for all rfc3986 exception classes.""" - - pass - - -class InvalidAuthority(RFC3986Exception): - """Exception when the authority string is invalid.""" - - def __init__(self, authority): - """Initialize the exception with the invalid authority.""" - super(InvalidAuthority, self).__init__( - u"The authority ({0}) is not valid.".format( - compat.to_str(authority))) - - -class InvalidPort(RFC3986Exception): - """Exception when the port is invalid.""" - - def __init__(self, port): - """Initialize the exception with the invalid port.""" - super(InvalidPort, self).__init__( - 'The port ("{0}") is not valid.'.format(port)) - - -class ResolutionError(RFC3986Exception): - """Exception to indicate a failure to resolve a URI.""" - - def __init__(self, uri): - """Initialize the error with the failed URI.""" - super(ResolutionError, self).__init__( - "{0} is not an absolute URI.".format(uri.unsplit())) - - -class ValidationError(RFC3986Exception): - """Exception raised during Validation of a URI.""" - - pass - - -class MissingComponentError(ValidationError): - """Exception raised when a required component is missing.""" - - def __init__(self, uri, *component_names): - """Initialize the error with the missing component name.""" - verb = 'was' - if len(component_names) > 1: - verb = 'were' - - self.uri = uri - self.components = sorted(component_names) - components = ', '.join(self.components) - super(MissingComponentError, self).__init__( - "{} {} required but missing".format(components, verb), - uri, - self.components, - ) - - -class UnpermittedComponentError(ValidationError): - """Exception raised when a component has an unpermitted value.""" - - def __init__(self, component_name, component_value, allowed_values): - """Initialize the error with the unpermitted component.""" - super(UnpermittedComponentError, self).__init__( - "{} was required to be one of {!r} but was {!r}".format( - component_name, list(sorted(allowed_values)), component_value, - ), - component_name, - component_value, - allowed_values, - ) - self.component_name = component_name - self.component_value = component_value - self.allowed_values = allowed_values - - -class PasswordForbidden(ValidationError): - """Exception raised when a URL has a password in the userinfo section.""" - - def __init__(self, uri): - """Initialize the error with the URI that failed validation.""" - unsplit = getattr(uri, 'unsplit', lambda: uri) - super(PasswordForbidden, self).__init__( - '"{}" contained a password when validation forbade it'.format( - unsplit() - ) - ) - self.uri = uri - - -class InvalidComponentsError(ValidationError): - """Exception raised when one or more components are invalid.""" - - def __init__(self, uri, *component_names): - """Initialize the error with the invalid component name(s).""" - verb = 'was' - if len(component_names) > 1: - verb = 'were' - - self.uri = uri - self.components = sorted(component_names) - components = ', '.join(self.components) - super(InvalidComponentsError, self).__init__( - "{} {} found to be invalid".format(components, verb), - uri, - self.components, - ) - - -class MissingDependencyError(RFC3986Exception): - """Exception raised when an IRI is encoded without the 'idna' module.""" diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/iri.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/iri.py deleted file mode 100644 index 416cae4..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/iri.py +++ /dev/null @@ -1,147 +0,0 @@ -"""Module containing the implementation of the IRIReference class.""" -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Copyright (c) 2015 Ian Stapleton Cordasco -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -from collections import namedtuple - -from . import compat -from . import exceptions -from . import misc -from . import normalizers -from . import uri - - -try: - from pip._vendor import idna -except ImportError: # pragma: no cover - idna = None - - -class IRIReference(namedtuple('IRIReference', misc.URI_COMPONENTS), - uri.URIMixin): - """Immutable object representing a parsed IRI Reference. - - Can be encoded into an URIReference object via the procedure - specified in RFC 3987 Section 3.1 - - .. note:: - The IRI submodule is a new interface and may possibly change in - the future. Check for changes to the interface when upgrading. - """ - - slots = () - - def __new__(cls, scheme, authority, path, query, fragment, - encoding='utf-8'): - """Create a new IRIReference.""" - ref = super(IRIReference, cls).__new__( - cls, - scheme or None, - authority or None, - path or None, - query, - fragment) - ref.encoding = encoding - return ref - - def __eq__(self, other): - """Compare this reference to another.""" - other_ref = other - if isinstance(other, tuple): - other_ref = self.__class__(*other) - elif not isinstance(other, IRIReference): - try: - other_ref = self.__class__.from_string(other) - except TypeError: - raise TypeError( - 'Unable to compare {0}() to {1}()'.format( - type(self).__name__, type(other).__name__)) - - # See http://tools.ietf.org/html/rfc3986#section-6.2 - return tuple(self) == tuple(other_ref) - - def _match_subauthority(self): - return misc.ISUBAUTHORITY_MATCHER.match(self.authority) - - @classmethod - def from_string(cls, iri_string, encoding='utf-8'): - """Parse a IRI reference from the given unicode IRI string. - - :param str iri_string: Unicode IRI to be parsed into a reference. - :param str encoding: The encoding of the string provided - :returns: :class:`IRIReference` or subclass thereof - """ - iri_string = compat.to_str(iri_string, encoding) - - split_iri = misc.IRI_MATCHER.match(iri_string).groupdict() - return cls( - split_iri['scheme'], split_iri['authority'], - normalizers.encode_component(split_iri['path'], encoding), - normalizers.encode_component(split_iri['query'], encoding), - normalizers.encode_component(split_iri['fragment'], encoding), - encoding, - ) - - def encode(self, idna_encoder=None): # noqa: C901 - """Encode an IRIReference into a URIReference instance. - - If the ``idna`` module is installed or the ``rfc3986[idna]`` - extra is used then unicode characters in the IRI host - component will be encoded with IDNA2008. - - :param idna_encoder: - Function that encodes each part of the host component - If not given will raise an exception if the IRI - contains a host component. - :rtype: uri.URIReference - :returns: A URI reference - """ - authority = self.authority - if authority: - if idna_encoder is None: - if idna is None: # pragma: no cover - raise exceptions.MissingDependencyError( - "Could not import the 'idna' module " - "and the IRI hostname requires encoding" - ) - - def idna_encoder(name): - if any(ord(c) > 128 for c in name): - try: - return idna.encode(name.lower(), - strict=True, - std3_rules=True) - except idna.IDNAError: - raise exceptions.InvalidAuthority(self.authority) - return name - - authority = "" - if self.host: - authority = ".".join([compat.to_str(idna_encoder(part)) - for part in self.host.split(".")]) - - if self.userinfo is not None: - authority = (normalizers.encode_component( - self.userinfo, self.encoding) + '@' + authority) - - if self.port is not None: - authority += ":" + str(self.port) - - return uri.URIReference(self.scheme, - authority, - path=self.path, - query=self.query, - fragment=self.fragment, - encoding=self.encoding) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/misc.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/misc.py deleted file mode 100644 index b735e04..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/misc.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -""" -Module containing compiled regular expressions and constants. - -This module contains important constants, patterns, and compiled regular -expressions for parsing and validating URIs and their components. -""" - -import re - -from . import abnf_regexp - -# These are enumerated for the named tuple used as a superclass of -# URIReference -URI_COMPONENTS = ['scheme', 'authority', 'path', 'query', 'fragment'] - -important_characters = { - 'generic_delimiters': abnf_regexp.GENERIC_DELIMITERS, - 'sub_delimiters': abnf_regexp.SUB_DELIMITERS, - # We need to escape the '*' in this case - 're_sub_delimiters': abnf_regexp.SUB_DELIMITERS_RE, - 'unreserved_chars': abnf_regexp.UNRESERVED_CHARS, - # We need to escape the '-' in this case: - 're_unreserved': abnf_regexp.UNRESERVED_RE, -} - -# For details about delimiters and reserved characters, see: -# http://tools.ietf.org/html/rfc3986#section-2.2 -GENERIC_DELIMITERS = abnf_regexp.GENERIC_DELIMITERS_SET -SUB_DELIMITERS = abnf_regexp.SUB_DELIMITERS_SET -RESERVED_CHARS = abnf_regexp.RESERVED_CHARS_SET -# For details about unreserved characters, see: -# http://tools.ietf.org/html/rfc3986#section-2.3 -UNRESERVED_CHARS = abnf_regexp.UNRESERVED_CHARS_SET -NON_PCT_ENCODED = abnf_regexp.NON_PCT_ENCODED_SET - -URI_MATCHER = re.compile(abnf_regexp.URL_PARSING_RE) - -SUBAUTHORITY_MATCHER = re.compile(( - '^(?:(?P<userinfo>{0})@)?' # userinfo - '(?P<host>{1})' # host - ':?(?P<port>{2})?$' # port - ).format(abnf_regexp.USERINFO_RE, - abnf_regexp.HOST_PATTERN, - abnf_regexp.PORT_RE)) - - -HOST_MATCHER = re.compile('^' + abnf_regexp.HOST_RE + '$') -IPv4_MATCHER = re.compile('^' + abnf_regexp.IPv4_RE + '$') -IPv6_MATCHER = re.compile(r'^\[' + abnf_regexp.IPv6_ADDRZ_RFC4007_RE + r'\]$') - -# Used by host validator -IPv6_NO_RFC4007_MATCHER = re.compile(r'^\[%s\]$' % ( - abnf_regexp.IPv6_ADDRZ_RE -)) - -# Matcher used to validate path components -PATH_MATCHER = re.compile(abnf_regexp.PATH_RE) - - -# ################################## -# Query and Fragment Matcher Section -# ################################## - -QUERY_MATCHER = re.compile(abnf_regexp.QUERY_RE) - -FRAGMENT_MATCHER = QUERY_MATCHER - -# Scheme validation, see: http://tools.ietf.org/html/rfc3986#section-3.1 -SCHEME_MATCHER = re.compile('^{0}$'.format(abnf_regexp.SCHEME_RE)) - -RELATIVE_REF_MATCHER = re.compile(r'^%s(\?%s)?(#%s)?$' % ( - abnf_regexp.RELATIVE_PART_RE, - abnf_regexp.QUERY_RE, - abnf_regexp.FRAGMENT_RE, -)) - -# See http://tools.ietf.org/html/rfc3986#section-4.3 -ABSOLUTE_URI_MATCHER = re.compile(r'^%s:%s(\?%s)?$' % ( - abnf_regexp.COMPONENT_PATTERN_DICT['scheme'], - abnf_regexp.HIER_PART_RE, - abnf_regexp.QUERY_RE[1:-1], -)) - -# ############### -# IRIs / RFC 3987 -# ############### - -IRI_MATCHER = re.compile(abnf_regexp.URL_PARSING_RE, re.UNICODE) - -ISUBAUTHORITY_MATCHER = re.compile(( - u'^(?:(?P<userinfo>{0})@)?' # iuserinfo - u'(?P<host>{1})' # ihost - u':?(?P<port>{2})?$' # port - ).format(abnf_regexp.IUSERINFO_RE, - abnf_regexp.IHOST_RE, - abnf_regexp.PORT_RE), re.UNICODE) - - -# Path merger as defined in http://tools.ietf.org/html/rfc3986#section-5.2.3 -def merge_paths(base_uri, relative_path): - """Merge a base URI's path with a relative URI's path.""" - if base_uri.path is None and base_uri.authority is not None: - return '/' + relative_path - else: - path = base_uri.path or '' - index = path.rfind('/') - return path[:index] + '/' + relative_path - - -UseExisting = object() diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/normalizers.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/normalizers.py deleted file mode 100644 index 2eb1bb3..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/normalizers.py +++ /dev/null @@ -1,167 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Module with functions to normalize components.""" -import re - -from . import compat -from . import misc - - -def normalize_scheme(scheme): - """Normalize the scheme component.""" - return scheme.lower() - - -def normalize_authority(authority): - """Normalize an authority tuple to a string.""" - userinfo, host, port = authority - result = '' - if userinfo: - result += normalize_percent_characters(userinfo) + '@' - if host: - result += normalize_host(host) - if port: - result += ':' + port - return result - - -def normalize_username(username): - """Normalize a username to make it safe to include in userinfo.""" - return compat.urlquote(username) - - -def normalize_password(password): - """Normalize a password to make safe for userinfo.""" - return compat.urlquote(password) - - -def normalize_host(host): - """Normalize a host string.""" - if misc.IPv6_MATCHER.match(host): - percent = host.find('%') - if percent != -1: - percent_25 = host.find('%25') - - # Replace RFC 4007 IPv6 Zone ID delimiter '%' with '%25' - # from RFC 6874. If the host is '[<IPv6 addr>%25]' then we - # assume RFC 4007 and normalize to '[<IPV6 addr>%2525]' - if percent_25 == -1 or percent < percent_25 or \ - (percent == percent_25 and percent_25 == len(host) - 4): - host = host.replace('%', '%25', 1) - - # Don't normalize the casing of the Zone ID - return host[:percent].lower() + host[percent:] - - return host.lower() - - -def normalize_path(path): - """Normalize the path string.""" - if not path: - return path - - path = normalize_percent_characters(path) - return remove_dot_segments(path) - - -def normalize_query(query): - """Normalize the query string.""" - if not query: - return query - return normalize_percent_characters(query) - - -def normalize_fragment(fragment): - """Normalize the fragment string.""" - if not fragment: - return fragment - return normalize_percent_characters(fragment) - - -PERCENT_MATCHER = re.compile('%[A-Fa-f0-9]{2}') - - -def normalize_percent_characters(s): - """All percent characters should be upper-cased. - - For example, ``"%3afoo%DF%ab"`` should be turned into ``"%3Afoo%DF%AB"``. - """ - matches = set(PERCENT_MATCHER.findall(s)) - for m in matches: - if not m.isupper(): - s = s.replace(m, m.upper()) - return s - - -def remove_dot_segments(s): - """Remove dot segments from the string. - - See also Section 5.2.4 of :rfc:`3986`. - """ - # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code - segments = s.split('/') # Turn the path into a list of segments - output = [] # Initialize the variable to use to store output - - for segment in segments: - # '.' is the current directory, so ignore it, it is superfluous - if segment == '.': - continue - # Anything other than '..', should be appended to the output - elif segment != '..': - output.append(segment) - # In this case segment == '..', if we can, we should pop the last - # element - elif output: - output.pop() - - # If the path starts with '/' and the output is empty or the first string - # is non-empty - if s.startswith('/') and (not output or output[0]): - output.insert(0, '') - - # If the path starts with '/.' or '/..' ensure we add one more empty - # string to add a trailing '/' - if s.endswith(('/.', '/..')): - output.append('') - - return '/'.join(output) - - -def encode_component(uri_component, encoding): - """Encode the specific component in the provided encoding.""" - if uri_component is None: - return uri_component - - # Try to see if the component we're encoding is already percent-encoded - # so we can skip all '%' characters but still encode all others. - percent_encodings = len(PERCENT_MATCHER.findall( - compat.to_str(uri_component, encoding))) - - uri_bytes = compat.to_bytes(uri_component, encoding) - is_percent_encoded = percent_encodings == uri_bytes.count(b'%') - - encoded_uri = bytearray() - - for i in range(0, len(uri_bytes)): - # Will return a single character bytestring on both Python 2 & 3 - byte = uri_bytes[i:i+1] - byte_ord = ord(byte) - if ((is_percent_encoded and byte == b'%') - or (byte_ord < 128 and byte.decode() in misc.NON_PCT_ENCODED)): - encoded_uri.extend(byte) - continue - encoded_uri.extend('%{0:02x}'.format(byte_ord).encode().upper()) - - return encoded_uri.decode(encoding) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/parseresult.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/parseresult.py deleted file mode 100644 index 0a73456..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/parseresult.py +++ /dev/null @@ -1,385 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2015 Ian Stapleton Cordasco -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Module containing the urlparse compatibility logic.""" -from collections import namedtuple - -from . import compat -from . import exceptions -from . import misc -from . import normalizers -from . import uri - -__all__ = ('ParseResult', 'ParseResultBytes') - -PARSED_COMPONENTS = ('scheme', 'userinfo', 'host', 'port', 'path', 'query', - 'fragment') - - -class ParseResultMixin(object): - def _generate_authority(self, attributes): - # I swear I did not align the comparisons below. That's just how they - # happened to align based on pep8 and attribute lengths. - userinfo, host, port = (attributes[p] - for p in ('userinfo', 'host', 'port')) - if (self.userinfo != userinfo or - self.host != host or - self.port != port): - if port: - port = '{0}'.format(port) - return normalizers.normalize_authority( - (compat.to_str(userinfo, self.encoding), - compat.to_str(host, self.encoding), - port) - ) - return self.authority - - def geturl(self): - """Shim to match the standard library method.""" - return self.unsplit() - - @property - def hostname(self): - """Shim to match the standard library.""" - return self.host - - @property - def netloc(self): - """Shim to match the standard library.""" - return self.authority - - @property - def params(self): - """Shim to match the standard library.""" - return self.query - - -class ParseResult(namedtuple('ParseResult', PARSED_COMPONENTS), - ParseResultMixin): - """Implementation of urlparse compatibility class. - - This uses the URIReference logic to handle compatibility with the - urlparse.ParseResult class. - """ - - slots = () - - def __new__(cls, scheme, userinfo, host, port, path, query, fragment, - uri_ref, encoding='utf-8'): - """Create a new ParseResult.""" - parse_result = super(ParseResult, cls).__new__( - cls, - scheme or None, - userinfo or None, - host, - port or None, - path or None, - query, - fragment) - parse_result.encoding = encoding - parse_result.reference = uri_ref - return parse_result - - @classmethod - def from_parts(cls, scheme=None, userinfo=None, host=None, port=None, - path=None, query=None, fragment=None, encoding='utf-8'): - """Create a ParseResult instance from its parts.""" - authority = '' - if userinfo is not None: - authority += userinfo + '@' - if host is not None: - authority += host - if port is not None: - authority += ':{0}'.format(port) - uri_ref = uri.URIReference(scheme=scheme, - authority=authority, - path=path, - query=query, - fragment=fragment, - encoding=encoding).normalize() - userinfo, host, port = authority_from(uri_ref, strict=True) - return cls(scheme=uri_ref.scheme, - userinfo=userinfo, - host=host, - port=port, - path=uri_ref.path, - query=uri_ref.query, - fragment=uri_ref.fragment, - uri_ref=uri_ref, - encoding=encoding) - - @classmethod - def from_string(cls, uri_string, encoding='utf-8', strict=True, - lazy_normalize=True): - """Parse a URI from the given unicode URI string. - - :param str uri_string: Unicode URI to be parsed into a reference. - :param str encoding: The encoding of the string provided - :param bool strict: Parse strictly according to :rfc:`3986` if True. - If False, parse similarly to the standard library's urlparse - function. - :returns: :class:`ParseResult` or subclass thereof - """ - reference = uri.URIReference.from_string(uri_string, encoding) - if not lazy_normalize: - reference = reference.normalize() - userinfo, host, port = authority_from(reference, strict) - - return cls(scheme=reference.scheme, - userinfo=userinfo, - host=host, - port=port, - path=reference.path, - query=reference.query, - fragment=reference.fragment, - uri_ref=reference, - encoding=encoding) - - @property - def authority(self): - """Return the normalized authority.""" - return self.reference.authority - - def copy_with(self, scheme=misc.UseExisting, userinfo=misc.UseExisting, - host=misc.UseExisting, port=misc.UseExisting, - path=misc.UseExisting, query=misc.UseExisting, - fragment=misc.UseExisting): - """Create a copy of this instance replacing with specified parts.""" - attributes = zip(PARSED_COMPONENTS, - (scheme, userinfo, host, port, path, query, fragment)) - attrs_dict = {} - for name, value in attributes: - if value is misc.UseExisting: - value = getattr(self, name) - attrs_dict[name] = value - authority = self._generate_authority(attrs_dict) - ref = self.reference.copy_with(scheme=attrs_dict['scheme'], - authority=authority, - path=attrs_dict['path'], - query=attrs_dict['query'], - fragment=attrs_dict['fragment']) - return ParseResult(uri_ref=ref, encoding=self.encoding, **attrs_dict) - - def encode(self, encoding=None): - """Convert to an instance of ParseResultBytes.""" - encoding = encoding or self.encoding - attrs = dict( - zip(PARSED_COMPONENTS, - (attr.encode(encoding) if hasattr(attr, 'encode') else attr - for attr in self))) - return ParseResultBytes( - uri_ref=self.reference, - encoding=encoding, - **attrs - ) - - def unsplit(self, use_idna=False): - """Create a URI string from the components. - - :returns: The parsed URI reconstituted as a string. - :rtype: str - """ - parse_result = self - if use_idna and self.host: - hostbytes = self.host.encode('idna') - host = hostbytes.decode(self.encoding) - parse_result = self.copy_with(host=host) - return parse_result.reference.unsplit() - - -class ParseResultBytes(namedtuple('ParseResultBytes', PARSED_COMPONENTS), - ParseResultMixin): - """Compatibility shim for the urlparse.ParseResultBytes object.""" - - def __new__(cls, scheme, userinfo, host, port, path, query, fragment, - uri_ref, encoding='utf-8', lazy_normalize=True): - """Create a new ParseResultBytes instance.""" - parse_result = super(ParseResultBytes, cls).__new__( - cls, - scheme or None, - userinfo or None, - host, - port or None, - path or None, - query or None, - fragment or None) - parse_result.encoding = encoding - parse_result.reference = uri_ref - parse_result.lazy_normalize = lazy_normalize - return parse_result - - @classmethod - def from_parts(cls, scheme=None, userinfo=None, host=None, port=None, - path=None, query=None, fragment=None, encoding='utf-8', - lazy_normalize=True): - """Create a ParseResult instance from its parts.""" - authority = '' - if userinfo is not None: - authority += userinfo + '@' - if host is not None: - authority += host - if port is not None: - authority += ':{0}'.format(int(port)) - uri_ref = uri.URIReference(scheme=scheme, - authority=authority, - path=path, - query=query, - fragment=fragment, - encoding=encoding) - if not lazy_normalize: - uri_ref = uri_ref.normalize() - to_bytes = compat.to_bytes - userinfo, host, port = authority_from(uri_ref, strict=True) - return cls(scheme=to_bytes(scheme, encoding), - userinfo=to_bytes(userinfo, encoding), - host=to_bytes(host, encoding), - port=port, - path=to_bytes(path, encoding), - query=to_bytes(query, encoding), - fragment=to_bytes(fragment, encoding), - uri_ref=uri_ref, - encoding=encoding, - lazy_normalize=lazy_normalize) - - @classmethod - def from_string(cls, uri_string, encoding='utf-8', strict=True, - lazy_normalize=True): - """Parse a URI from the given unicode URI string. - - :param str uri_string: Unicode URI to be parsed into a reference. - :param str encoding: The encoding of the string provided - :param bool strict: Parse strictly according to :rfc:`3986` if True. - If False, parse similarly to the standard library's urlparse - function. - :returns: :class:`ParseResultBytes` or subclass thereof - """ - reference = uri.URIReference.from_string(uri_string, encoding) - if not lazy_normalize: - reference = reference.normalize() - userinfo, host, port = authority_from(reference, strict) - - to_bytes = compat.to_bytes - return cls(scheme=to_bytes(reference.scheme, encoding), - userinfo=to_bytes(userinfo, encoding), - host=to_bytes(host, encoding), - port=port, - path=to_bytes(reference.path, encoding), - query=to_bytes(reference.query, encoding), - fragment=to_bytes(reference.fragment, encoding), - uri_ref=reference, - encoding=encoding, - lazy_normalize=lazy_normalize) - - @property - def authority(self): - """Return the normalized authority.""" - return self.reference.authority.encode(self.encoding) - - def copy_with(self, scheme=misc.UseExisting, userinfo=misc.UseExisting, - host=misc.UseExisting, port=misc.UseExisting, - path=misc.UseExisting, query=misc.UseExisting, - fragment=misc.UseExisting, lazy_normalize=True): - """Create a copy of this instance replacing with specified parts.""" - attributes = zip(PARSED_COMPONENTS, - (scheme, userinfo, host, port, path, query, fragment)) - attrs_dict = {} - for name, value in attributes: - if value is misc.UseExisting: - value = getattr(self, name) - if not isinstance(value, bytes) and hasattr(value, 'encode'): - value = value.encode(self.encoding) - attrs_dict[name] = value - authority = self._generate_authority(attrs_dict) - to_str = compat.to_str - ref = self.reference.copy_with( - scheme=to_str(attrs_dict['scheme'], self.encoding), - authority=to_str(authority, self.encoding), - path=to_str(attrs_dict['path'], self.encoding), - query=to_str(attrs_dict['query'], self.encoding), - fragment=to_str(attrs_dict['fragment'], self.encoding) - ) - if not lazy_normalize: - ref = ref.normalize() - return ParseResultBytes( - uri_ref=ref, - encoding=self.encoding, - lazy_normalize=lazy_normalize, - **attrs_dict - ) - - def unsplit(self, use_idna=False): - """Create a URI bytes object from the components. - - :returns: The parsed URI reconstituted as a string. - :rtype: bytes - """ - parse_result = self - if use_idna and self.host: - # self.host is bytes, to encode to idna, we need to decode it - # first - host = self.host.decode(self.encoding) - hostbytes = host.encode('idna') - parse_result = self.copy_with(host=hostbytes) - if self.lazy_normalize: - parse_result = parse_result.copy_with(lazy_normalize=False) - uri = parse_result.reference.unsplit() - return uri.encode(self.encoding) - - -def split_authority(authority): - # Initialize our expected return values - userinfo = host = port = None - # Initialize an extra var we may need to use - extra_host = None - # Set-up rest in case there is no userinfo portion - rest = authority - - if '@' in authority: - userinfo, rest = authority.rsplit('@', 1) - - # Handle IPv6 host addresses - if rest.startswith('['): - host, rest = rest.split(']', 1) - host += ']' - - if ':' in rest: - extra_host, port = rest.split(':', 1) - elif not host and rest: - host = rest - - if extra_host and not host: - host = extra_host - - return userinfo, host, port - - -def authority_from(reference, strict): - try: - subauthority = reference.authority_info() - except exceptions.InvalidAuthority: - if strict: - raise - userinfo, host, port = split_authority(reference.authority) - else: - # Thanks to Richard Barrell for this idea: - # https://twitter.com/0x2ba22e11/status/617338811975139328 - userinfo, host, port = (subauthority.get(p) - for p in ('userinfo', 'host', 'port')) - - if port: - try: - port = int(port) - except ValueError: - raise exceptions.InvalidPort(port) - return userinfo, host, port diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/uri.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/uri.py deleted file mode 100644 index d1d7150..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/uri.py +++ /dev/null @@ -1,153 +0,0 @@ -"""Module containing the implementation of the URIReference class.""" -# -*- coding: utf-8 -*- -# Copyright (c) 2014 Rackspace -# Copyright (c) 2015 Ian Stapleton Cordasco -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -from collections import namedtuple - -from . import compat -from . import misc -from . import normalizers -from ._mixin import URIMixin - - -class URIReference(namedtuple('URIReference', misc.URI_COMPONENTS), URIMixin): - """Immutable object representing a parsed URI Reference. - - .. note:: - - This class is not intended to be directly instantiated by the user. - - This object exposes attributes for the following components of a - URI: - - - scheme - - authority - - path - - query - - fragment - - .. attribute:: scheme - - The scheme that was parsed for the URI Reference. For example, - ``http``, ``https``, ``smtp``, ``imap``, etc. - - .. attribute:: authority - - Component of the URI that contains the user information, host, - and port sub-components. For example, - ``google.com``, ``127.0.0.1:5000``, ``username@[::1]``, - ``username:password@example.com:443``, etc. - - .. attribute:: path - - The path that was parsed for the given URI Reference. For example, - ``/``, ``/index.php``, etc. - - .. attribute:: query - - The query component for a given URI Reference. For example, ``a=b``, - ``a=b%20c``, ``a=b+c``, ``a=b,c=d,e=%20f``, etc. - - .. attribute:: fragment - - The fragment component of a URI. For example, ``section-3.1``. - - This class also provides extra attributes for easier access to information - like the subcomponents of the authority component. - - .. attribute:: userinfo - - The user information parsed from the authority. - - .. attribute:: host - - The hostname, IPv4, or IPv6 adddres parsed from the authority. - - .. attribute:: port - - The port parsed from the authority. - """ - - slots = () - - def __new__(cls, scheme, authority, path, query, fragment, - encoding='utf-8'): - """Create a new URIReference.""" - ref = super(URIReference, cls).__new__( - cls, - scheme or None, - authority or None, - path or None, - query, - fragment) - ref.encoding = encoding - return ref - - __hash__ = tuple.__hash__ - - def __eq__(self, other): - """Compare this reference to another.""" - other_ref = other - if isinstance(other, tuple): - other_ref = URIReference(*other) - elif not isinstance(other, URIReference): - try: - other_ref = URIReference.from_string(other) - except TypeError: - raise TypeError( - 'Unable to compare URIReference() to {0}()'.format( - type(other).__name__)) - - # See http://tools.ietf.org/html/rfc3986#section-6.2 - naive_equality = tuple(self) == tuple(other_ref) - return naive_equality or self.normalized_equality(other_ref) - - def normalize(self): - """Normalize this reference as described in Section 6.2.2. - - This is not an in-place normalization. Instead this creates a new - URIReference. - - :returns: A new reference object with normalized components. - :rtype: URIReference - """ - # See http://tools.ietf.org/html/rfc3986#section-6.2.2 for logic in - # this method. - return URIReference(normalizers.normalize_scheme(self.scheme or ''), - normalizers.normalize_authority( - (self.userinfo, self.host, self.port)), - normalizers.normalize_path(self.path or ''), - normalizers.normalize_query(self.query), - normalizers.normalize_fragment(self.fragment), - self.encoding) - - @classmethod - def from_string(cls, uri_string, encoding='utf-8'): - """Parse a URI reference from the given unicode URI string. - - :param str uri_string: Unicode URI to be parsed into a reference. - :param str encoding: The encoding of the string provided - :returns: :class:`URIReference` or subclass thereof - """ - uri_string = compat.to_str(uri_string, encoding) - - split_uri = misc.URI_MATCHER.match(uri_string).groupdict() - return cls( - split_uri['scheme'], split_uri['authority'], - normalizers.encode_component(split_uri['path'], encoding), - normalizers.encode_component(split_uri['query'], encoding), - normalizers.encode_component(split_uri['fragment'], encoding), - encoding, - ) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/validators.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/validators.py deleted file mode 100644 index 7fc9721..0000000 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/rfc3986/validators.py +++ /dev/null @@ -1,450 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2017 Ian Stapleton Cordasco -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Module containing the validation logic for rfc3986.""" -from . import exceptions -from . import misc -from . import normalizers - - -class Validator(object): - """Object used to configure validation of all objects in rfc3986. - - .. versionadded:: 1.0 - - Example usage:: - - >>> from rfc3986 import api, validators - >>> uri = api.uri_reference('https://github.com/') - >>> validator = validators.Validator().require_presence_of( - ... 'scheme', 'host', 'path', - ... ).allow_schemes( - ... 'http', 'https', - ... ).allow_hosts( - ... '127.0.0.1', 'github.com', - ... ) - >>> validator.validate(uri) - >>> invalid_uri = rfc3986.uri_reference('imap://mail.google.com') - >>> validator.validate(invalid_uri) - Traceback (most recent call last): - ... - rfc3986.exceptions.MissingComponentError: ('path was required but - missing', URIReference(scheme=u'imap', authority=u'mail.google.com', - path=None, query=None, fragment=None), ['path']) - - """ - - COMPONENT_NAMES = frozenset([ - 'scheme', - 'userinfo', - 'host', - 'port', - 'path', - 'query', - 'fragment', - ]) - - def __init__(self): - """Initialize our default validations.""" - self.allowed_schemes = set() - self.allowed_hosts = set() - self.allowed_ports = set() - self.allow_password = True - self.required_components = { - 'scheme': False, - 'userinfo': False, - 'host': False, - 'port': False, - 'path': False, - 'query': False, - 'fragment': False, - } - self.validated_components = self.required_components.copy() - - def allow_schemes(self, *schemes): - """Require the scheme to be one of the provided schemes. - - .. versionadded:: 1.0 - - :param schemes: - Schemes, without ``://`` that are allowed. - :returns: - The validator instance. - :rtype: - Validator - """ - for scheme in schemes: - self.allowed_schemes.add(normalizers.normalize_scheme(scheme)) - return self - - def allow_hosts(self, *hosts): - """Require the host to be one of the provided hosts. - - .. versionadded:: 1.0 - - :param hosts: - Hosts that are allowed. - :returns: - The validator instance. - :rtype: - Validator - """ - for host in hosts: - self.allowed_hosts.add(normalizers.normalize_host(host)) - return self - - def allow_ports(self, *ports): - """Require the port to be one of the provided ports. - - .. versionadded:: 1.0 - - :param ports: - Ports that are allowed. - :returns: - The validator instance. - :rtype: - Validator - """ - for port in ports: - port_int = int(port, base=10) - if 0 <= port_int <= 65535: - self.allowed_ports.add(port) - return self - - def allow_use_of_password(self): - """Allow passwords to be present in the URI. - - .. versionadded:: 1.0 - - :returns: - The validator instance. - :rtype: - Validator - """ - self.allow_password = True - return self - - def forbid_use_of_password(self): - """Prevent passwords from being included in the URI. - - .. versionadded:: 1.0 - - :returns: - The validator instance. - :rtype: - Validator - """ - self.allow_password = False - return self - - def check_validity_of(self, *components): - """Check the validity of the components provided. - - This can be specified repeatedly. - - .. versionadded:: 1.1 - - :param components: - Names of components from :attr:`Validator.COMPONENT_NAMES`. - :returns: - The validator instance. - :rtype: - Validator - """ - components = [c.lower() for c in components] - for component in components: - if component not in self.COMPONENT_NAMES: - raise ValueError( - '"{}" is not a valid component'.format(component) - ) - self.validated_components.update({ - component: True for component in components - }) - return self - - def require_presence_of(self, *components): - """Require the components provided. - - This can be specified repeatedly. - - .. versionadded:: 1.0 - - :param components: - Names of components from :attr:`Validator.COMPONENT_NAMES`. - :returns: - The validator instance. - :rtype: - Validator - """ - components = [c.lower() for c in components] - for component in components: - if component not in self.COMPONENT_NAMES: - raise ValueError( - '"{}" is not a valid component'.format(component) - ) - self.required_components.update({ - component: True for component in components - }) - return self - - def validate(self, uri): - """Check a URI for conditions specified on this validator. - - .. versionadded:: 1.0 - - :param uri: - Parsed URI to validate. - :type uri: - rfc3986.uri.URIReference - :raises MissingComponentError: - When a required component is missing. - :raises UnpermittedComponentError: - When a component is not one of those allowed. - :raises PasswordForbidden: - When a password is present in the userinfo component but is - not permitted by configuration. - :raises InvalidComponentsError: - When a component was found to be invalid. - """ - if not self.allow_password: - check_password(uri) - - required_components = [ - component - for component, required in self.required_components.items() - if required - ] - validated_components = [ - component - for component, required in self.validated_components.items() - if required - ] - if required_components: - ensure_required_components_exist(uri, required_components) - if validated_components: - ensure_components_are_valid(uri, validated_components) - - ensure_one_of(self.allowed_schemes, uri, 'scheme') - ensure_one_of(self.allowed_hosts, uri, 'host') - ensure_one_of(self.allowed_ports, uri, 'port') - - -def check_password(uri): - """Assert that there is no password present in the uri.""" - userinfo = uri.userinfo - if not userinfo: - return - credentials = userinfo.split(':', 1) - if len(credentials) <= 1: - return - raise exceptions.PasswordForbidden(uri) - - -def ensure_one_of(allowed_values, uri, attribute): - """Assert that the uri's attribute is one of the allowed values.""" - value = getattr(uri, attribute) - if value is not None and allowed_values and value not in allowed_values: - raise exceptions.UnpermittedComponentError( - attribute, value, allowed_values, - ) - - -def ensure_required_components_exist(uri, required_components): - """Assert that all required components are present in the URI.""" - missing_components = sorted([ - component - for component in required_components - if getattr(uri, component) is None - ]) - if missing_components: - raise exceptions.MissingComponentError(uri, *missing_components) - - -def is_valid(value, matcher, require): - """Determine if a value is valid based on the provided matcher. - - :param str value: - Value to validate. - :param matcher: - Compiled regular expression to use to validate the value. - :param require: - Whether or not the value is required. - """ - if require: - return (value is not None - and matcher.match(value)) - - # require is False and value is not None - return value is None or matcher.match(value) - - -def authority_is_valid(authority, host=None, require=False): - """Determine if the authority string is valid. - - :param str authority: - The authority to validate. - :param str host: - (optional) The host portion of the authority to validate. - :param bool require: - (optional) Specify if authority must not be None. - :returns: - ``True`` if valid, ``False`` otherwise - :rtype: - bool - """ - validated = is_valid(authority, misc.SUBAUTHORITY_MATCHER, require) - if validated and host is not None: - return host_is_valid(host, require) - return validated - - -def host_is_valid(host, require=False): - """Determine if the host string is valid. - - :param str host: - The host to validate. - :param bool require: - (optional) Specify if host must not be None. - :returns: - ``True`` if valid, ``False`` otherwise - :rtype: - bool - """ - validated = is_valid(host, misc.HOST_MATCHER, require) - if validated and host is not None and misc.IPv4_MATCHER.match(host): - return valid_ipv4_host_address(host) - elif validated and host is not None and misc.IPv6_MATCHER.match(host): - return misc.IPv6_NO_RFC4007_MATCHER.match(host) is not None - return validated - - -def scheme_is_valid(scheme, require=False): - """Determine if the scheme is valid. - - :param str scheme: - The scheme string to validate. - :param bool require: - (optional) Set to ``True`` to require the presence of a scheme. - :returns: - ``True`` if the scheme is valid. ``False`` otherwise. - :rtype: - bool - """ - return is_valid(scheme, misc.SCHEME_MATCHER, require) - - -def path_is_valid(path, require=False): - """Determine if the path component is valid. - - :param str path: - The path string to validate. - :param bool require: - (optional) Set to ``True`` to require the presence of a path. - :returns: - ``True`` if the path is valid. ``False`` otherwise. - :rtype: - bool - """ - return is_valid(path, misc.PATH_MATCHER, require) - - -def query_is_valid(query, require=False): - """Determine if the query component is valid. - - :param str query: - The query string to validate. - :param bool require: - (optional) Set to ``True`` to require the presence of a query. - :returns: - ``True`` if the query is valid. ``False`` otherwise. - :rtype: - bool - """ - return is_valid(query, misc.QUERY_MATCHER, require) - - -def fragment_is_valid(fragment, require=False): - """Determine if the fragment component is valid. - - :param str fragment: - The fragment string to validate. - :param bool require: - (optional) Set to ``True`` to require the presence of a fragment. - :returns: - ``True`` if the fragment is valid. ``False`` otherwise. - :rtype: - bool - """ - return is_valid(fragment, misc.FRAGMENT_MATCHER, require) - - -def valid_ipv4_host_address(host): - """Determine if the given host is a valid IPv4 address.""" - # If the host exists, and it might be IPv4, check each byte in the - # address. - return all([0 <= int(byte, base=10) <= 255 for byte in host.split('.')]) - - -_COMPONENT_VALIDATORS = { - 'scheme': scheme_is_valid, - 'path': path_is_valid, - 'query': query_is_valid, - 'fragment': fragment_is_valid, -} - -_SUBAUTHORITY_VALIDATORS = set(['userinfo', 'host', 'port']) - - -def subauthority_component_is_valid(uri, component): - """Determine if the userinfo, host, and port are valid.""" - try: - subauthority_dict = uri.authority_info() - except exceptions.InvalidAuthority: - return False - - # If we can parse the authority into sub-components and we're not - # validating the port, we can assume it's valid. - if component == 'host': - return host_is_valid(subauthority_dict['host']) - elif component != 'port': - return True - - try: - port = int(subauthority_dict['port']) - except TypeError: - # If the port wasn't provided it'll be None and int(None) raises a - # TypeError - return True - - return (0 <= port <= 65535) - - -def ensure_components_are_valid(uri, validated_components): - """Assert that all components are valid in the URI.""" - invalid_components = set([]) - for component in validated_components: - if component in _SUBAUTHORITY_VALIDATORS: - if not subauthority_component_is_valid(uri, component): - invalid_components.add(component) - # Python's peephole optimizer means that while this continue *is* - # actually executed, coverage.py cannot detect that. See also, - # https://bitbucket.org/ned/coveragepy/issues/198/continue-marked-as-not-covered - continue # nocov: Python 2.7, 3.3, 3.4 - - validator = _COMPONENT_VALIDATORS[component] - if not validator(getattr(uri, component)): - invalid_components.add(component) - - if invalid_components: - raise exceptions.InvalidComponentsError(uri, *invalid_components) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/six.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/six.py index 190c023..3144240 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/six.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/six.py @@ -1,6 +1,4 @@ -"""Utilities for writing code that runs on Python 2 and 3""" - -# Copyright (c) 2010-2015 Benjamin Peterson +# Copyright (c) 2010-2019 Benjamin Peterson # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,6 +18,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +"""Utilities for writing code that runs on Python 2 and 3""" + from __future__ import absolute_import import functools @@ -29,7 +29,7 @@ import sys import types __author__ = "Benjamin Peterson <benjamin@python.org>" -__version__ = "1.10.0" +__version__ = "1.12.0" # Useful for very coarse version differentiation. @@ -38,15 +38,15 @@ PY3 = sys.version_info[0] == 3 PY34 = sys.version_info[0:2] >= (3, 4) if PY3: - string_types = str, - integer_types = int, - class_types = type, + string_types = (str,) + integer_types = (int,) + class_types = (type,) text_type = str binary_type = bytes MAXSIZE = sys.maxsize else: - string_types = basestring, + string_types = (basestring,) integer_types = (int, long) class_types = (type, types.ClassType) text_type = unicode @@ -58,9 +58,9 @@ else: else: # It's possible to have sizeof(long) != sizeof(Py_ssize_t). class X(object): - def __len__(self): return 1 << 31 + try: len(X()) except OverflowError: @@ -84,7 +84,6 @@ def _import_module(name): class _LazyDescr(object): - def __init__(self, name): self.name = name @@ -101,7 +100,6 @@ class _LazyDescr(object): class MovedModule(_LazyDescr): - def __init__(self, name, old, new=None): super(MovedModule, self).__init__(name) if PY3: @@ -122,7 +120,6 @@ class MovedModule(_LazyDescr): class _LazyModule(types.ModuleType): - def __init__(self, name): super(_LazyModule, self).__init__(name) self.__doc__ = self.__class__.__doc__ @@ -137,7 +134,6 @@ class _LazyModule(types.ModuleType): class MovedAttribute(_LazyDescr): - def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): super(MovedAttribute, self).__init__(name) if PY3: @@ -221,28 +217,36 @@ class _SixMetaPathImporter(object): Required, if is_package is implemented""" self.__get_module(fullname) # eventually raises ImportError return None + get_source = get_code # same as get_code + _importer = _SixMetaPathImporter(__name__) class _MovedItems(_LazyModule): """Lazy loading of moved objects""" + __path__ = [] # mark as package _moved_attributes = [ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), - MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute( + "filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse" + ), MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), MovedAttribute("intern", "__builtin__", "sys"), MovedAttribute("map", "itertools", "builtins", "imap", "map"), MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("getoutput", "commands", "subprocess"), MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), - MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute( + "reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload" + ), MovedAttribute("reduce", "__builtin__", "functools"), MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), MovedAttribute("StringIO", "StringIO", "io"), @@ -251,7 +255,9 @@ _moved_attributes = [ MovedAttribute("UserString", "UserString", "collections"), MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), - MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedAttribute( + "zip_longest", "itertools", "itertools", "izip_longest", "zip_longest" + ), MovedModule("builtins", "__builtin__"), MovedModule("configparser", "ConfigParser"), MovedModule("copyreg", "copy_reg"), @@ -262,10 +268,13 @@ _moved_attributes = [ MovedModule("html_entities", "htmlentitydefs", "html.entities"), MovedModule("html_parser", "HTMLParser", "html.parser"), MovedModule("http_client", "httplib", "http.client"), - MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), - MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), - MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule( + "email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart" + ), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), @@ -283,15 +292,12 @@ _moved_attributes = [ MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), - MovedModule("tkinter_colorchooser", "tkColorChooser", - "tkinter.colorchooser"), - MovedModule("tkinter_commondialog", "tkCommonDialog", - "tkinter.commondialog"), + MovedModule("tkinter_colorchooser", "tkColorChooser", "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", "tkinter.commondialog"), MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), MovedModule("tkinter_font", "tkFont", "tkinter.font"), MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), - MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", - "tkinter.simpledialog"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", "tkinter.simpledialog"), MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), @@ -301,9 +307,7 @@ _moved_attributes = [ ] # Add windows specific modules. if sys.platform == "win32": - _moved_attributes += [ - MovedModule("winreg", "_winreg"), - ] + _moved_attributes += [MovedModule("winreg", "_winreg")] for attr in _moved_attributes: setattr(_MovedItems, attr.name, attr) @@ -337,10 +341,14 @@ _urllib_parse_moved_attributes = [ MovedAttribute("quote_plus", "urllib", "urllib.parse"), MovedAttribute("unquote", "urllib", "urllib.parse"), MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute( + "unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes" + ), MovedAttribute("urlencode", "urllib", "urllib.parse"), MovedAttribute("splitquery", "urllib", "urllib.parse"), MovedAttribute("splittag", "urllib", "urllib.parse"), MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("splitvalue", "urllib", "urllib.parse"), MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), MovedAttribute("uses_params", "urlparse", "urllib.parse"), @@ -353,8 +361,11 @@ del attr Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes -_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), - "moves.urllib_parse", "moves.urllib.parse") +_importer._add_module( + Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", + "moves.urllib.parse", +) class Module_six_moves_urllib_error(_LazyModule): @@ -373,8 +384,11 @@ del attr Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes -_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), - "moves.urllib_error", "moves.urllib.error") +_importer._add_module( + Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", + "moves.urllib.error", +) class Module_six_moves_urllib_request(_LazyModule): @@ -416,6 +430,8 @@ _urllib_request_moved_attributes = [ MovedAttribute("URLopener", "urllib", "urllib.request"), MovedAttribute("FancyURLopener", "urllib", "urllib.request"), MovedAttribute("proxy_bypass", "urllib", "urllib.request"), + MovedAttribute("parse_http_list", "urllib2", "urllib.request"), + MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"), ] for attr in _urllib_request_moved_attributes: setattr(Module_six_moves_urllib_request, attr.name, attr) @@ -423,8 +439,11 @@ del attr Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes -_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), - "moves.urllib_request", "moves.urllib.request") +_importer._add_module( + Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", + "moves.urllib.request", +) class Module_six_moves_urllib_response(_LazyModule): @@ -444,8 +463,11 @@ del attr Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes -_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), - "moves.urllib_response", "moves.urllib.response") +_importer._add_module( + Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", + "moves.urllib.response", +) class Module_six_moves_urllib_robotparser(_LazyModule): @@ -454,21 +476,27 @@ class Module_six_moves_urllib_robotparser(_LazyModule): _urllib_robotparser_moved_attributes = [ - MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser") ] for attr in _urllib_robotparser_moved_attributes: setattr(Module_six_moves_urllib_robotparser, attr.name, attr) del attr -Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes +Module_six_moves_urllib_robotparser._moved_attributes = ( + _urllib_robotparser_moved_attributes +) -_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), - "moves.urllib_robotparser", "moves.urllib.robotparser") +_importer._add_module( + Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", + "moves.urllib.robotparser", +) class Module_six_moves_urllib(types.ModuleType): """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package parse = _importer._get_module("moves.urllib_parse") error = _importer._get_module("moves.urllib_error") @@ -477,10 +505,12 @@ class Module_six_moves_urllib(types.ModuleType): robotparser = _importer._get_module("moves.urllib_robotparser") def __dir__(self): - return ['parse', 'error', 'request', 'response', 'robotparser'] + return ["parse", "error", "request", "response", "robotparser"] -_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), - "moves.urllib") + +_importer._add_module( + Module_six_moves_urllib(__name__ + ".moves.urllib"), "moves.urllib" +) def add_move(move): @@ -520,19 +550,24 @@ else: try: advance_iterator = next except NameError: + def advance_iterator(it): return it.next() + + next = advance_iterator try: callable = callable except NameError: + def callable(obj): return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) if PY3: + def get_unbound_function(unbound): return unbound @@ -543,6 +578,7 @@ if PY3: Iterator = object else: + def get_unbound_function(unbound): return unbound.im_func @@ -553,13 +589,13 @@ else: return types.MethodType(func, None, cls) class Iterator(object): - def next(self): return type(self).__next__(self) callable = callable -_add_doc(get_unbound_function, - """Get the function out of a possibly unbound function""") +_add_doc( + get_unbound_function, """Get the function out of a possibly unbound function""" +) get_method_function = operator.attrgetter(_meth_func) @@ -571,6 +607,7 @@ get_function_globals = operator.attrgetter(_func_globals) if PY3: + def iterkeys(d, **kw): return iter(d.keys(**kw)) @@ -589,6 +626,7 @@ if PY3: viewitems = operator.methodcaller("items") else: + def iterkeys(d, **kw): return d.iterkeys(**kw) @@ -609,28 +647,33 @@ else: _add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") _add_doc(itervalues, "Return an iterator over the values of a dictionary.") -_add_doc(iteritems, - "Return an iterator over the (key, value) pairs of a dictionary.") -_add_doc(iterlists, - "Return an iterator over the (key, [values]) pairs of a dictionary.") +_add_doc(iteritems, "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc( + iterlists, "Return an iterator over the (key, [values]) pairs of a dictionary." +) if PY3: + def b(s): return s.encode("latin-1") def u(s): return s + unichr = chr import struct + int2byte = struct.Struct(">B").pack del struct byte2int = operator.itemgetter(0) indexbytes = operator.getitem iterbytes = iter import io + StringIO = io.StringIO BytesIO = io.BytesIO + del io _assertCountEqual = "assertCountEqual" if sys.version_info[1] <= 1: _assertRaisesRegex = "assertRaisesRegexp" @@ -639,12 +682,15 @@ if PY3: _assertRaisesRegex = "assertRaisesRegex" _assertRegex = "assertRegex" else: + def b(s): return s + # Workaround for standalone backslash def u(s): - return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + return unicode(s.replace(r"\\", r"\\\\"), "unicode_escape") + unichr = unichr int2byte = chr @@ -653,8 +699,10 @@ else: def indexbytes(buf, i): return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) import StringIO + StringIO = BytesIO = StringIO.StringIO _assertCountEqual = "assertItemsEqual" _assertRaisesRegex = "assertRaisesRegexp" @@ -679,13 +727,19 @@ if PY3: exec_ = getattr(moves.builtins, "exec") def reraise(tp, value, tb=None): - if value is None: - value = tp() - if value.__traceback__ is not tb: - raise value.with_traceback(tb) - raise value + try: + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + finally: + value = None + tb = None + else: + def exec_(_code_, _globs_=None, _locs_=None): """Execute code in a namespace.""" if _globs_ is None: @@ -698,28 +752,45 @@ else: _locs_ = _globs_ exec("""exec _code_ in _globs_, _locs_""") - exec_("""def reraise(tp, value, tb=None): - raise tp, value, tb -""") + exec_( + """def reraise(tp, value, tb=None): + try: + raise tp, value, tb + finally: + tb = None +""" + ) if sys.version_info[:2] == (3, 2): - exec_("""def raise_from(value, from_value): - if from_value is None: - raise value - raise value from from_value -""") + exec_( + """def raise_from(value, from_value): + try: + if from_value is None: + raise value + raise value from from_value + finally: + value = None +""" + ) elif sys.version_info[:2] > (3, 2): - exec_("""def raise_from(value, from_value): - raise value from from_value -""") + exec_( + """def raise_from(value, from_value): + try: + raise value from from_value + finally: + value = None +""" + ) else: + def raise_from(value, from_value): raise value print_ = getattr(moves.builtins, "print", None) if print_ is None: + def print_(*args, **kwargs): """The new-style print function for Python 2.4 and 2.5.""" fp = kwargs.pop("file", sys.stdout) @@ -730,14 +801,17 @@ if print_ is None: if not isinstance(data, basestring): data = str(data) # If the file has an encoding, encode unicode with it. - if (isinstance(fp, file) and - isinstance(data, unicode) and - fp.encoding is not None): + if ( + isinstance(fp, file) + and isinstance(data, unicode) + and fp.encoding is not None + ): errors = getattr(fp, "errors", None) if errors is None: errors = "strict" data = data.encode(fp.encoding, errors) fp.write(data) + want_unicode = False sep = kwargs.pop("sep", None) if sep is not None: @@ -773,6 +847,8 @@ if print_ is None: write(sep) write(arg) write(end) + + if sys.version_info[:2] < (3, 3): _print = print_ @@ -783,16 +859,24 @@ if sys.version_info[:2] < (3, 3): if flush and fp is not None: fp.flush() + _add_doc(reraise, """Reraise an exception.""") if sys.version_info[0:2] < (3, 4): - def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, - updated=functools.WRAPPER_UPDATES): + + def wraps( + wrapped, + assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES, + ): def wrapper(f): f = functools.wraps(wrapped, assigned, updated)(f) f.__wrapped__ = wrapped return f + return wrapper + + else: wraps = functools.wraps @@ -802,29 +886,95 @@ def with_metaclass(meta, *bases): # This requires a bit of explanation: the basic idea is to make a dummy # metaclass for one level of class instantiation that replaces itself with # the actual metaclass. - class metaclass(meta): - + class metaclass(type): def __new__(cls, name, this_bases, d): return meta(name, bases, d) - return type.__new__(metaclass, 'temporary_class', (), {}) + + @classmethod + def __prepare__(cls, name, this_bases): + return meta.__prepare__(name, bases) + + return type.__new__(metaclass, "temporary_class", (), {}) def add_metaclass(metaclass): """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): orig_vars = cls.__dict__.copy() - slots = orig_vars.get('__slots__') + slots = orig_vars.get("__slots__") if slots is not None: if isinstance(slots, str): slots = [slots] for slots_var in slots: orig_vars.pop(slots_var) - orig_vars.pop('__dict__', None) - orig_vars.pop('__weakref__', None) + orig_vars.pop("__dict__", None) + orig_vars.pop("__weakref__", None) + if hasattr(cls, "__qualname__"): + orig_vars["__qualname__"] = cls.__qualname__ return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper +def ensure_binary(s, encoding="utf-8", errors="strict"): + """Coerce **s** to six.binary_type. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> encoded to `bytes` + - `bytes` -> `bytes` + """ + if isinstance(s, text_type): + return s.encode(encoding, errors) + elif isinstance(s, binary_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + +def ensure_str(s, encoding="utf-8", errors="strict"): + """Coerce *s* to `str`. + + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if not isinstance(s, (text_type, binary_type)): + raise TypeError("not expecting type '%s'" % type(s)) + if PY2 and isinstance(s, text_type): + s = s.encode(encoding, errors) + elif PY3 and isinstance(s, binary_type): + s = s.decode(encoding, errors) + return s + + +def ensure_text(s, encoding="utf-8", errors="strict"): + """Coerce *s* to six.text_type. + + For Python 2: + - `unicode` -> `unicode` + - `str` -> `unicode` + + For Python 3: + - `str` -> `str` + - `bytes` -> decoded to `str` + """ + if isinstance(s, binary_type): + return s.decode(encoding, errors) + elif isinstance(s, text_type): + return s + else: + raise TypeError("not expecting type '%s'" % type(s)) + + def python_2_unicode_compatible(klass): """ A decorator that defines __unicode__ and __str__ methods under Python 2. @@ -834,12 +984,13 @@ def python_2_unicode_compatible(klass): returning text and apply this decorator to the class. """ if PY2: - if '__str__' not in klass.__dict__: - raise ValueError("@python_2_unicode_compatible cannot be applied " - "to %s because it doesn't define __str__()." % - klass.__name__) + if "__str__" not in klass.__dict__: + raise ValueError( + "@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % klass.__name__ + ) klass.__unicode__ = klass.__str__ - klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + klass.__str__ = lambda self: self.__unicode__().encode("utf-8") return klass @@ -859,8 +1010,10 @@ if sys.meta_path: # be floating around. Therefore, we can't use isinstance() to check for # the six meta path importer, since the other six instance will have # inserted an importer with different class. - if (type(importer).__name__ == "_SixMetaPathImporter" and - importer.name == __name__): + if ( + type(importer).__name__ == "_SixMetaPathImporter" + and importer.name == __name__ + ): del sys.meta_path[i] break del i, importer diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py index d6594eb..75b6bb1 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py @@ -16,4 +16,4 @@ except ImportError: from ._implementation import CertificateError, match_hostname # Not needed, but documenting what we provide. -__all__ = ('CertificateError', 'match_hostname') +__all__ = ("CertificateError", "match_hostname") diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-38.pyc index 0c9fa6cf7cf9808886f974b0199a20d4968c2d74..92f09ffdd5b4f542bc712423f8e1d723f241a644 100644 GIT binary patch delta 93 zcmZo>S;4{+%FD~e00f%<cExYxDPwf5)6dAyP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS vE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc5FjfH4^WkOCln delta 56 zcmZ3%(#*mW%FD~e00hs=HpFe@DPxq2)Gx^`&@ad=(9O&%E=kPE(KX62DXlQhPXq~0 IKFXL30L$JI3IG5A diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-38.pyc index f763571aaf1334a7aa109ae47ed8bc5216ff1773..f1636744e8a8d0ea3cef8b37e16b1f8cc1ea3eb3 100644 GIT binary patch delta 168 zcmca1*(${w%FD~e00f%<cEvkv<Sk`%Zq?7o&rQ`Ysw^$d%G56|O4d(F%*#y8NzN}S zNiEi^sI1a2OU*0O&&f>EFQ_cZ$j>v@v(PWjEJ@WZNKDR7OiwM|ynxYxnUQt!LzX*? z{+su)>N7HiZhpu1l0`TXXjO3-$U+VlMkYq4|17MNpK)6W0hx?K|C#=?vG6g9F@Yo| O>+vjQHRE98-~j*;voW9m delta 123 zcmZpbx*^FM%FD~e00hs=HpIDX<Sk{COVBULEzmE>EYQu&D=taQ$<Z~+Fe$At&QAmh zZa&KBz|6=pnT_=hqu=Joton?M!JCEIU$XGW15GLR1DVCa!pOlqnV-jskA+F-9|toZ VBMTGPKMt13(L768O*vROcmRFu9@_u_ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py index 970cf65..5831c2e 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py @@ -15,7 +15,7 @@ try: except ImportError: ipaddress = None -__version__ = '3.5.0.1' +__version__ = "3.5.0.1" class CertificateError(ValueError): @@ -33,18 +33,19 @@ def _dnsname_match(dn, hostname, max_wildcards=1): # Ported from python3-syntax: # leftmost, *remainder = dn.split(r'.') - parts = dn.split(r'.') + parts = dn.split(r".") leftmost = parts[0] remainder = parts[1:] - wildcards = leftmost.count('*') + wildcards = leftmost.count("*") if wildcards > max_wildcards: # Issue #17980: avoid denials of service by refusing more # than one wildcard per fragment. A survey of established # policy among SSL implementations showed it to be a # reasonable choice. raise CertificateError( - "too many wildcards in certificate DNS name: " + repr(dn)) + "too many wildcards in certificate DNS name: " + repr(dn) + ) # speed up common case w/o wildcards if not wildcards: @@ -53,11 +54,11 @@ def _dnsname_match(dn, hostname, max_wildcards=1): # RFC 6125, section 6.4.3, subitem 1. # The client SHOULD NOT attempt to match a presented identifier in which # the wildcard character comprises a label other than the left-most label. - if leftmost == '*': + if leftmost == "*": # When '*' is a fragment by itself, it matches a non-empty dotless # fragment. - pats.append('[^.]+') - elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + pats.append("[^.]+") + elif leftmost.startswith("xn--") or hostname.startswith("xn--"): # RFC 6125, section 6.4.3, subitem 3. # The client SHOULD NOT attempt to match a presented identifier # where the wildcard character is embedded within an A-label or @@ -65,21 +66,22 @@ def _dnsname_match(dn, hostname, max_wildcards=1): pats.append(re.escape(leftmost)) else: # Otherwise, '*' matches any dotless string, e.g. www* - pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) + pats.append(re.escape(leftmost).replace(r"\*", "[^.]*")) # add the remaining fragments, ignore any wildcards for frag in remainder: pats.append(re.escape(frag)) - pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) + pat = re.compile(r"\A" + r"\.".join(pats) + r"\Z", re.IGNORECASE) return pat.match(hostname) def _to_unicode(obj): if isinstance(obj, str) and sys.version_info < (3,): - obj = unicode(obj, encoding='ascii', errors='strict') + obj = unicode(obj, encoding="ascii", errors="strict") return obj + def _ipaddress_match(ipname, host_ip): """Exact matching of IP addresses. @@ -101,9 +103,11 @@ def match_hostname(cert, hostname): returns nothing. """ if not cert: - raise ValueError("empty or no certificate, match_hostname needs a " - "SSL socket or SSL context with either " - "CERT_OPTIONAL or CERT_REQUIRED") + raise ValueError( + "empty or no certificate, match_hostname needs a " + "SSL socket or SSL context with either " + "CERT_OPTIONAL or CERT_REQUIRED" + ) try: # Divergence from upstream: ipaddress can't handle byte str host_ip = ipaddress.ip_address(_to_unicode(hostname)) @@ -122,35 +126,35 @@ def match_hostname(cert, hostname): else: raise dnsnames = [] - san = cert.get('subjectAltName', ()) + san = cert.get("subjectAltName", ()) for key, value in san: - if key == 'DNS': + if key == "DNS": if host_ip is None and _dnsname_match(value, hostname): return dnsnames.append(value) - elif key == 'IP Address': + elif key == "IP Address": if host_ip is not None and _ipaddress_match(value, host_ip): return dnsnames.append(value) if not dnsnames: # The subject is only checked when there is no dNSName entry # in subjectAltName - for sub in cert.get('subject', ()): + for sub in cert.get("subject", ()): for key, value in sub: # XXX according to RFC 2818, the most specific Common Name # must be used. - if key == 'commonName': + if key == "commonName": if _dnsname_match(value, hostname): return dnsnames.append(value) if len(dnsnames) > 1: - raise CertificateError("hostname %r " - "doesn't match either of %s" - % (hostname, ', '.join(map(repr, dnsnames)))) + raise CertificateError( + "hostname %r " + "doesn't match either of %s" % (hostname, ", ".join(map(repr, dnsnames))) + ) elif len(dnsnames) == 1: - raise CertificateError("hostname %r " - "doesn't match %r" - % (hostname, dnsnames[0])) + raise CertificateError("hostname %r doesn't match %r" % (hostname, dnsnames[0])) else: - raise CertificateError("no appropriate commonName or " - "subjectAltName fields were found") + raise CertificateError( + "no appropriate commonName or subjectAltName fields were found" + ) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/poolmanager.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/poolmanager.py index a6ade6e..e2bd3bd 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/poolmanager.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/poolmanager.py @@ -2,11 +2,17 @@ from __future__ import absolute_import import collections import functools import logging +import warnings from ._collections import RecentlyUsedContainer from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool from .connectionpool import port_by_scheme -from .exceptions import LocationValueError, MaxRetryError, ProxySchemeUnknown +from .exceptions import ( + LocationValueError, + MaxRetryError, + ProxySchemeUnknown, + InvalidProxyConfigurationWarning, +) from .packages import six from .packages.six.moves.urllib.parse import urljoin from .request import RequestMethods @@ -14,48 +20,55 @@ from .util.url import parse_url from .util.retry import Retry -__all__ = ['PoolManager', 'ProxyManager', 'proxy_from_url'] +__all__ = ["PoolManager", "ProxyManager", "proxy_from_url"] log = logging.getLogger(__name__) -SSL_KEYWORDS = ('key_file', 'cert_file', 'cert_reqs', 'ca_certs', - 'ssl_version', 'ca_cert_dir', 'ssl_context', - 'key_password') +SSL_KEYWORDS = ( + "key_file", + "cert_file", + "cert_reqs", + "ca_certs", + "ssl_version", + "ca_cert_dir", + "ssl_context", + "key_password", +) # All known keyword arguments that could be provided to the pool manager, its # pools, or the underlying connections. This is used to construct a pool key. _key_fields = ( - 'key_scheme', # str - 'key_host', # str - 'key_port', # int - 'key_timeout', # int or float or Timeout - 'key_retries', # int or Retry - 'key_strict', # bool - 'key_block', # bool - 'key_source_address', # str - 'key_key_file', # str - 'key_key_password', # str - 'key_cert_file', # str - 'key_cert_reqs', # str - 'key_ca_certs', # str - 'key_ssl_version', # str - 'key_ca_cert_dir', # str - 'key_ssl_context', # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext - 'key_maxsize', # int - 'key_headers', # dict - 'key__proxy', # parsed proxy url - 'key__proxy_headers', # dict - 'key_socket_options', # list of (level (int), optname (int), value (int or str)) tuples - 'key__socks_options', # dict - 'key_assert_hostname', # bool or string - 'key_assert_fingerprint', # str - 'key_server_hostname', # str + "key_scheme", # str + "key_host", # str + "key_port", # int + "key_timeout", # int or float or Timeout + "key_retries", # int or Retry + "key_strict", # bool + "key_block", # bool + "key_source_address", # str + "key_key_file", # str + "key_key_password", # str + "key_cert_file", # str + "key_cert_reqs", # str + "key_ca_certs", # str + "key_ssl_version", # str + "key_ca_cert_dir", # str + "key_ssl_context", # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext + "key_maxsize", # int + "key_headers", # dict + "key__proxy", # parsed proxy url + "key__proxy_headers", # dict + "key_socket_options", # list of (level (int), optname (int), value (int or str)) tuples + "key__socks_options", # dict + "key_assert_hostname", # bool or string + "key_assert_fingerprint", # str + "key_server_hostname", # str ) #: The namedtuple class used to construct keys for the connection pool. #: All custom key schemes should include the fields in this key at a minimum. -PoolKey = collections.namedtuple('PoolKey', _key_fields) +PoolKey = collections.namedtuple("PoolKey", _key_fields) def _default_key_normalizer(key_class, request_context): @@ -80,24 +93,24 @@ def _default_key_normalizer(key_class, request_context): """ # Since we mutate the dictionary, make a copy first context = request_context.copy() - context['scheme'] = context['scheme'].lower() - context['host'] = context['host'].lower() + context["scheme"] = context["scheme"].lower() + context["host"] = context["host"].lower() # These are both dictionaries and need to be transformed into frozensets - for key in ('headers', '_proxy_headers', '_socks_options'): + for key in ("headers", "_proxy_headers", "_socks_options"): if key in context and context[key] is not None: context[key] = frozenset(context[key].items()) # The socket_options key may be a list and needs to be transformed into a # tuple. - socket_opts = context.get('socket_options') + socket_opts = context.get("socket_options") if socket_opts is not None: - context['socket_options'] = tuple(socket_opts) + context["socket_options"] = tuple(socket_opts) # Map the kwargs to the names in the namedtuple - this is necessary since # namedtuples can't have fields starting with '_'. for key in list(context.keys()): - context['key_' + key] = context.pop(key) + context["key_" + key] = context.pop(key) # Default to ``None`` for keys missing from the context for field in key_class._fields: @@ -112,14 +125,11 @@ def _default_key_normalizer(key_class, request_context): #: Each PoolManager makes a copy of this dictionary so they can be configured #: globally here, or individually on the instance. key_fn_by_scheme = { - 'http': functools.partial(_default_key_normalizer, PoolKey), - 'https': functools.partial(_default_key_normalizer, PoolKey), + "http": functools.partial(_default_key_normalizer, PoolKey), + "https": functools.partial(_default_key_normalizer, PoolKey), } -pool_classes_by_scheme = { - 'http': HTTPConnectionPool, - 'https': HTTPSConnectionPool, -} +pool_classes_by_scheme = {"http": HTTPConnectionPool, "https": HTTPSConnectionPool} class PoolManager(RequestMethods): @@ -155,8 +165,7 @@ class PoolManager(RequestMethods): def __init__(self, num_pools=10, headers=None, **connection_pool_kw): RequestMethods.__init__(self, headers) self.connection_pool_kw = connection_pool_kw - self.pools = RecentlyUsedContainer(num_pools, - dispose_func=lambda p: p.close()) + self.pools = RecentlyUsedContainer(num_pools, dispose_func=lambda p: p.close()) # Locally set the pool classes and keys so other PoolManagers can # override them. @@ -189,10 +198,10 @@ class PoolManager(RequestMethods): # this function has historically only used the scheme, host, and port # in the positional args. When an API change is acceptable these can # be removed. - for key in ('scheme', 'host', 'port'): + for key in ("scheme", "host", "port"): request_context.pop(key, None) - if scheme == 'http': + if scheme == "http": for kw in SSL_KEYWORDS: request_context.pop(kw, None) @@ -207,7 +216,7 @@ class PoolManager(RequestMethods): """ self.pools.clear() - def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): + def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None): """ Get a :class:`ConnectionPool` based on the host, port, and scheme. @@ -222,11 +231,11 @@ class PoolManager(RequestMethods): raise LocationValueError("No host specified.") request_context = self._merge_pool_kwargs(pool_kwargs) - request_context['scheme'] = scheme or 'http' + request_context["scheme"] = scheme or "http" if not port: - port = port_by_scheme.get(request_context['scheme'].lower(), 80) - request_context['port'] = port - request_context['host'] = host + port = port_by_scheme.get(request_context["scheme"].lower(), 80) + request_context["port"] = port + request_context["host"] = host return self.connection_from_context(request_context) @@ -237,7 +246,7 @@ class PoolManager(RequestMethods): ``request_context`` must at least contain the ``scheme`` key and its value must be a key in ``key_fn_by_scheme`` instance variable. """ - scheme = request_context['scheme'].lower() + scheme = request_context["scheme"].lower() pool_key_constructor = self.key_fn_by_scheme[scheme] pool_key = pool_key_constructor(request_context) @@ -259,9 +268,9 @@ class PoolManager(RequestMethods): return pool # Make a fresh ConnectionPool of the desired type - scheme = request_context['scheme'] - host = request_context['host'] - port = request_context['port'] + scheme = request_context["scheme"] + host = request_context["host"] + port = request_context["port"] pool = self._new_pool(scheme, host, port, request_context=request_context) self.pools[pool_key] = pool @@ -279,8 +288,9 @@ class PoolManager(RequestMethods): not used. """ u = parse_url(url) - return self.connection_from_host(u.host, port=u.port, scheme=u.scheme, - pool_kwargs=pool_kwargs) + return self.connection_from_host( + u.host, port=u.port, scheme=u.scheme, pool_kwargs=pool_kwargs + ) def _merge_pool_kwargs(self, override): """ @@ -314,11 +324,11 @@ class PoolManager(RequestMethods): u = parse_url(url) conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme) - kw['assert_same_host'] = False - kw['redirect'] = False + kw["assert_same_host"] = False + kw["redirect"] = False - if 'headers' not in kw: - kw['headers'] = self.headers.copy() + if "headers" not in kw: + kw["headers"] = self.headers.copy() if self.proxy is not None and u.scheme == "http": response = conn.urlopen(method, url, **kw) @@ -334,33 +344,37 @@ class PoolManager(RequestMethods): # RFC 7231, Section 6.4.4 if response.status == 303: - method = 'GET' + method = "GET" - retries = kw.get('retries') + retries = kw.get("retries") if not isinstance(retries, Retry): retries = Retry.from_int(retries, redirect=redirect) # Strip headers marked as unsafe to forward to the redirected location. # Check remove_headers_on_redirect to avoid a potential network call within # conn.is_same_host() which may use socket.gethostbyname() in the future. - if (retries.remove_headers_on_redirect - and not conn.is_same_host(redirect_location)): - headers = list(six.iterkeys(kw['headers'])) + if retries.remove_headers_on_redirect and not conn.is_same_host( + redirect_location + ): + headers = list(six.iterkeys(kw["headers"])) for header in headers: if header.lower() in retries.remove_headers_on_redirect: - kw['headers'].pop(header, None) + kw["headers"].pop(header, None) try: retries = retries.increment(method, url, response=response, _pool=conn) except MaxRetryError: if retries.raise_on_redirect: + response.drain_conn() raise return response - kw['retries'] = retries - kw['redirect'] = redirect + kw["retries"] = retries + kw["redirect"] = redirect log.info("Redirecting %s -> %s", url, redirect_location) + + response.drain_conn() return self.urlopen(method, redirect_location, **kw) @@ -391,12 +405,21 @@ class ProxyManager(PoolManager): """ - def __init__(self, proxy_url, num_pools=10, headers=None, - proxy_headers=None, **connection_pool_kw): + def __init__( + self, + proxy_url, + num_pools=10, + headers=None, + proxy_headers=None, + **connection_pool_kw + ): if isinstance(proxy_url, HTTPConnectionPool): - proxy_url = '%s://%s:%i' % (proxy_url.scheme, proxy_url.host, - proxy_url.port) + proxy_url = "%s://%s:%i" % ( + proxy_url.scheme, + proxy_url.host, + proxy_url.port, + ) proxy = parse_url(proxy_url) if not proxy.port: port = port_by_scheme.get(proxy.scheme, 80) @@ -408,45 +431,59 @@ class ProxyManager(PoolManager): self.proxy = proxy self.proxy_headers = proxy_headers or {} - connection_pool_kw['_proxy'] = self.proxy - connection_pool_kw['_proxy_headers'] = self.proxy_headers + connection_pool_kw["_proxy"] = self.proxy + connection_pool_kw["_proxy_headers"] = self.proxy_headers - super(ProxyManager, self).__init__( - num_pools, headers, **connection_pool_kw) + super(ProxyManager, self).__init__(num_pools, headers, **connection_pool_kw) - def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): + def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None): if scheme == "https": return super(ProxyManager, self).connection_from_host( - host, port, scheme, pool_kwargs=pool_kwargs) + host, port, scheme, pool_kwargs=pool_kwargs + ) return super(ProxyManager, self).connection_from_host( - self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs) + self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs + ) def _set_proxy_headers(self, url, headers=None): """ Sets headers needed by proxies: specifically, the Accept and Host headers. Only sets headers not provided by the user. """ - headers_ = {'Accept': '*/*'} + headers_ = {"Accept": "*/*"} netloc = parse_url(url).netloc if netloc: - headers_['Host'] = netloc + headers_["Host"] = netloc if headers: headers_.update(headers) return headers_ + def _validate_proxy_scheme_url_selection(self, url_scheme): + if url_scheme == "https" and self.proxy.scheme == "https": + warnings.warn( + "Your proxy configuration specified an HTTPS scheme for the proxy. " + "Are you sure you want to use HTTPS to contact the proxy? " + "This most likely indicates an error in your configuration. " + "Read this issue for more info: " + "https://github.com/urllib3/urllib3/issues/1850", + InvalidProxyConfigurationWarning, + stacklevel=3, + ) + def urlopen(self, method, url, redirect=True, **kw): "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute." u = parse_url(url) + self._validate_proxy_scheme_url_selection(u.scheme) if u.scheme == "http": # For proxied HTTPS requests, httplib sets the necessary headers # on the CONNECT to the proxy. For HTTP, we'll definitely # need to set 'Host' at the very least. - headers = kw.get('headers', self.headers) - kw['headers'] = self._set_proxy_headers(url, headers) + headers = kw.get("headers", self.headers) + kw["headers"] = self._set_proxy_headers(url, headers) return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/request.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/request.py index 8f2f44b..55f160b 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/request.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/request.py @@ -4,7 +4,7 @@ from .filepost import encode_multipart_formdata from .packages.six.moves.urllib.parse import urlencode -__all__ = ['RequestMethods'] +__all__ = ["RequestMethods"] class RequestMethods(object): @@ -36,16 +36,25 @@ class RequestMethods(object): explicitly. """ - _encode_url_methods = {'DELETE', 'GET', 'HEAD', 'OPTIONS'} + _encode_url_methods = {"DELETE", "GET", "HEAD", "OPTIONS"} def __init__(self, headers=None): self.headers = headers or {} - def urlopen(self, method, url, body=None, headers=None, - encode_multipart=True, multipart_boundary=None, - **kw): # Abstract - raise NotImplementedError("Classes extending RequestMethods must implement " - "their own ``urlopen`` method.") + def urlopen( + self, + method, + url, + body=None, + headers=None, + encode_multipart=True, + multipart_boundary=None, + **kw + ): # Abstract + raise NotImplementedError( + "Classes extending RequestMethods must implement " + "their own ``urlopen`` method." + ) def request(self, method, url, fields=None, headers=None, **urlopen_kw): """ @@ -60,19 +69,18 @@ class RequestMethods(object): """ method = method.upper() - urlopen_kw['request_url'] = url + urlopen_kw["request_url"] = url if method in self._encode_url_methods: - return self.request_encode_url(method, url, fields=fields, - headers=headers, - **urlopen_kw) + return self.request_encode_url( + method, url, fields=fields, headers=headers, **urlopen_kw + ) else: - return self.request_encode_body(method, url, fields=fields, - headers=headers, - **urlopen_kw) + return self.request_encode_body( + method, url, fields=fields, headers=headers, **urlopen_kw + ) - def request_encode_url(self, method, url, fields=None, headers=None, - **urlopen_kw): + def request_encode_url(self, method, url, fields=None, headers=None, **urlopen_kw): """ Make a request using :meth:`urlopen` with the ``fields`` encoded in the url. This is useful for request methods like GET, HEAD, DELETE, etc. @@ -80,17 +88,24 @@ class RequestMethods(object): if headers is None: headers = self.headers - extra_kw = {'headers': headers} + extra_kw = {"headers": headers} extra_kw.update(urlopen_kw) if fields: - url += '?' + urlencode(fields) + url += "?" + urlencode(fields) return self.urlopen(method, url, **extra_kw) - def request_encode_body(self, method, url, fields=None, headers=None, - encode_multipart=True, multipart_boundary=None, - **urlopen_kw): + def request_encode_body( + self, + method, + url, + fields=None, + headers=None, + encode_multipart=True, + multipart_boundary=None, + **urlopen_kw + ): """ Make a request using :meth:`urlopen` with the ``fields`` encoded in the body. This is useful for request methods like POST, PUT, PATCH, etc. @@ -129,22 +144,28 @@ class RequestMethods(object): if headers is None: headers = self.headers - extra_kw = {'headers': {}} + extra_kw = {"headers": {}} if fields: - if 'body' in urlopen_kw: + if "body" in urlopen_kw: raise TypeError( - "request got values for both 'fields' and 'body', can only specify one.") + "request got values for both 'fields' and 'body', can only specify one." + ) if encode_multipart: - body, content_type = encode_multipart_formdata(fields, boundary=multipart_boundary) + body, content_type = encode_multipart_formdata( + fields, boundary=multipart_boundary + ) else: - body, content_type = urlencode(fields), 'application/x-www-form-urlencoded' + body, content_type = ( + urlencode(fields), + "application/x-www-form-urlencoded", + ) - extra_kw['body'] = body - extra_kw['headers'] = {'Content-Type': content_type} + extra_kw["body"] = body + extra_kw["headers"] = {"Content-Type": content_type} - extra_kw['headers'].update(headers) + extra_kw["headers"].update(headers) extra_kw.update(urlopen_kw) return self.urlopen(method, url, **extra_kw) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/response.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/response.py index 4f85793..7dc9b93 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/response.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/response.py @@ -13,8 +13,14 @@ except ImportError: from ._collections import HTTPHeaderDict from .exceptions import ( - BodyNotHttplibCompatible, ProtocolError, DecodeError, ReadTimeoutError, - ResponseNotChunked, IncompleteRead, InvalidHeader + BodyNotHttplibCompatible, + ProtocolError, + DecodeError, + ReadTimeoutError, + ResponseNotChunked, + IncompleteRead, + InvalidHeader, + HTTPError, ) from .packages.six import string_types as basestring, PY3 from .packages.six.moves import http_client as httplib @@ -25,10 +31,9 @@ log = logging.getLogger(__name__) class DeflateDecoder(object): - def __init__(self): self._first_try = True - self._data = b'' + self._data = b"" self._obj = zlib.decompressobj() def __getattr__(self, name): @@ -65,7 +70,6 @@ class GzipDecoderState(object): class GzipDecoder(object): - def __init__(self): self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) self._state = GzipDecoderState.FIRST_MEMBER @@ -96,6 +100,7 @@ class GzipDecoder(object): if brotli is not None: + class BrotliDecoder(object): # Supports both 'brotlipy' and 'Brotli' packages # since they share an import name. The top branches @@ -104,14 +109,14 @@ if brotli is not None: self._obj = brotli.Decompressor() def decompress(self, data): - if hasattr(self._obj, 'decompress'): + if hasattr(self._obj, "decompress"): return self._obj.decompress(data) return self._obj.process(data) def flush(self): - if hasattr(self._obj, 'flush'): + if hasattr(self._obj, "flush"): return self._obj.flush() - return b'' + return b"" class MultiDecoder(object): @@ -124,7 +129,7 @@ class MultiDecoder(object): """ def __init__(self, modes): - self._decoders = [_get_decoder(m.strip()) for m in modes.split(',')] + self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")] def flush(self): return self._decoders[0].flush() @@ -136,13 +141,13 @@ class MultiDecoder(object): def _get_decoder(mode): - if ',' in mode: + if "," in mode: return MultiDecoder(mode) - if mode == 'gzip': + if mode == "gzip": return GzipDecoder() - if brotli is not None and mode == 'br': + if brotli is not None and mode == "br": return BrotliDecoder() return DeflateDecoder() @@ -181,16 +186,31 @@ class HTTPResponse(io.IOBase): value of Content-Length header, if present. Otherwise, raise error. """ - CONTENT_DECODERS = ['gzip', 'deflate'] + CONTENT_DECODERS = ["gzip", "deflate"] if brotli is not None: - CONTENT_DECODERS += ['br'] + CONTENT_DECODERS += ["br"] REDIRECT_STATUSES = [301, 302, 303, 307, 308] - def __init__(self, body='', headers=None, status=0, version=0, reason=None, - strict=0, preload_content=True, decode_content=True, - original_response=None, pool=None, connection=None, msg=None, - retries=None, enforce_content_length=False, - request_method=None, request_url=None): + def __init__( + self, + body="", + headers=None, + status=0, + version=0, + reason=None, + strict=0, + preload_content=True, + decode_content=True, + original_response=None, + pool=None, + connection=None, + msg=None, + retries=None, + enforce_content_length=False, + request_method=None, + request_url=None, + auto_close=True, + ): if isinstance(headers, HTTPHeaderDict): self.headers = headers @@ -203,6 +223,7 @@ class HTTPResponse(io.IOBase): self.decode_content = decode_content self.retries = retries self.enforce_content_length = enforce_content_length + self.auto_close = auto_close self._decoder = None self._body = None @@ -218,13 +239,13 @@ class HTTPResponse(io.IOBase): self._pool = pool self._connection = connection - if hasattr(body, 'read'): + if hasattr(body, "read"): self._fp = body # Are we using the chunked-style of transfer encoding? self.chunked = False self.chunk_left = None - tr_enc = self.headers.get('transfer-encoding', '').lower() + tr_enc = self.headers.get("transfer-encoding", "").lower() # Don't incur the penalty of creating a list and then discarding it encodings = (enc.strip() for enc in tr_enc.split(",")) if "chunked" in encodings: @@ -246,7 +267,7 @@ class HTTPResponse(io.IOBase): location. ``False`` if not a redirect status code. """ if self.status in self.REDIRECT_STATUSES: - return self.headers.get('location') + return self.headers.get("location") return False @@ -257,6 +278,17 @@ class HTTPResponse(io.IOBase): self._pool._put_conn(self._connection) self._connection = None + def drain_conn(self): + """ + Read and discard any remaining HTTP response data in the response connection. + + Unread data in the HTTPResponse connection blocks the connection from being released back to the pool. + """ + try: + self.read() + except (HTTPError, SocketError, BaseSSLError, HTTPException): + pass + @property def data(self): # For backwords-compat with earlier urllib3 0.4 and earlier. @@ -285,18 +317,20 @@ class HTTPResponse(io.IOBase): """ Set initial length value for Response content if available. """ - length = self.headers.get('content-length') + length = self.headers.get("content-length") if length is not None: if self.chunked: # This Response will fail with an IncompleteRead if it can't be # received as chunked. This method falls back to attempt reading # the response before raising an exception. - log.warning("Received response with both Content-Length and " - "Transfer-Encoding set. This is expressly forbidden " - "by RFC 7230 sec 3.3.2. Ignoring Content-Length and " - "attempting to process response as Transfer-Encoding: " - "chunked.") + log.warning( + "Received response with both Content-Length and " + "Transfer-Encoding set. This is expressly forbidden " + "by RFC 7230 sec 3.3.2. Ignoring Content-Length and " + "attempting to process response as Transfer-Encoding: " + "chunked." + ) return None try: @@ -305,10 +339,12 @@ class HTTPResponse(io.IOBase): # (e.g. Content-Length: 42, 42). This line ensures the values # are all valid ints and that as long as the `set` length is 1, # all values are the same. Otherwise, the header is invalid. - lengths = set([int(val) for val in length.split(',')]) + lengths = set([int(val) for val in length.split(",")]) if len(lengths) > 1: - raise InvalidHeader("Content-Length contained multiple " - "unmatching values (%s)" % length) + raise InvalidHeader( + "Content-Length contained multiple " + "unmatching values (%s)" % length + ) length = lengths.pop() except ValueError: length = None @@ -324,7 +360,7 @@ class HTTPResponse(io.IOBase): status = 0 # Check for responses that shouldn't include a body - if status in (204, 304) or 100 <= status < 200 or request_method == 'HEAD': + if status in (204, 304) or 100 <= status < 200 or request_method == "HEAD": length = 0 return length @@ -335,14 +371,16 @@ class HTTPResponse(io.IOBase): """ # Note: content-encoding value should be case-insensitive, per RFC 7230 # Section 3.2 - content_encoding = self.headers.get('content-encoding', '').lower() + content_encoding = self.headers.get("content-encoding", "").lower() if self._decoder is None: if content_encoding in self.CONTENT_DECODERS: self._decoder = _get_decoder(content_encoding) - elif ',' in content_encoding: + elif "," in content_encoding: encodings = [ - e.strip() for e in content_encoding.split(',') - if e.strip() in self.CONTENT_DECODERS] + e.strip() + for e in content_encoding.split(",") + if e.strip() in self.CONTENT_DECODERS + ] if len(encodings): self._decoder = _get_decoder(content_encoding) @@ -361,10 +399,12 @@ class HTTPResponse(io.IOBase): if self._decoder: data = self._decoder.decompress(data) except self.DECODER_ERROR_CLASSES as e: - content_encoding = self.headers.get('content-encoding', '').lower() + content_encoding = self.headers.get("content-encoding", "").lower() raise DecodeError( "Received response with content-encoding: %s, but " - "failed to decode it." % content_encoding, e) + "failed to decode it." % content_encoding, + e, + ) if flush_decoder: data += self._flush_decoder() @@ -376,10 +416,10 @@ class HTTPResponse(io.IOBase): being used. """ if self._decoder: - buf = self._decoder.decompress(b'') + buf = self._decoder.decompress(b"") return buf + self._decoder.flush() - return b'' + return b"" @contextmanager def _error_catcher(self): @@ -399,20 +439,20 @@ class HTTPResponse(io.IOBase): except SocketTimeout: # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but # there is yet no clean way to get at it from this context. - raise ReadTimeoutError(self._pool, None, 'Read timed out.') + raise ReadTimeoutError(self._pool, None, "Read timed out.") except BaseSSLError as e: # FIXME: Is there a better way to differentiate between SSLErrors? - if 'read operation timed out' not in str(e): # Defensive: + if "read operation timed out" not in str(e): # Defensive: # This shouldn't happen but just in case we're missing an edge # case, let's avoid swallowing SSL errors. raise - raise ReadTimeoutError(self._pool, None, 'Read timed out.') + raise ReadTimeoutError(self._pool, None, "Read timed out.") except (HTTPException, SocketError) as e: # This includes IncompleteRead. - raise ProtocolError('Connection broken: %r' % e, e) + raise ProtocolError("Connection broken: %r" % e, e) # If no exception is thrown, we should avoid cleaning up # unnecessarily. @@ -467,17 +507,19 @@ class HTTPResponse(io.IOBase): return flush_decoder = False - data = None + fp_closed = getattr(self._fp, "closed", False) with self._error_catcher(): if amt is None: # cStringIO doesn't like amt=None - data = self._fp.read() + data = self._fp.read() if not fp_closed else b"" flush_decoder = True else: cache_content = False - data = self._fp.read(amt) - if amt != 0 and not data: # Platform-specific: Buggy versions of Python. + data = self._fp.read(amt) if not fp_closed else b"" + if ( + amt != 0 and not data + ): # Platform-specific: Buggy versions of Python. # Close the connection when no data is returned # # This is redundant to what httplib/http.client _should_ @@ -487,7 +529,10 @@ class HTTPResponse(io.IOBase): # no harm in redundantly calling close. self._fp.close() flush_decoder = True - if self.enforce_content_length and self.length_remaining not in (0, None): + if self.enforce_content_length and self.length_remaining not in ( + 0, + None, + ): # This is an edge case that httplib failed to cover due # to concerns of backward compatibility. We're # addressing it here to make sure IncompleteRead is @@ -507,7 +552,7 @@ class HTTPResponse(io.IOBase): return data - def stream(self, amt=2**16, decode_content=None): + def stream(self, amt=2 ** 16, decode_content=None): """ A generator wrapper for the read() method. A call will block until ``amt`` bytes have been read from the connection or until the @@ -552,15 +597,17 @@ class HTTPResponse(io.IOBase): headers = HTTPHeaderDict.from_httplib(headers) # HTTPResponse objects in Python 3 don't have a .strict attribute - strict = getattr(r, 'strict', 0) - resp = ResponseCls(body=r, - headers=headers, - status=r.status, - version=r.version, - reason=r.reason, - strict=strict, - original_response=r, - **response_kw) + strict = getattr(r, "strict", 0) + resp = ResponseCls( + body=r, + headers=headers, + status=r.status, + version=r.version, + reason=r.reason, + strict=strict, + original_response=r, + **response_kw + ) return resp # Backwards-compatibility methods for httplib.HTTPResponse @@ -582,13 +629,18 @@ class HTTPResponse(io.IOBase): if self._connection: self._connection.close() + if not self.auto_close: + io.IOBase.close(self) + @property def closed(self): - if self._fp is None: + if not self.auto_close: + return io.IOBase.closed.__get__(self) + elif self._fp is None: return True - elif hasattr(self._fp, 'isclosed'): + elif hasattr(self._fp, "isclosed"): return self._fp.isclosed() - elif hasattr(self._fp, 'closed'): + elif hasattr(self._fp, "closed"): return self._fp.closed else: return True @@ -599,11 +651,17 @@ class HTTPResponse(io.IOBase): elif hasattr(self._fp, "fileno"): return self._fp.fileno() else: - raise IOError("The file-like object this HTTPResponse is wrapped " - "around has no file descriptor") + raise IOError( + "The file-like object this HTTPResponse is wrapped " + "around has no file descriptor" + ) def flush(self): - if self._fp is not None and hasattr(self._fp, 'flush'): + if ( + self._fp is not None + and hasattr(self._fp, "flush") + and not getattr(self._fp, "closed", False) + ): return self._fp.flush() def readable(self): @@ -616,7 +674,7 @@ class HTTPResponse(io.IOBase): if len(temp) == 0: return 0 else: - b[:len(temp)] = temp + b[: len(temp)] = temp return len(temp) def supports_chunked_reads(self): @@ -626,7 +684,7 @@ class HTTPResponse(io.IOBase): attribute. If it is present we assume it returns raw chunks as processed by read_chunked(). """ - return hasattr(self._fp, 'fp') + return hasattr(self._fp, "fp") def _update_chunk_length(self): # First, we'll figure out length of a chunk and then @@ -634,7 +692,7 @@ class HTTPResponse(io.IOBase): if self.chunk_left is not None: return line = self._fp.fp.readline() - line = line.split(b';', 1)[0] + line = line.split(b";", 1)[0] try: self.chunk_left = int(line, 16) except ValueError: @@ -683,11 +741,13 @@ class HTTPResponse(io.IOBase): if not self.chunked: raise ResponseNotChunked( "Response is not chunked. " - "Header 'transfer-encoding: chunked' is missing.") + "Header 'transfer-encoding: chunked' is missing." + ) if not self.supports_chunked_reads(): raise BodyNotHttplibCompatible( "Body should be httplib.HTTPResponse like. " - "It should have have an fp attribute which returns raw chunks.") + "It should have have an fp attribute which returns raw chunks." + ) with self._error_catcher(): # Don't bother reading the body of a HEAD request. @@ -705,8 +765,9 @@ class HTTPResponse(io.IOBase): if self.chunk_left == 0: break chunk = self._handle_chunk(amt) - decoded = self._decode(chunk, decode_content=decode_content, - flush_decoder=False) + decoded = self._decode( + chunk, decode_content=decode_content, flush_decoder=False + ) if decoded: yield decoded @@ -724,7 +785,7 @@ class HTTPResponse(io.IOBase): if not line: # Some sites may not end with '\r\n'. break - if line == b'\r\n': + if line == b"\r\n": break # We read everything; close the "file". @@ -743,7 +804,7 @@ class HTTPResponse(io.IOBase): return self._request_url def __iter__(self): - buffer = [b""] + buffer = [] for chunk in self.stream(decode_content=True): if b"\n" in chunk: chunk = chunk.split(b"\n") diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__init__.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__init__.py index 2914bb4..a96c73a 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__init__.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__init__.py @@ -1,4 +1,5 @@ from __future__ import absolute_import + # For backwards compatibility, provide imports that used to be here. from .connection import is_connection_dropped from .request import make_headers @@ -14,43 +15,32 @@ from .ssl_ import ( ssl_wrap_socket, PROTOCOL_TLS, ) -from .timeout import ( - current_time, - Timeout, -) +from .timeout import current_time, Timeout from .retry import Retry -from .url import ( - get_host, - parse_url, - split_first, - Url, -) -from .wait import ( - wait_for_read, - wait_for_write -) +from .url import get_host, parse_url, split_first, Url +from .wait import wait_for_read, wait_for_write __all__ = ( - 'HAS_SNI', - 'IS_PYOPENSSL', - 'IS_SECURETRANSPORT', - 'SSLContext', - 'PROTOCOL_TLS', - 'Retry', - 'Timeout', - 'Url', - 'assert_fingerprint', - 'current_time', - 'is_connection_dropped', - 'is_fp_closed', - 'get_host', - 'parse_url', - 'make_headers', - 'resolve_cert_reqs', - 'resolve_ssl_version', - 'split_first', - 'ssl_wrap_socket', - 'wait_for_read', - 'wait_for_write' + "HAS_SNI", + "IS_PYOPENSSL", + "IS_SECURETRANSPORT", + "SSLContext", + "PROTOCOL_TLS", + "Retry", + "Timeout", + "Url", + "assert_fingerprint", + "current_time", + "is_connection_dropped", + "is_fp_closed", + "get_host", + "parse_url", + "make_headers", + "resolve_cert_reqs", + "resolve_ssl_version", + "split_first", + "ssl_wrap_socket", + "wait_for_read", + "wait_for_write", ) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-38.pyc index 57f8d5645886427058f0af80153937ba87f39aa4..480089d82405aaaca7b5862a4871a038845bc4a7 100644 GIT binary patch delta 112 zcmcb@{*#?Il$V!_0SGkz?TY8y$Q#e>oUWgdpPQ;*R9RY@m8oA`l&qhUn3tKFlbl~v zl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2(-keHmEn4VfZxr^CSkeP=O1a-It Ln0Oc^7zLOB9)BT- delta 75 zcmey#eubSkl$V!_0SKO#ZHTkl$Q#cr=cHefTcBT%S)iMlS6q^qlcQ^tVNzOQoSz61 YoV=ddQjm#<5d?L(1z33)CD;U50ZbtiN&o-= diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-38.pyc index cb6167528d78afec25513f3ac5a526b2c0828b19..36800f68861b6a033ea77b700c473e4bb8508a2d 100644 GIT binary patch delta 137 zcmca8@lAp^l$V!_0SGkz?TVM($a{gwIa5C)KQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+H_-^KYgARz{)8J{%hv oBRBu!uw!IQ+-%F`%gC5Bxtn`CzYGf_6C=|fE(;D04sH%P0H|v##Q*>R delta 100 zcmew+aZ!Rdl$V!_0SKO#ZHSZK$a{fF&PBf@w?Mxjvp_d9uec;JCr8&P!=$vrI6o02 zxLJWYfR&MNav{e?#?Z~moOX<iv73{)d>I)tCU4;0&M(En$i%?(pUZ@UgM*tx4gd_P B8`S^+ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-38.pyc index 07b9ee96e0d3c0e7822048dedaf53fb640a49fb1..2ea081584b5fde3668843417a220de51c67b4391 100644 GIT binary patch delta 94 zcmZqVSjNE<%FD~e00f%<cExYxv1W8m(a*@wP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7b@$~cD!0GWFrO#lD@ delta 57 zcmZ3+(a6CQ%FD~e00hs=HpFe@v1XLB*DuK}&@ad=(9O&%E=kPE(KX62DXlQhPXq~W J?qZz71OU>Q5!nC$ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-38.pyc index 2d101c6accd35913a31e582ba58abd2d975d92d1..6603d3cb751d629963f1f89c28e8d811c7e1d571 100644 GIT binary patch delta 234 zcmaDYIY){&l$V!_0SGkz?TUZCk(Za<IZZz!KQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+H_-vIV=1rWOk$3nLdJ z6A<$-u`qHVVJRS+g^}$)3lq~nE|$%6+4C3~qc-z!USU$p0lKAF4&)+k9!4RcZV1Wr xpNE+P$Yc7?#tJlX@;~n5T53Q=JV3Jrz~+Ng@-eb8aWJv5FfhX5FD?%bApi?nFW&$F delta 164 zcmbOu^;(iQl$V!_0SKO#ZHW7^k(ZZU&QZT4w?Mxjvp_d9uec;JCr8&P!=$vrI6o02 zI60QxhEZkmEOseACPsn(9Ly|?5PI_=_B=+$kj;jiSD56|fF>4;fz0LRVH5(Y0FeSr v9E@B*^=y;1d5)_o0VR1Dd6)!%7-R+yBOfCh69*F;GXo<?Bg20#Ck`P1H-jIL diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-38.pyc index f393f9672f40976137819f7c5df68fc893b6a88d..89f52ff5b1d0073055509f274f950b849065a06f 100644 GIT binary patch delta 119 zcmbQozn`Bsl$V!_0SGkz?TY8!$ScO=oUWgdpPQ;*R9RY@m8oA`l&qhUn3tKFlbl~v zl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2(-keHmEn4Vg^*^$YMnM(p>t^g0C U5Yy(FtT~K~UX$6_r!%Sm0Mqd!!vFvP delta 86 zcmdnbKaZa`l$V!_0SKO#ZHSZF$ScMq=cHefTcBT%S)iMlS6q^qlcQ^tVNzOQoSz61 k+?>Yb#mpxI(jvga$i~R_pN)C*F4i1IM(@e$?9&-l0SP%4sQ>@~ diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-38.pyc index a8274628dd2ef922a8dad672b4b93ed160855408..ec8be23000f83433de570dc13b5a7b588a36b262 100644 GIT binary patch delta 2387 zcmbVOO>7iZ9G~}Qc6N65yWN)Ux)x~5$5OfrR0F|UYSe%T1{6e_;4s~J+iuz2S>Mb; z+bk(qu9}c{AjX7%p12re4@ML8q%rZpjl|*L$peWOBpxI}{r_jnwplSTcG6$o`@i@9 z{&@SVb)UsfMx(j}f4Rrs7+;NDiDk(bSBBZ)YH~73Br9MAD_zy@$!;Ps`Fe`=+#r*^ zEMRF?$kMH_6|thzfh9V*;h<#2toUWginH{RJlV(kti%#weMaWWoe2^Y8%Qzi>BqP| zH~%W<_VPUWId!xj^m2rUR$<1jvI3uPG-k^MhZhT$Su3+j(dI65@^kYGg>$TSu23mY z73%Zuj9nYe?<+WEmyOiT;#qT=IbxwVAO0SMISPO(iRIn{q)R;L{lOYSJzEgAB5XtG zLfC<jLl{Qbi7<jtK-h(_2cc~!AAqf=8AiEQb`9fG*f}U&N{VOG{W2vHF`gdK<3M>G z&rXQh^z(~NX*Oz+52F`olU|QC$qhmzH{O(%NJ(nakH}k6j=qtL^8ab4Zz39-OL&S^ zF1j6p7XP!yZAqTms9UDXJjI=_vz*LFLA*!Lp7+$c$<3<M84|h1&i{xWV}K+=iL&-3 z*Os_?pvJ|uzOTtP@lIx(q{P+CR#<<V$@F!Gxy0=%MB2T(d_SX+!ETV8BOaOSRIZIx z%<7b7j^7vA?0c%8ykT)Mn<k^;<Lq#Fom_D{+tYIo4aEYGR0^hct<V)Eu>40hNq`~P zzi(h216=Zw;IqRF&Rjlkm?f9-hr;Z?HFg>fZ?48h<IJhsHHYzcf!b+de44rI`E?>D zH&*tVc=Z&j2sjnS>fCr5uYY8eY~GTPBI40TXZ+X`UOok@9Brj2I0fxsmr9)m#Eh1d z)#I%AeAC3xc3_0slz6sD;9t5<ur{$udDeoe1PWb_Y(7C=mRrqGM4b%PwY=tMVC~yp zcRMutRt*pcv_D=#y0|uw&t%}fD>aErmMBj&$t=A<{Jkvh3|!u)@G-c+BPcay^YV1L zW>yRa1A}uFh&NZgl!3HfpSUpC7vF=*@Rp?LL?z<J;O$XgTnI>9LzqG6NN&t1I}ljY zYU$Z8J{$VwMH~!Xpi!?gz8YDMJ>AKhLf$Had1SS6V@_4r#PWArLbRuf_x;)8w>9>s zmlp9<I+RoVT=BSgylvp64s$f$8Yr~a(4Ai3l7c!>Xo4uRN|Y5!>0>Hue=Wq`#B$7+ z9kFrK2H|e6p8nVIaTs;0rE&!-mmh)6lWK{yO1fw_YVJQ;Is%rkxf!$JxXe1eJf8bR zCWnN#b8xebBGis4vu?-~ME}Uny}mh7R2}4un`LN?y|8=gAfCm8vj|mjY2@Id-@-B6 z??-SEf(YXX2LN)()gU4vfp7*P3E%~cx@}jyu;IAS4K6o}>}ke&5jb}nj^X?71&ZJ* z^B;!&9A}OH3V0!yY^~&WW<OM}6*;T2np?tLVH--_;!=JhlOQTpNNhz_6qqmV@1YtJ zck@3Tnn2+=Q6UctxW>5TNXwzldN4pa3<l#?yO$_kp|UE`N8-1_Np&~yLSY?^rYWxp zbJzC8qbTw@1Pq=RE>=v(X;mqI1<C&Cz~RMBgmzc^J<HeS0#DyZ@Dp$mSC<ghZ1h(+ z^LYvYch2J5fErQeC`3R}VpNwEr5%H{XtY+p>sz&McsHY3QcGyMu4$^C&;YfNp3=e+ zX@7s}r+g*%WRRbG#?uX>)NmV|L4+ufT7xuL5lg#s>Iozq7hmokIo=v4+LPZ2+%L%x z4CEvB^fWZY2Y7WH0SnGk?WtJ?Zz%f1UqI;eRt)bM>KzJ2WF6g-BJg-57A5?4{0&-> B0G<E< delta 2303 zcmbVNU1%Id9N(GS+uPgQyCiLzUeh$qM;q>J^U+JK_UoEjNYGYWtd){}Y&W-a$(p;{ zV|LG`7(F3<5-gO#Cy}=JR238gN*}~G5q$7PM3$ltR@6sDD2O)x|8q$zTZ`Zg_uHA- z`G5cCx4*I<oy@6p+EC#4)5{;7AK8C3(?dSEx`Ry;#fdwKN=J3w^g5!j*!A_S^9GsT zz~YYXBpt&^Ii{1IjW5yZt|`UIIBk~|r;Tk~icM!()@ffNENgAL8cq;RY$m1UH^{f0 zxh-IaBm8k_G^o}`>u!D6t@(jnsSFq9b~hHrJsUU0hg~D7kKvrJ0%%11+;xa_h}_1{ zn}eug8^U&kA%qTuJVFlPF@zlmI}t_@MiF))-1mX^!!pz@%dNSAWnF`nkBSvdBXZDo zq7s#A#B8krO?;sfD*Wt#k%6;EQR;-amVLbGkT=a&=_0+JUL-dNQG(2(vP8<tBE3RR zDtY=`-sJz&dvrYC7OIY03Ld4S`ClnOC85@+J9fZAHMmq~`4}(YCY`?+YIU32RX>`Z zSdCr0g)#O4D1>506ghDAVBFP6O8l_t78w%nbQj5bal3nHHx?&MIIL_pDnXb6RTgIf zciBT`^fLFVP>A4*<vp8qGPn*T^CTn-QGfIU6}vj)*u~qz?m53z))wm>#;R^DOg(k@ z$kF4Ilh(6`Ph)W6yPh4pA_Z@sWq~zgm*%~4*$Uh$`v$~)tfiuvL|@VAa&b!sAq8=w z_sM~Xa0g_`XEKUQmR$}Qza!r3{q(?DkiNN^O`S8p?$vz8Ps46BfHpLbSy+|-T@mkY zt@K~Oqb~x4algV?ou7}$im|><dQTCPeSY!y+F@?PEKgfiOsobKwV1J_#<iF=akp=x zcK`$z3GZ4|uEX;N!N%oX4m2w4kmWP|FOVYTGib;`8?D&51#{_PJ&2f*u9yT;DcK~c zir)rC44emGARuDj;N>aG_oGG);O45=F~)gBRoH2{zE$#SHC75-uV%p!kN2Q%3X+N{ zdbfQwE;S`losLjOh*T?sdN{M4mWBb*xBdHr$P;0_QLi(;nmLZekIG6Psw|lEoL0H) znF`A-9~er~4fA+jQjNUN$Sq-3Z0*b@^Qx=`&xluY1LF~Qbm<LLeiw#<Ev_UCAQ+$- zY7)9aq5H(wxhv-$$r4YaC9UjMpz%0T&sy!xR!5b*MlE>ga+zS4EzH>sKVZ(`<<IhO z$H<g8Gd$Q|MHSkk7zL<PTpQl`gmlM5(+SSF?Lueofz`jV@EpEy5#|LQnVOLoG>z-M z2pl1Sa1fygkndPc8E&*8V3YB7fG}>=J+Bg`Ecir}<^yh**h9{W_eVAr<re@mD%n0v zu2IdUXjzkPt;AWC)q-cR2-x6?Dd^}#w?@<zjcPPYRiHVl$U*2|T3nnR{c`dUDlY&) z$`^2sDaezS@6keA&@y#yS#O~YY)=KhBMQAIys=Z-7_6aR&ZV=ISHzvMT=N+0@Nopp zQkW`LY~OD+A3uWI^2Q^{@Cyj{@1?wT{2xijw;qDb^lLb4B0TU=&iZk0JwOlq{pRz4 zI#Czy$BogiXt4}6Vk$K-8?B7AW`7#pdK)EXTF>b1x?$+LX0+=Xj3hjh3Pi1}7)Pan zUt+MxcZY^$l^a2WGsq3z;uhH@D&Fj@D>8-c+DY6zA@&xAkA-?2%5BfWcS5#Z5;*f1 w9E7HS9Z$*L!KMl|Z{{T+32BM%!*|g@#V3VrU46P4GgKMJil(+V6&$g@0WQ$rS^xk5 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-38.pyc index 31c6827fa7467770890975188b47ec43a00130a6..7187a181f97942f1ecae347b7b5f10b30ba7599c 100644 GIT binary patch delta 3199 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 HsmA^XPvE=G delta 2976 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 G*ZdEj>}p~F diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-38.pyc index 9c925926431796e5e1fd934a99aee1c7d1957412..ee2ddd16be7a5405f096ba61d93856f4c11f5b35 100644 GIT binary patch delta 718 zcmYjPzi-n(7|nNf?2GL<Y1|(wRLBJhHBuW7fYbqmfOhD@Qedb+mdRbHp|K<T656O6 z6$4v!Gw>fEQ7@<<Mi2vREOcN*Vg?DJl5iK2mb2{d`M&qw>E7MPrMJt)o5iA$6QkPO z_YZc9-(hq2*Zgg~R-gva3Es&)f;Cg%0x<^IA||nRa%)9WB(|tFDUq_MC0Zt9q%z=) z3G9&Z0j?0VnyXHH(QkxJ8n;>SBin{k>Xo@La#LE5Ba&8K7P}9FkhzUGaRXOOMzqet zI5OPf2pFTy7L&w4$dV3C_^15&@)2RE;a~MhKBt|<qegaJD}eR?V*HkVXVPWs)NKVx z(4>qeBQpP>&kOa`k(yuDo@Os`BY&;ot;bF3C0p(G{m@I3x<`U2q#N}(VKl96Zgss5 zjXK^&c-L!fvGq7QS6lSbkkN%!P=65Iqba{&*TCn*-e17JpU_s~`&1;KS~7n?fI*ed zVYfWYsy3iyE2W>xa!WEVN~VcHLlsbwAvCD3st7EoNDNvZ^^LrA5`ReRp+3&r=(v-m z&SM16vfmSXV7`!!NIF{C>#1#kH+*rr0cHMtIxyYi<Jmjmfb(9G2NwkomsPUUCl3HV zXT6zs%B63zKO@a5xQ~$0Lkj+bRO1lo252w?lQ53D<D-owG$20vcO$9}S7xtb-S<-_ uBH>H3t7jZ(=ZcTWWJN_~4Hs0g4`V^RC2V68+x*q+6H~PSBTLm(Tlot)X}E#_ delta 592 zcmX|-&ubGw6vy*sH?xz;{>YD7tidp;C>GNeG#)%E3icp~KTwJqmdwU3G}&b{t>O<T zSUeOI!hkpb13_^G!GkC9CWr?QdhjTC@nWGDyUrx0Zy4T}_dfHTnfLzOr?bvg$DuhD zKi6N~Iy!WIff(*IuNSz*$!6{mEYqOC3!IL0kr%nWnOnBG!(Ejf?(ve!Zs74UuZ)<I z(p5e+(q)b==jQf(v#x}_AX*dtmvjT_W=llujvorvjS}XwPSo!Q9T7%-<_i(@V!;&P zvq6xo2MJ~4kU#RR+Jt3dY^cD!eu>P=i`bJ(<f+`o_vJ(D#`L7g#7e+oKk<8k2om|* zYLZDyp2A1cCGsa<KfNe=@nRgt^I?A={MFU@<14MTyC))F7v+Y#05|1J_uVn8-5!Xf z-R`Kd4QxF;KtOV)UfDhG|7RC8l|J*fjgz-E*wkQ=07exs5e0$}*q}7v%r=yPs^VR0 zxM*BSKUW_kc#>Y5ehuDp?SQp|O~K64sr?TCUdZ807xHpv#!vZyDtK@AD5Cw-t=e~h z4{7({N8`{}-K%SdG6k9;M0Sxu|DrqvtY48~Brh~-P?2HdjC|9$)Tm5OsF$5LQ3(?h a0X?j?M?6v_j+~p_DjK%B$u_a+8vg)?Adr0k diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-38.pyc index 4a6d247b0e3b5feb2b4a2e07c4504838793d8012..771a183a7c7e8459093427921f76193a4b47bb8a 100644 GIT binary patch literal 10727 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 YXaTCC4n8oBo9`NL8*dr?hH2#f4;YiDp#T5? delta 3548 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 diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-38.pyc index b05c7d1094e0031f53dbf0d78f89e04c91a208eb..88c31defd9174d7b6d053547d28a65beebdc2149 100644 GIT binary patch delta 196 zcmV;#06YJJ7^fHwRSgXa00000DgL@&9<dF$0YhUiXm4$0FLHTxb!urZb8=%ZWMOV; zWo%<_a&%>LE_iu*FLq^ab}wvcVlQxcbZBpGGcGtUb7^#CEpTCDYhh<)bCcr%CIJqU z3IcKgDzkk8IRODMv$q3z0Rcy|F$EX_0cMj*2C)HJll%s&0dAA12f+bylWGXJ0e`b1 y2?PNFj*}+}>;aXN6bsKE0s;XL0S*BY0ty2V8VUjm1_&1l6ABav1PBcX4+;l3lQ&2J delta 159 zcmZ23(Imke%FD~e00hs=HpEG9<lVt2XQyA1TcBT%S)iMlS6q^qlcQ^tVNzOQoSz61 zoXo+b#>hKapQ(sZbMqo5OGZZB&3Bk985vzRhp|d9GA2*XXWPgaK3S1{HDmVVv+M^M z^C$OnY-g<5?9R!;$k;vEhwBaFq{)`t=j9oh7zG&l7=@U)m<6P`n7CLt#JPmIL^xPD JcscmF*a29nC`teT diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/connection.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/connection.py index 5ad70b2..86f0a3b 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/connection.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/connection.py @@ -14,7 +14,7 @@ def is_connection_dropped(conn): # Platform-specific Note: For platforms like AppEngine, this will always return ``False`` to let the platform handle connection recycling transparently for us. """ - sock = getattr(conn, 'sock', False) + sock = getattr(conn, "sock", False) if sock is False: # Platform-specific: AppEngine return False if sock is None: # Connection already closed (such as by httplib). @@ -30,8 +30,12 @@ def is_connection_dropped(conn): # Platform-specific # library test suite. Added to its signature is only `socket_options`. # One additional modification is that we avoid binding to IPv6 servers # discovered in DNS if the system doesn't have IPv6 functionality. -def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, - source_address=None, socket_options=None): +def create_connection( + address, + timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None, + socket_options=None, +): """Connect to *address* and return the socket object. Convenience function. Connect to *address* (a 2-tuple ``(host, @@ -45,8 +49,8 @@ def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, """ host, port = address - if host.startswith('['): - host = host.strip('[]') + if host.startswith("["): + host = host.strip("[]") err = None # Using the value from allowed_gai_family() in the context of getaddrinfo lets @@ -117,7 +121,7 @@ def _has_ipv6(host): # has_ipv6 returns true if cPython was compiled with IPv6 support. # It does not tell us if the system has IPv6 support enabled. To # determine that we must bind to an IPv6 address. - # https://github.com/shazow/urllib3/pull/611 + # https://github.com/urllib3/urllib3/pull/611 # https://bugs.python.org/issue658327 try: sock = socket.socket(socket.AF_INET6) @@ -131,4 +135,4 @@ def _has_ipv6(host): return has_ipv6 -HAS_IPV6 = _has_ipv6('::1') +HAS_IPV6 = _has_ipv6("::1") diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/request.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/request.py index 280b853..3b7bb54 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/request.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/request.py @@ -4,19 +4,25 @@ from base64 import b64encode from ..packages.six import b, integer_types from ..exceptions import UnrewindableBodyError -ACCEPT_ENCODING = 'gzip,deflate' +ACCEPT_ENCODING = "gzip,deflate" try: import brotli as _unused_module_brotli # noqa: F401 except ImportError: pass else: - ACCEPT_ENCODING += ',br' + ACCEPT_ENCODING += ",br" _FAILEDTELL = object() -def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, - basic_auth=None, proxy_basic_auth=None, disable_cache=None): +def make_headers( + keep_alive=None, + accept_encoding=None, + user_agent=None, + basic_auth=None, + proxy_basic_auth=None, + disable_cache=None, +): """ Shortcuts for generating request headers. @@ -56,27 +62,27 @@ def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, if isinstance(accept_encoding, str): pass elif isinstance(accept_encoding, list): - accept_encoding = ','.join(accept_encoding) + accept_encoding = ",".join(accept_encoding) else: accept_encoding = ACCEPT_ENCODING - headers['accept-encoding'] = accept_encoding + headers["accept-encoding"] = accept_encoding if user_agent: - headers['user-agent'] = user_agent + headers["user-agent"] = user_agent if keep_alive: - headers['connection'] = 'keep-alive' + headers["connection"] = "keep-alive" if basic_auth: - headers['authorization'] = 'Basic ' + \ - b64encode(b(basic_auth)).decode('utf-8') + headers["authorization"] = "Basic " + b64encode(b(basic_auth)).decode("utf-8") if proxy_basic_auth: - headers['proxy-authorization'] = 'Basic ' + \ - b64encode(b(proxy_basic_auth)).decode('utf-8') + headers["proxy-authorization"] = "Basic " + b64encode( + b(proxy_basic_auth) + ).decode("utf-8") if disable_cache: - headers['cache-control'] = 'no-cache' + headers["cache-control"] = "no-cache" return headers @@ -88,7 +94,7 @@ def set_file_position(body, pos): """ if pos is not None: rewind_body(body, pos) - elif getattr(body, 'tell', None) is not None: + elif getattr(body, "tell", None) is not None: try: pos = body.tell() except (IOError, OSError): @@ -110,16 +116,20 @@ def rewind_body(body, body_pos): :param int pos: Position to seek to in file. """ - body_seek = getattr(body, 'seek', None) + body_seek = getattr(body, "seek", None) if body_seek is not None and isinstance(body_pos, integer_types): try: body_seek(body_pos) except (IOError, OSError): - raise UnrewindableBodyError("An error occurred when rewinding request " - "body for redirect/retry.") + raise UnrewindableBodyError( + "An error occurred when rewinding request body for redirect/retry." + ) elif body_pos is _FAILEDTELL: - raise UnrewindableBodyError("Unable to record file position for rewinding " - "request body during a redirect/retry.") + raise UnrewindableBodyError( + "Unable to record file position for rewinding " + "request body during a redirect/retry." + ) else: - raise ValueError("body_pos must be of type integer, " - "instead it was %s." % type(body_pos)) + raise ValueError( + "body_pos must be of type integer, instead it was %s." % type(body_pos) + ) diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/response.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/response.py index 3d54864..715868d 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/response.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/response.py @@ -52,11 +52,10 @@ def assert_header_parsing(headers): # This will fail silently if we pass in the wrong kind of parameter. # To make debugging easier add an explicit check. if not isinstance(headers, httplib.HTTPMessage): - raise TypeError('expected httplib.Message, got {0}.'.format( - type(headers))) + raise TypeError("expected httplib.Message, got {0}.".format(type(headers))) - defects = getattr(headers, 'defects', None) - get_payload = getattr(headers, 'get_payload', None) + defects = getattr(headers, "defects", None) + get_payload = getattr(headers, "get_payload", None) unparsed_data = None if get_payload: @@ -84,4 +83,4 @@ def is_response_to_head(response): method = response._method if isinstance(method, int): # Platform-specific: Appengine return method == 3 - return method.upper() == 'HEAD' + return method.upper() == "HEAD" diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/retry.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/retry.py index 02429ee..ee30c91 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/retry.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/retry.py @@ -13,6 +13,7 @@ from ..exceptions import ( ReadTimeoutError, ResponseError, InvalidHeader, + ProxyError, ) from ..packages import six @@ -21,8 +22,9 @@ log = logging.getLogger(__name__) # Data structure for representing the metadata of requests that result in a retry. -RequestHistory = namedtuple('RequestHistory', ["method", "url", "error", - "status", "redirect_location"]) +RequestHistory = namedtuple( + "RequestHistory", ["method", "url", "error", "status", "redirect_location"] +) class Retry(object): @@ -146,21 +148,33 @@ class Retry(object): request. """ - DEFAULT_METHOD_WHITELIST = frozenset([ - 'HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']) + DEFAULT_METHOD_WHITELIST = frozenset( + ["HEAD", "GET", "PUT", "DELETE", "OPTIONS", "TRACE"] + ) RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) - DEFAULT_REDIRECT_HEADERS_BLACKLIST = frozenset(['Authorization']) + DEFAULT_REDIRECT_HEADERS_BLACKLIST = frozenset(["Authorization"]) #: Maximum backoff time. BACKOFF_MAX = 120 - def __init__(self, total=10, connect=None, read=None, redirect=None, status=None, - method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None, - backoff_factor=0, raise_on_redirect=True, raise_on_status=True, - history=None, respect_retry_after_header=True, - remove_headers_on_redirect=DEFAULT_REDIRECT_HEADERS_BLACKLIST): + def __init__( + self, + total=10, + connect=None, + read=None, + redirect=None, + status=None, + method_whitelist=DEFAULT_METHOD_WHITELIST, + status_forcelist=None, + backoff_factor=0, + raise_on_redirect=True, + raise_on_status=True, + history=None, + respect_retry_after_header=True, + remove_headers_on_redirect=DEFAULT_REDIRECT_HEADERS_BLACKLIST, + ): self.total = total self.connect = connect @@ -179,20 +193,25 @@ class Retry(object): self.raise_on_status = raise_on_status self.history = history or tuple() self.respect_retry_after_header = respect_retry_after_header - self.remove_headers_on_redirect = frozenset([ - h.lower() for h in remove_headers_on_redirect]) + self.remove_headers_on_redirect = frozenset( + [h.lower() for h in remove_headers_on_redirect] + ) def new(self, **kw): params = dict( total=self.total, - connect=self.connect, read=self.read, redirect=self.redirect, status=self.status, + connect=self.connect, + read=self.read, + redirect=self.redirect, + status=self.status, method_whitelist=self.method_whitelist, status_forcelist=self.status_forcelist, backoff_factor=self.backoff_factor, raise_on_redirect=self.raise_on_redirect, raise_on_status=self.raise_on_status, history=self.history, - remove_headers_on_redirect=self.remove_headers_on_redirect + remove_headers_on_redirect=self.remove_headers_on_redirect, + respect_retry_after_header=self.respect_retry_after_header, ) params.update(kw) return type(self)(**params) @@ -217,8 +236,11 @@ class Retry(object): :rtype: float """ # We want to consider only the last consecutive errors sequence (Ignore redirects). - consecutive_errors_len = len(list(takewhile(lambda x: x.redirect_location is None, - reversed(self.history)))) + consecutive_errors_len = len( + list( + takewhile(lambda x: x.redirect_location is None, reversed(self.history)) + ) + ) if consecutive_errors_len <= 1: return 0 @@ -274,7 +296,7 @@ class Retry(object): this method will return immediately. """ - if response: + if self.respect_retry_after_header and response: slept = self.sleep_for_retry(response) if slept: return @@ -285,6 +307,8 @@ class Retry(object): """ Errors when we're fairly sure that the server did not receive the request, so it should be safe to retry. """ + if isinstance(err, ProxyError): + err = err.original_error return isinstance(err, ConnectTimeoutError) def _is_read_error(self, err): @@ -315,8 +339,12 @@ class Retry(object): if self.status_forcelist and status_code in self.status_forcelist: return True - return (self.total and self.respect_retry_after_header and - has_retry_after and (status_code in self.RETRY_AFTER_STATUS_CODES)) + return ( + self.total + and self.respect_retry_after_header + and has_retry_after + and (status_code in self.RETRY_AFTER_STATUS_CODES) + ) def is_exhausted(self): """ Are we out of retries? """ @@ -327,8 +355,15 @@ class Retry(object): return min(retry_counts) < 0 - def increment(self, method=None, url=None, response=None, error=None, - _pool=None, _stacktrace=None): + def increment( + self, + method=None, + url=None, + response=None, + error=None, + _pool=None, + _stacktrace=None, + ): """ Return a new Retry object with incremented retry counters. :param response: A response object, or None, if the server did not @@ -351,7 +386,7 @@ class Retry(object): read = self.read redirect = self.redirect status_count = self.status - cause = 'unknown' + cause = "unknown" status = None redirect_location = None @@ -373,7 +408,7 @@ class Retry(object): # Redirect retry? if redirect is not None: redirect -= 1 - cause = 'too many redirects' + cause = "too many redirects" redirect_location = response.get_redirect_location() status = response.status @@ -384,16 +419,21 @@ class Retry(object): if response and response.status: if status_count is not None: status_count -= 1 - cause = ResponseError.SPECIFIC_ERROR.format( - status_code=response.status) + cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status) status = response.status - history = self.history + (RequestHistory(method, url, error, status, redirect_location),) + history = self.history + ( + RequestHistory(method, url, error, status, redirect_location), + ) new_retry = self.new( total=total, - connect=connect, read=read, redirect=redirect, status=status_count, - history=history) + connect=connect, + read=read, + redirect=redirect, + status=status_count, + history=history, + ) if new_retry.is_exhausted(): raise MaxRetryError(_pool, url, error or ResponseError(cause)) @@ -403,9 +443,10 @@ class Retry(object): return new_retry def __repr__(self): - return ('{cls.__name__}(total={self.total}, connect={self.connect}, ' - 'read={self.read}, redirect={self.redirect}, status={self.status})').format( - cls=type(self), self=self) + return ( + "{cls.__name__}(total={self.total}, connect={self.connect}, " + "read={self.read}, redirect={self.redirect}, status={self.status})" + ).format(cls=type(self), self=self) # For backwards compatibility (equivalent to pre-v1.9): diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/ssl_.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/ssl_.py index fbdef65..d3b463d 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/ssl_.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/ssl_.py @@ -2,14 +2,14 @@ from __future__ import absolute_import import errno import warnings import hmac -import re +import sys from binascii import hexlify, unhexlify from hashlib import md5, sha1, sha256 +from .url import IPV4_RE, BRACELESS_IPV6_ADDRZ_RE from ..exceptions import SSLError, InsecurePlatformWarning, SNIMissingWarning from ..packages import six -from ..packages.rfc3986 import abnf_regexp SSLContext = None @@ -18,11 +18,7 @@ IS_PYOPENSSL = False IS_SECURETRANSPORT = False # Maps the length of a digest to a possible hash function producing this digest -HASHFUNC_MAP = { - 32: md5, - 40: sha1, - 64: sha256, -} +HASHFUNC_MAP = {32: md5, 40: sha1, 64: sha256} def _const_compare_digest_backport(a, b): @@ -38,18 +34,7 @@ def _const_compare_digest_backport(a, b): return result == 0 -_const_compare_digest = getattr(hmac, 'compare_digest', - _const_compare_digest_backport) - -# Borrow rfc3986's regular expressions for IPv4 -# and IPv6 addresses for use in is_ipaddress() -_IP_ADDRESS_REGEX = re.compile( - r'^(?:%s|%s|%s)$' % ( - abnf_regexp.IPv4_RE, - abnf_regexp.IPv6_RE, - abnf_regexp.IPv6_ADDRZ_RFC4007_RE - ) -) +_const_compare_digest = getattr(hmac, "compare_digest", _const_compare_digest_backport) try: # Test for SSL features import ssl @@ -60,10 +45,12 @@ except ImportError: try: # Platform-specific: Python 3.6 from ssl import PROTOCOL_TLS + PROTOCOL_SSLv23 = PROTOCOL_TLS except ImportError: try: from ssl import PROTOCOL_SSLv23 as PROTOCOL_TLS + PROTOCOL_SSLv23 = PROTOCOL_TLS except ImportError: PROTOCOL_SSLv23 = PROTOCOL_TLS = 2 @@ -93,26 +80,29 @@ except ImportError: # insecure ciphers for security reasons. # - NOTE: TLS 1.3 cipher suites are managed through a different interface # not exposed by CPython (yet!) and are enabled by default if they're available. -DEFAULT_CIPHERS = ':'.join([ - 'ECDHE+AESGCM', - 'ECDHE+CHACHA20', - 'DHE+AESGCM', - 'DHE+CHACHA20', - 'ECDH+AESGCM', - 'DH+AESGCM', - 'ECDH+AES', - 'DH+AES', - 'RSA+AESGCM', - 'RSA+AES', - '!aNULL', - '!eNULL', - '!MD5', - '!DSS', -]) +DEFAULT_CIPHERS = ":".join( + [ + "ECDHE+AESGCM", + "ECDHE+CHACHA20", + "DHE+AESGCM", + "DHE+CHACHA20", + "ECDH+AESGCM", + "DH+AESGCM", + "ECDH+AES", + "DH+AES", + "RSA+AESGCM", + "RSA+AES", + "!aNULL", + "!eNULL", + "!MD5", + "!DSS", + ] +) try: from ssl import SSLContext # Modern SSL? except ImportError: + class SSLContext(object): # Platform-specific: Python 2 def __init__(self, protocol_version): self.protocol = protocol_version @@ -129,32 +119,35 @@ except ImportError: self.certfile = certfile self.keyfile = keyfile - def load_verify_locations(self, cafile=None, capath=None): + def load_verify_locations(self, cafile=None, capath=None, cadata=None): self.ca_certs = cafile if capath is not None: raise SSLError("CA directories not supported in older Pythons") + if cadata is not None: + raise SSLError("CA data not supported in older Pythons") + def set_ciphers(self, cipher_suite): self.ciphers = cipher_suite def wrap_socket(self, socket, server_hostname=None, server_side=False): warnings.warn( - 'A true SSLContext object is not available. This prevents ' - 'urllib3 from configuring SSL appropriately and may cause ' - 'certain SSL connections to fail. You can upgrade to a newer ' - 'version of Python to solve this. For more information, see ' - 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' - '#ssl-warnings', - InsecurePlatformWarning + "A true SSLContext object is not available. This prevents " + "urllib3 from configuring SSL appropriately and may cause " + "certain SSL connections to fail. You can upgrade to a newer " + "version of Python to solve this. For more information, see " + "https://urllib3.readthedocs.io/en/latest/advanced-usage.html" + "#ssl-warnings", + InsecurePlatformWarning, ) kwargs = { - 'keyfile': self.keyfile, - 'certfile': self.certfile, - 'ca_certs': self.ca_certs, - 'cert_reqs': self.verify_mode, - 'ssl_version': self.protocol, - 'server_side': server_side, + "keyfile": self.keyfile, + "certfile": self.certfile, + "ca_certs": self.ca_certs, + "cert_reqs": self.verify_mode, + "ssl_version": self.protocol, + "server_side": server_side, } return wrap_socket(socket, ciphers=self.ciphers, **kwargs) @@ -169,12 +162,11 @@ def assert_fingerprint(cert, fingerprint): Fingerprint as string of hexdigits, can be interspersed by colons. """ - fingerprint = fingerprint.replace(':', '').lower() + fingerprint = fingerprint.replace(":", "").lower() digest_length = len(fingerprint) hashfunc = HASHFUNC_MAP.get(digest_length) if not hashfunc: - raise SSLError( - 'Fingerprint of invalid length: {0}'.format(fingerprint)) + raise SSLError("Fingerprint of invalid length: {0}".format(fingerprint)) # We need encode() here for py32; works on py2 and p33. fingerprint_bytes = unhexlify(fingerprint.encode()) @@ -182,15 +174,18 @@ def assert_fingerprint(cert, fingerprint): cert_digest = hashfunc(cert).digest() if not _const_compare_digest(cert_digest, fingerprint_bytes): - raise SSLError('Fingerprints did not match. Expected "{0}", got "{1}".' - .format(fingerprint, hexlify(cert_digest))) + raise SSLError( + 'Fingerprints did not match. Expected "{0}", got "{1}".'.format( + fingerprint, hexlify(cert_digest) + ) + ) def resolve_cert_reqs(candidate): """ Resolves the argument to a numeric constant, which can be passed to the wrap_socket function/method from the ssl module. - Defaults to :data:`ssl.CERT_NONE`. + Defaults to :data:`ssl.CERT_REQUIRED`. If given a string it is assumed to be the name of the constant in the :mod:`ssl` module or its abbreviation. (So you can specify `REQUIRED` instead of `CERT_REQUIRED`. @@ -203,7 +198,7 @@ def resolve_cert_reqs(candidate): if isinstance(candidate, str): res = getattr(ssl, candidate, None) if res is None: - res = getattr(ssl, 'CERT_' + candidate) + res = getattr(ssl, "CERT_" + candidate) return res return candidate @@ -219,14 +214,15 @@ def resolve_ssl_version(candidate): if isinstance(candidate, str): res = getattr(ssl, candidate, None) if res is None: - res = getattr(ssl, 'PROTOCOL_' + candidate) + res = getattr(ssl, "PROTOCOL_" + candidate) return res return candidate -def create_urllib3_context(ssl_version=None, cert_reqs=None, - options=None, ciphers=None): +def create_urllib3_context( + ssl_version=None, cert_reqs=None, options=None, ciphers=None +): """All arguments have the same meaning as ``ssl_wrap_socket``. By default, this function does a lot of the same work that @@ -279,18 +275,41 @@ def create_urllib3_context(ssl_version=None, cert_reqs=None, context.options |= options + # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is + # necessary for conditional client cert authentication with TLS 1.3. + # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older + # versions of Python. We only enable on Python 3.7.4+ or if certificate + # verification is enabled to work around Python issue #37428 + # See: https://bugs.python.org/issue37428 + if (cert_reqs == ssl.CERT_REQUIRED or sys.version_info >= (3, 7, 4)) and getattr( + context, "post_handshake_auth", None + ) is not None: + context.post_handshake_auth = True + context.verify_mode = cert_reqs - if getattr(context, 'check_hostname', None) is not None: # Platform-specific: Python 3.2 + if ( + getattr(context, "check_hostname", None) is not None + ): # Platform-specific: Python 3.2 # We do our own verification, including fingerprints and alternative # hostnames. So disable it here context.check_hostname = False return context -def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, - ca_certs=None, server_hostname=None, - ssl_version=None, ciphers=None, ssl_context=None, - ca_cert_dir=None, key_password=None): +def ssl_wrap_socket( + sock, + keyfile=None, + certfile=None, + cert_reqs=None, + ca_certs=None, + server_hostname=None, + ssl_version=None, + ciphers=None, + ssl_context=None, + ca_cert_dir=None, + key_password=None, + ca_cert_data=None, +): """ All arguments except for server_hostname, ssl_context, and ca_cert_dir have the same meaning as they do when using :func:`ssl.wrap_socket`. @@ -308,18 +327,20 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, SSLContext.load_verify_locations(). :param key_password: Optional password if the keyfile is encrypted. + :param ca_cert_data: + Optional string containing CA certificates in PEM format suitable for + passing as the cadata parameter to SSLContext.load_verify_locations() """ context = ssl_context if context is None: # Note: This branch of code and all the variables in it are no longer # used by urllib3 itself. We should consider deprecating and removing # this code. - context = create_urllib3_context(ssl_version, cert_reqs, - ciphers=ciphers) + context = create_urllib3_context(ssl_version, cert_reqs, ciphers=ciphers) - if ca_certs or ca_cert_dir: + if ca_certs or ca_cert_dir or ca_cert_data: try: - context.load_verify_locations(ca_certs, ca_cert_dir) + context.load_verify_locations(ca_certs, ca_cert_dir, ca_cert_data) except IOError as e: # Platform-specific: Python 2.7 raise SSLError(e) # Py33 raises FileNotFoundError which subclasses OSError @@ -329,7 +350,7 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, raise SSLError(e) raise - elif ssl_context is None and hasattr(context, 'load_default_certs'): + elif ssl_context is None and hasattr(context, "load_default_certs"): # try to load OS default certs; works well on Windows (require Python3.4+) context.load_default_certs() @@ -349,20 +370,21 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, # extension should not be used according to RFC3546 Section 3.1 # We shouldn't warn the user if SNI isn't available but we would # not be using SNI anyways due to IP address for server_hostname. - if ((server_hostname is not None and not is_ipaddress(server_hostname)) - or IS_SECURETRANSPORT): + if ( + server_hostname is not None and not is_ipaddress(server_hostname) + ) or IS_SECURETRANSPORT: if HAS_SNI and server_hostname is not None: return context.wrap_socket(sock, server_hostname=server_hostname) warnings.warn( - 'An HTTPS request has been made, but the SNI (Server Name ' - 'Indication) extension to TLS is not available on this platform. ' - 'This may cause the server to present an incorrect TLS ' - 'certificate, which can cause validation failures. You can upgrade to ' - 'a newer version of Python to solve this. For more information, see ' - 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' - '#ssl-warnings', - SNIMissingWarning + "An HTTPS request has been made, but the SNI (Server Name " + "Indication) extension to TLS is not available on this platform. " + "This may cause the server to present an incorrect TLS " + "certificate, which can cause validation failures. You can upgrade to " + "a newer version of Python to solve this. For more information, see " + "https://urllib3.readthedocs.io/en/latest/advanced-usage.html" + "#ssl-warnings", + SNIMissingWarning, ) return context.wrap_socket(sock) @@ -375,18 +397,18 @@ def is_ipaddress(hostname): :param str hostname: Hostname to examine. :return: True if the hostname is an IP address, False otherwise. """ - if six.PY3 and isinstance(hostname, bytes): + if not six.PY2 and isinstance(hostname, bytes): # IDN A-label bytes are ASCII compatible. - hostname = hostname.decode('ascii') - return _IP_ADDRESS_REGEX.match(hostname) is not None + hostname = hostname.decode("ascii") + return bool(IPV4_RE.match(hostname) or BRACELESS_IPV6_ADDRZ_RE.match(hostname)) def _is_key_file_encrypted(key_file): """Detects if a key file is encrypted or not.""" - with open(key_file, 'r') as f: + with open(key_file, "r") as f: for line in f: # Look for Proc-Type: 4,ENCRYPTED - if 'ENCRYPTED' in line: + if "ENCRYPTED" in line: return True return False diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/timeout.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/timeout.py index a4d004a..b61fea7 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/timeout.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/timeout.py @@ -1,4 +1,5 @@ from __future__ import absolute_import + # The default socket timeout, used by httplib to indicate that no timeout was # specified by the user from socket import _GLOBAL_DEFAULT_TIMEOUT @@ -45,19 +46,20 @@ class Timeout(object): :type total: integer, float, or None :param connect: - The maximum amount of time to wait for a connection attempt to a server - to succeed. Omitting the parameter will default the connect timeout to - the system default, probably `the global default timeout in socket.py + The maximum amount of time (in seconds) to wait for a connection + attempt to a server to succeed. Omitting the parameter will default the + connect timeout to the system default, probably `the global default + timeout in socket.py <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. None will set an infinite timeout for connection attempts. :type connect: integer, float, or None :param read: - The maximum amount of time to wait between consecutive - read operations for a response from the server. Omitting - the parameter will default the read timeout to the system - default, probably `the global default timeout in socket.py + The maximum amount of time (in seconds) to wait between consecutive + read operations for a response from the server. Omitting the parameter + will default the read timeout to the system default, probably `the + global default timeout in socket.py <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. None will set an infinite timeout. @@ -91,14 +93,21 @@ class Timeout(object): DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT def __init__(self, total=None, connect=_Default, read=_Default): - self._connect = self._validate_timeout(connect, 'connect') - self._read = self._validate_timeout(read, 'read') - self.total = self._validate_timeout(total, 'total') + self._connect = self._validate_timeout(connect, "connect") + self._read = self._validate_timeout(read, "read") + self.total = self._validate_timeout(total, "total") self._start_connect = None - def __str__(self): - return '%s(connect=%r, read=%r, total=%r)' % ( - type(self).__name__, self._connect, self._read, self.total) + def __repr__(self): + return "%s(connect=%r, read=%r, total=%r)" % ( + type(self).__name__, + self._connect, + self._read, + self.total, + ) + + # __str__ provided for backwards compatibility + __str__ = __repr__ @classmethod def _validate_timeout(cls, value, name): @@ -118,23 +127,31 @@ class Timeout(object): return value if isinstance(value, bool): - raise ValueError("Timeout cannot be a boolean value. It must " - "be an int, float or None.") + raise ValueError( + "Timeout cannot be a boolean value. It must " + "be an int, float or None." + ) try: float(value) except (TypeError, ValueError): - raise ValueError("Timeout value %s was %s, but it must be an " - "int, float or None." % (name, value)) + raise ValueError( + "Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value) + ) try: if value <= 0: - raise ValueError("Attempted to set %s timeout to %s, but the " - "timeout cannot be set to a value less " - "than or equal to 0." % (name, value)) + raise ValueError( + "Attempted to set %s timeout to %s, but the " + "timeout cannot be set to a value less " + "than or equal to 0." % (name, value) + ) except TypeError: # Python 3 - raise ValueError("Timeout value %s was %s, but it must be an " - "int, float or None." % (name, value)) + raise ValueError( + "Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value) + ) return value @@ -166,8 +183,7 @@ class Timeout(object): # We can't use copy.deepcopy because that will also create a new object # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to # detect the user default. - return Timeout(connect=self._connect, read=self._read, - total=self.total) + return Timeout(connect=self._connect, read=self._read, total=self.total) def start_connect(self): """ Start the timeout clock, used during a connect() attempt @@ -183,14 +199,15 @@ class Timeout(object): def get_connect_duration(self): """ Gets the time elapsed since the call to :meth:`start_connect`. - :return: Elapsed time. + :return: Elapsed time in seconds. :rtype: float :raises urllib3.exceptions.TimeoutStateError: if you attempt to get duration for a timer that hasn't been started. """ if self._start_connect is None: - raise TimeoutStateError("Can't get connect duration for timer " - "that has not started.") + raise TimeoutStateError( + "Can't get connect duration for timer that has not started." + ) return current_time() - self._start_connect @property @@ -228,15 +245,16 @@ class Timeout(object): :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect` has not yet been called on this object. """ - if (self.total is not None and - self.total is not self.DEFAULT_TIMEOUT and - self._read is not None and - self._read is not self.DEFAULT_TIMEOUT): + if ( + self.total is not None + and self.total is not self.DEFAULT_TIMEOUT + and self._read is not None + and self._read is not self.DEFAULT_TIMEOUT + ): # In case the connect timeout has not yet been established. if self._start_connect is None: return self._read - return max(0, min(self.total - self.get_connect_duration(), - self._read)) + return max(0, min(self.total - self.get_connect_duration(), self._read)) elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT: return max(0, self.total - self.get_connect_duration()) else: diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/url.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/url.py index aefa119..0eb0b6a 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/url.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/url.py @@ -3,41 +3,108 @@ import re from collections import namedtuple from ..exceptions import LocationParseError -from ..packages import six, rfc3986 -from ..packages.rfc3986.exceptions import RFC3986Exception, ValidationError -from ..packages.rfc3986.validators import Validator -from ..packages.rfc3986 import abnf_regexp, normalizers, compat, misc +from ..packages import six -url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'] +url_attrs = ["scheme", "auth", "host", "port", "path", "query", "fragment"] # We only want to normalize urls with an HTTP(S) scheme. # urllib3 infers URLs without a scheme (None) to be http. -NORMALIZABLE_SCHEMES = ('http', 'https', None) +NORMALIZABLE_SCHEMES = ("http", "https", None) -# Regex for detecting URLs with schemes. RFC 3986 Section 3.1 -SCHEME_REGEX = re.compile(r"^(?:[a-zA-Z][a-zA-Z0-9+\-]*:|/)") +# Almost all of these patterns were derived from the +# 'rfc3986' module: https://github.com/python-hyper/rfc3986 +PERCENT_RE = re.compile(r"%[a-fA-F0-9]{2}") +SCHEME_RE = re.compile(r"^(?:[a-zA-Z][a-zA-Z0-9+-]*:|/)") +URI_RE = re.compile( + r"^(?:([a-zA-Z][a-zA-Z0-9+.-]*):)?" + r"(?://([^\\/?#]*))?" + r"([^?#]*)" + r"(?:\?([^#]*))?" + r"(?:#(.*))?$", + re.UNICODE | re.DOTALL, +) -PATH_CHARS = abnf_regexp.UNRESERVED_CHARS_SET | abnf_regexp.SUB_DELIMITERS_SET | {':', '@', '/'} -QUERY_CHARS = FRAGMENT_CHARS = PATH_CHARS | {'?'} +IPV4_PAT = r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}" +HEX_PAT = "[0-9A-Fa-f]{1,4}" +LS32_PAT = "(?:{hex}:{hex}|{ipv4})".format(hex=HEX_PAT, ipv4=IPV4_PAT) +_subs = {"hex": HEX_PAT, "ls32": LS32_PAT} +_variations = [ + # 6( h16 ":" ) ls32 + "(?:%(hex)s:){6}%(ls32)s", + # "::" 5( h16 ":" ) ls32 + "::(?:%(hex)s:){5}%(ls32)s", + # [ h16 ] "::" 4( h16 ":" ) ls32 + "(?:%(hex)s)?::(?:%(hex)s:){4}%(ls32)s", + # [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 + "(?:(?:%(hex)s:)?%(hex)s)?::(?:%(hex)s:){3}%(ls32)s", + # [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 + "(?:(?:%(hex)s:){0,2}%(hex)s)?::(?:%(hex)s:){2}%(ls32)s", + # [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 + "(?:(?:%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s", + # [ *4( h16 ":" ) h16 ] "::" ls32 + "(?:(?:%(hex)s:){0,4}%(hex)s)?::%(ls32)s", + # [ *5( h16 ":" ) h16 ] "::" h16 + "(?:(?:%(hex)s:){0,5}%(hex)s)?::%(hex)s", + # [ *6( h16 ":" ) h16 ] "::" + "(?:(?:%(hex)s:){0,6}%(hex)s)?::", +] + +UNRESERVED_PAT = r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._!\-~" +IPV6_PAT = "(?:" + "|".join([x % _subs for x in _variations]) + ")" +ZONE_ID_PAT = "(?:%25|%)(?:[" + UNRESERVED_PAT + "]|%[a-fA-F0-9]{2})+" +IPV6_ADDRZ_PAT = r"\[" + IPV6_PAT + r"(?:" + ZONE_ID_PAT + r")?\]" +REG_NAME_PAT = r"(?:[^\[\]%:/?#]|%[a-fA-F0-9]{2})*" +TARGET_RE = re.compile(r"^(/[^?#]*)(?:\?([^#]*))?(?:#.*)?$") + +IPV4_RE = re.compile("^" + IPV4_PAT + "$") +IPV6_RE = re.compile("^" + IPV6_PAT + "$") +IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT + "$") +BRACELESS_IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT[2:-2] + "$") +ZONE_ID_RE = re.compile("(" + ZONE_ID_PAT + r")\]$") + +SUBAUTHORITY_PAT = (u"^(?:(.*)@)?(%s|%s|%s)(?::([0-9]{0,5}))?$") % ( + REG_NAME_PAT, + IPV4_PAT, + IPV6_ADDRZ_PAT, +) +SUBAUTHORITY_RE = re.compile(SUBAUTHORITY_PAT, re.UNICODE | re.DOTALL) + +UNRESERVED_CHARS = set( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-~" +) +SUB_DELIM_CHARS = set("!$&'()*+,;=") +USERINFO_CHARS = UNRESERVED_CHARS | SUB_DELIM_CHARS | {":"} +PATH_CHARS = USERINFO_CHARS | {"@", "/"} +QUERY_CHARS = FRAGMENT_CHARS = PATH_CHARS | {"?"} -class Url(namedtuple('Url', url_attrs)): +class Url(namedtuple("Url", url_attrs)): """ Data structure for representing an HTTP URL. Used as a return value for :func:`parse_url`. Both the scheme and host are normalized as they are both case-insensitive according to RFC 3986. """ + __slots__ = () - def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None, - query=None, fragment=None): - if path and not path.startswith('/'): - path = '/' + path + def __new__( + cls, + scheme=None, + auth=None, + host=None, + port=None, + path=None, + query=None, + fragment=None, + ): + if path and not path.startswith("/"): + path = "/" + path if scheme is not None: scheme = scheme.lower() - return super(Url, cls).__new__(cls, scheme, auth, host, port, path, - query, fragment) + return super(Url, cls).__new__( + cls, scheme, auth, host, port, path, query, fragment + ) @property def hostname(self): @@ -47,10 +114,10 @@ class Url(namedtuple('Url', url_attrs)): @property def request_uri(self): """Absolute path including the query string.""" - uri = self.path or '/' + uri = self.path or "/" if self.query is not None: - uri += '?' + self.query + uri += "?" + self.query return uri @@ -58,7 +125,7 @@ class Url(namedtuple('Url', url_attrs)): def netloc(self): """Network location including host and port""" if self.port: - return '%s:%d' % (self.host, self.port) + return "%s:%d" % (self.host, self.port) return self.host @property @@ -81,23 +148,23 @@ class Url(namedtuple('Url', url_attrs)): 'http://username:password@host.com:80/path?query#fragment' """ scheme, auth, host, port, path, query, fragment = self - url = u'' + url = u"" # We use "is not None" we want things to happen with empty strings (or 0 port) if scheme is not None: - url += scheme + u'://' + url += scheme + u"://" if auth is not None: - url += auth + u'@' + url += auth + u"@" if host is not None: url += host if port is not None: - url += u':' + str(port) + url += u":" + str(port) if path is not None: url += path if query is not None: - url += u'?' + query + url += u"?" + query if fragment is not None: - url += u'#' + fragment + url += u"#" + fragment return url @@ -135,48 +202,140 @@ def split_first(s, delims): min_delim = d if min_idx is None or min_idx < 0: - return s, '', None + return s, "", None - return s[:min_idx], s[min_idx + 1:], min_delim + return s[:min_idx], s[min_idx + 1 :], min_delim -def _encode_invalid_chars(component, allowed_chars, encoding='utf-8'): +def _encode_invalid_chars(component, allowed_chars, encoding="utf-8"): """Percent-encodes a URI component without reapplying - onto an already percent-encoded component. Based on - rfc3986.normalizers.encode_component() + onto an already percent-encoded component. """ if component is None: return component + component = six.ensure_text(component) + + # Normalize existing percent-encoded bytes. # Try to see if the component we're encoding is already percent-encoded # so we can skip all '%' characters but still encode all others. - percent_encodings = len(normalizers.PERCENT_MATCHER.findall( - compat.to_str(component, encoding))) - - uri_bytes = component.encode('utf-8', 'surrogatepass') - is_percent_encoded = percent_encodings == uri_bytes.count(b'%') + component, percent_encodings = PERCENT_RE.subn( + lambda match: match.group(0).upper(), component + ) + uri_bytes = component.encode("utf-8", "surrogatepass") + is_percent_encoded = percent_encodings == uri_bytes.count(b"%") encoded_component = bytearray() for i in range(0, len(uri_bytes)): # Will return a single character bytestring on both Python 2 & 3 - byte = uri_bytes[i:i+1] + byte = uri_bytes[i : i + 1] byte_ord = ord(byte) - if ((is_percent_encoded and byte == b'%') - or (byte_ord < 128 and byte.decode() in allowed_chars)): - encoded_component.extend(byte) + if (is_percent_encoded and byte == b"%") or ( + byte_ord < 128 and byte.decode() in allowed_chars + ): + encoded_component += byte continue - encoded_component.extend('%{0:02x}'.format(byte_ord).encode().upper()) + encoded_component.extend(b"%" + (hex(byte_ord)[2:].encode().zfill(2).upper())) return encoded_component.decode(encoding) +def _remove_path_dot_segments(path): + # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code + segments = path.split("/") # Turn the path into a list of segments + output = [] # Initialize the variable to use to store output + + for segment in segments: + # '.' is the current directory, so ignore it, it is superfluous + if segment == ".": + continue + # Anything other than '..', should be appended to the output + elif segment != "..": + output.append(segment) + # In this case segment == '..', if we can, we should pop the last + # element + elif output: + output.pop() + + # If the path starts with '/' and the output is empty or the first string + # is non-empty + if path.startswith("/") and (not output or output[0]): + output.insert(0, "") + + # If the path starts with '/.' or '/..' ensure we add one more empty + # string to add a trailing '/' + if path.endswith(("/.", "/..")): + output.append("") + + return "/".join(output) + + +def _normalize_host(host, scheme): + if host: + if isinstance(host, six.binary_type): + host = six.ensure_str(host) + + if scheme in NORMALIZABLE_SCHEMES: + is_ipv6 = IPV6_ADDRZ_RE.match(host) + if is_ipv6: + match = ZONE_ID_RE.search(host) + if match: + start, end = match.span(1) + zone_id = host[start:end] + + if zone_id.startswith("%25") and zone_id != "%25": + zone_id = zone_id[3:] + else: + zone_id = zone_id[1:] + zone_id = "%" + _encode_invalid_chars(zone_id, UNRESERVED_CHARS) + return host[:start].lower() + zone_id + host[end:] + else: + return host.lower() + elif not IPV4_RE.match(host): + return six.ensure_str( + b".".join([_idna_encode(label) for label in host.split(".")]) + ) + return host + + +def _idna_encode(name): + if name and any([ord(x) > 128 for x in name]): + try: + from pip._vendor import idna + except ImportError: + six.raise_from( + LocationParseError("Unable to parse URL without the 'idna' module"), + None, + ) + try: + return idna.encode(name.lower(), strict=True, std3_rules=True) + except idna.IDNAError: + six.raise_from( + LocationParseError(u"Name '%s' is not a valid IDNA label" % name), None + ) + return name.lower().encode("ascii") + + +def _encode_target(target): + """Percent-encodes a request target so that there are no invalid characters""" + path, query = TARGET_RE.match(target).groups() + target = _encode_invalid_chars(path, PATH_CHARS) + query = _encode_invalid_chars(query, QUERY_CHARS) + if query is not None: + target += "?" + query + return target + + def parse_url(url): """ Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is performed to parse incomplete urls. Fields not provided will be None. This parser is RFC 3986 compliant. + The parser logic and helper functions are based heavily on + work done in the ``rfc3986`` module. + :param str url: URL to parse into a :class:`.Url` namedtuple. Partly backwards-compatible with :mod:`urlparse`. @@ -194,90 +353,72 @@ def parse_url(url): # Empty return Url() - is_string = not isinstance(url, six.binary_type) - - # RFC 3986 doesn't like URLs that have a host but don't start - # with a scheme and we support URLs like that so we need to - # detect that problem and add an empty scheme indication. - # We don't get hurt on path-only URLs here as it's stripped - # off and given an empty scheme anyways. - if not SCHEME_REGEX.search(url): + source_url = url + if not SCHEME_RE.search(url): url = "//" + url - def idna_encode(name): - if name and any([ord(x) > 128 for x in name]): - try: - from pip._vendor import idna - except ImportError: - raise LocationParseError("Unable to parse URL without the 'idna' module") - try: - return idna.encode(name.lower(), strict=True, std3_rules=True) - except idna.IDNAError: - raise LocationParseError(u"Name '%s' is not a valid IDNA label" % name) - return name - try: - split_iri = misc.IRI_MATCHER.match(compat.to_str(url)).groupdict() - iri_ref = rfc3986.IRIReference( - split_iri['scheme'], split_iri['authority'], - _encode_invalid_chars(split_iri['path'], PATH_CHARS), - _encode_invalid_chars(split_iri['query'], QUERY_CHARS), - _encode_invalid_chars(split_iri['fragment'], FRAGMENT_CHARS) - ) - has_authority = iri_ref.authority is not None - uri_ref = iri_ref.encode(idna_encoder=idna_encode) - except (ValueError, RFC3986Exception): - return six.raise_from(LocationParseError(url), None) + scheme, authority, path, query, fragment = URI_RE.match(url).groups() + normalize_uri = scheme is None or scheme.lower() in NORMALIZABLE_SCHEMES - # rfc3986 strips the authority if it's invalid - if has_authority and uri_ref.authority is None: - raise LocationParseError(url) + if scheme: + scheme = scheme.lower() - # Only normalize schemes we understand to not break http+unix - # or other schemes that don't follow RFC 3986. - if uri_ref.scheme is None or uri_ref.scheme.lower() in NORMALIZABLE_SCHEMES: - uri_ref = uri_ref.normalize() + if authority: + auth, host, port = SUBAUTHORITY_RE.match(authority).groups() + if auth and normalize_uri: + auth = _encode_invalid_chars(auth, USERINFO_CHARS) + if port == "": + port = None + else: + auth, host, port = None, None, None - # Validate all URIReference components and ensure that all - # components that were set before are still set after - # normalization has completed. - validator = Validator() - try: - validator.check_validity_of( - *validator.COMPONENT_NAMES - ).validate(uri_ref) - except ValidationError: - return six.raise_from(LocationParseError(url), None) + if port is not None: + port = int(port) + if not (0 <= port <= 65535): + raise LocationParseError(url) + + host = _normalize_host(host, scheme) + + if normalize_uri and path: + path = _remove_path_dot_segments(path) + path = _encode_invalid_chars(path, PATH_CHARS) + if normalize_uri and query: + query = _encode_invalid_chars(query, QUERY_CHARS) + if normalize_uri and fragment: + fragment = _encode_invalid_chars(fragment, FRAGMENT_CHARS) + + except (ValueError, AttributeError): + return six.raise_from(LocationParseError(source_url), None) # For the sake of backwards compatibility we put empty # string values for path if there are any defined values # beyond the path in the URL. # TODO: Remove this when we break backwards compatibility. - path = uri_ref.path if not path: - if (uri_ref.query is not None - or uri_ref.fragment is not None): + if query is not None or fragment is not None: path = "" else: path = None # Ensure that each part of the URL is a `str` for # backwards compatibility. - def to_input_type(x): - if x is None: - return None - elif not is_string and not isinstance(x, six.binary_type): - return x.encode('utf-8') - return x + if isinstance(url, six.text_type): + ensure_func = six.ensure_text + else: + ensure_func = six.ensure_str + + def ensure_type(x): + return x if x is None else ensure_func(x) return Url( - scheme=to_input_type(uri_ref.scheme), - auth=to_input_type(uri_ref.userinfo), - host=to_input_type(uri_ref.host), - port=int(uri_ref.port) if uri_ref.port is not None else None, - path=to_input_type(path), - query=to_input_type(uri_ref.query), - fragment=to_input_type(uri_ref.fragment) + scheme=ensure_type(scheme), + auth=ensure_type(auth), + host=ensure_type(host), + port=port, + path=ensure_type(path), + query=ensure_type(query), + fragment=ensure_type(fragment), ) @@ -286,4 +427,4 @@ def get_host(url): Deprecated. Use :func:`parse_url` instead. """ p = parse_url(url) - return p.scheme or 'http', p.hostname, p.port + return p.scheme or "http", p.hostname, p.port diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/wait.py b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/wait.py index 4db71ba..d71d2fd 100644 --- a/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/wait.py +++ b/venv/lib/python3.8/site-packages/pip/_vendor/urllib3/util/wait.py @@ -2,6 +2,7 @@ import errno from functools import partial import select import sys + try: from time import monotonic except ImportError: @@ -40,6 +41,8 @@ if sys.version_info >= (3, 5): # Modern Python, that retries syscalls by default def _retry_on_intr(fn, timeout): return fn(timeout) + + else: # Old and broken Pythons. def _retry_on_intr(fn, timeout): diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-38.pyc index b6c222feb89041bf3ebd1055dcf0f24e4609dced..467cd331268ac9a8ff89daba90f63dc38bcd50ad 100644 GIT binary patch delta 94 zcmaFj-RZ*<%FD~e00f%<cExYx@nv&P*U!k$P1P@|EG^B-)Gsbd)=x>y%S_El&MzuS wE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPc7bD&Xy|=0PB(=IRF3v delta 57 zcmeD5dE(6z%FD~e00hs=HpFe@@nw^9(l5y^&@ad=(9O&%E=kPE(KX62DXlQhPXq~W Jp2L<a4*&vP62$-j diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-38.pyc index e5503b4e0098688d98dbe8917b8421fdeb04d60f..df44f413ea9fa830d82d2572a87e18670b2c66b9 100644 GIT binary patch delta 94 zcmca6`&*VLl$V!_0SGkz?TX*XbBxD1RX-y?H&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lA2cBn)02Om0mjD0& delta 57 zcmew@drg)nl$V!_0SKO#ZHU{*bBssMLBAxoK))cfKsPh5xFj(rN7pFBq_n~~KM^Fj JS(Nt~BLEg06C?lt diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-38.pyc index 54431438b70f7ece6bf008090c9a5ba5a14337b0..41d966e951593acb20544a57fef91acf18db5eba 100644 GIT binary patch delta 94 zcmaFH*Uirp%FD~e00f%<cExYx+0W>luAh;go2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5*5C1Wis0OH{xlK=n! delta 57 zcmeC?f5yiX%FD~e00hs=HpFe@+0Q8Fq+gO-pkI(#pqrUjT#}fRqid95Qd(i0p9m7% J%*RyA3IO))5+DEo diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-38.pyc index 4bca903da347dfef872cd16468b7af96d0e14998..803eab8398ef4d3c74abaf891d40cc270fb782fd 100644 GIT binary patch delta 94 zcmX@2{!*PMl$V!_0SGkz?TX*XGm*(TML#1yH&wr=va~cSQ@^+<SwAH)FEceKIlrhR wwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ+*lAZYEAa0QxZ@I{*Lx delta 57 zcmaE<eng!ol$V!_0SKO#ZHU{*Gm%NoUcV%_K))cfKsPh5xFj(rN7pFBq_n~~KM^Fj J`2iEBAOH$>62|}l diff --git a/venv/lib/python3.8/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-38.pyc b/venv/lib/python3.8/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-38.pyc index 79c9d6af8c14b6db2e0bfd9b61cd0b37cd6c1524..6b91d3d0d983851bd4f6b653367990794de070e6 100644 GIT binary patch delta 94 zcmX>i@=}B+l$V!_0SGkz?TX*X)57GOtDljdo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu wTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo?5(l9n&;+0PG$ihX4Qo delta 57 zcmaDUazunDl$V!_0SKO#ZHU{*)50X@p<j|)pkI(#pqrUjT#}fRqid95Qd(i0p9m7% Je3@w)I{*T86B7Uc diff --git a/venv/lib/python3.8/site-packages/pkg_resources/__init__.py b/venv/lib/python3.8/site-packages/pkg_resources/__init__.py index 1f170cf..5927ef0 100644 --- a/venv/lib/python3.8/site-packages/pkg_resources/__init__.py +++ b/venv/lib/python3.8/site-packages/pkg_resources/__init__.py @@ -55,7 +55,7 @@ except NameError: FileExistsError = OSError from pkg_resources.extern import six -from pkg_resources.extern.six.moves import urllib, map, filter +from pkg_resources.extern.six.moves import map, filter # capture these to bypass sandboxing from os import utime @@ -76,7 +76,6 @@ try: except ImportError: importlib_machinery = None -from . import py31compat from pkg_resources.extern import appdirs from pkg_resources.extern import packaging __import__('pkg_resources.extern.packaging.version') @@ -88,8 +87,8 @@ __import__('pkg_resources.extern.packaging.markers') __metaclass__ = type -if (3, 0) < sys.version_info < (3, 4): - raise RuntimeError("Python 3.4 or later is required") +if (3, 0) < sys.version_info < (3, 5): + raise RuntimeError("Python 3.5 or later is required") if six.PY2: # Those builtin exceptions are only defined in Python 3 @@ -178,10 +177,10 @@ def get_supported_platform(): """Return this platform's maximum compatible version. distutils.util.get_platform() normally reports the minimum version - of Mac OS X that would be required to *use* extensions produced by + of macOS that would be required to *use* extensions produced by distutils. But what we want when checking compatibility is to know the - version of Mac OS X that we are *running*. To allow usage of packages that - explicitly require a newer version of Mac OS X, we must also know the + version of macOS that we are *running*. To allow usage of packages that + explicitly require a newer version of macOS, we must also know the current version of the OS. If this condition occurs for any other platform with a version in its @@ -191,9 +190,9 @@ def get_supported_platform(): m = macosVersionString.match(plat) if m is not None and sys.platform == "darwin": try: - plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3)) + plat = 'macosx-%s-%s' % ('.'.join(_macos_vers()[:2]), m.group(3)) except ValueError: - # not Mac OS X + # not macOS pass return plat @@ -333,7 +332,7 @@ class UnknownExtra(ResolutionError): _provider_factories = {} -PY_MAJOR = sys.version[:3] +PY_MAJOR = '{}.{}'.format(*sys.version_info) EGG_DIST = 3 BINARY_DIST = 2 SOURCE_DIST = 1 @@ -364,7 +363,7 @@ def get_provider(moduleOrReq): return _find_adapter(_provider_factories, loader)(module) -def _macosx_vers(_cache=[]): +def _macos_vers(_cache=[]): if not _cache: version = platform.mac_ver()[0] # fallback for MacPorts @@ -380,7 +379,7 @@ def _macosx_vers(_cache=[]): return _cache[0] -def _macosx_arch(machine): +def _macos_arch(machine): return {'PowerPC': 'ppc', 'Power_Macintosh': 'ppc'}.get(machine, machine) @@ -388,18 +387,18 @@ def get_build_platform(): """Return this platform's string for platform-specific distributions XXX Currently this is the same as ``distutils.util.get_platform()``, but it - needs some hacks for Linux and Mac OS X. + needs some hacks for Linux and macOS. """ from sysconfig import get_platform plat = get_platform() if sys.platform == "darwin" and not plat.startswith('macosx-'): try: - version = _macosx_vers() + version = _macos_vers() machine = os.uname()[4].replace(" ", "_") return "macosx-%d.%d-%s" % ( int(version[0]), int(version[1]), - _macosx_arch(machine), + _macos_arch(machine), ) except ValueError: # if someone is running a non-Mac darwin system, this will fall @@ -425,7 +424,7 @@ def compatible_platforms(provided, required): # easy case return True - # Mac OS X special cases + # macOS special cases reqMac = macosVersionString.match(required) if reqMac: provMac = macosVersionString.match(provided) @@ -434,7 +433,7 @@ def compatible_platforms(provided, required): if not provMac: # this is backwards compatibility for packages built before # setuptools 0.6. All packages built after this point will - # use the new macosx designation. + # use the new macOS designation. provDarwin = darwinVersionString.match(provided) if provDarwin: dversion = int(provDarwin.group(1)) @@ -442,7 +441,7 @@ def compatible_platforms(provided, required): if dversion == 7 and macosversion >= "10.3" or \ dversion == 8 and macosversion >= "10.4": return True - # egg isn't macosx or legacy darwin + # egg isn't macOS or legacy darwin return False # are they the same major version and machine type? @@ -1234,12 +1233,13 @@ class ResourceManager: mode = os.stat(path).st_mode if mode & stat.S_IWOTH or mode & stat.S_IWGRP: msg = ( - "%s is writable by group/others and vulnerable to attack " - "when " - "used with get_resource_filename. Consider a more secure " + "Extraction path is writable by group/others " + "and vulnerable to attack when " + "used with get_resource_filename ({path}). " + "Consider a more secure " "location (set with .set_extraction_path or the " - "PYTHON_EGG_CACHE environment variable)." % path - ) + "PYTHON_EGG_CACHE environment variable)." + ).format(**locals()) warnings.warn(msg, UserWarning) def postprocess(self, tempname, filename): @@ -1377,7 +1377,7 @@ def evaluate_marker(text, extra=None): marker = packaging.markers.Marker(text) return marker.evaluate() except packaging.markers.InvalidMarker as e: - raise SyntaxError(e) + raise SyntaxError(e) from e class NullProvider: @@ -1457,7 +1457,8 @@ class NullProvider: script_filename = self._fn(self.egg_info, script) namespace['__file__'] = script_filename if os.path.exists(script_filename): - source = open(script_filename).read() + with open(script_filename) as fid: + source = fid.read() code = compile(source, script_filename, 'exec') exec(code, namespace, namespace) else: @@ -1575,6 +1576,17 @@ is not allowed. register_loader_type(object, NullProvider) +def _parents(path): + """ + yield all parents of path including path + """ + last = None + while path != last: + yield path + last = path + path, _ = os.path.split(path) + + class EggProvider(NullProvider): """Provider based on a virtual filesystem""" @@ -1583,18 +1595,16 @@ class EggProvider(NullProvider): self._setup_prefix() def _setup_prefix(self): - # we assume here that our metadata may be nested inside a "basket" - # of multiple eggs; that's why we use module_path instead of .archive - path = self.module_path - old = None - while path != old: - if _is_egg_path(path): - self.egg_name = os.path.basename(path) - self.egg_info = os.path.join(path, 'EGG-INFO') - self.egg_root = path - break - old = path - path, base = os.path.split(path) + # Assume that metadata may be nested inside a "basket" + # of multiple eggs and use module_path instead of .archive. + eggs = filter(_is_egg_path, _parents(self.module_path)) + egg = next(eggs, None) + egg and self._set_egg(egg) + + def _set_egg(self, path): + self.egg_name = os.path.basename(path) + self.egg_info = os.path.join(path, 'EGG-INFO') + self.egg_root = path class DefaultProvider(EggProvider): @@ -2067,11 +2077,14 @@ def find_on_path(importer, path_item, only=False): def dist_factory(path_item, entry, only): - """ - Return a dist_factory for a path_item and entry - """ + """Return a dist_factory for the given entry.""" lower = entry.lower() - is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info'))) + is_egg_info = lower.endswith('.egg-info') + is_dist_info = ( + lower.endswith('.dist-info') and + os.path.isdir(os.path.join(path_item, entry)) + ) + is_meta = is_egg_info or is_dist_info return ( distributions_from_metadata if is_meta else @@ -2195,10 +2208,14 @@ def _handle_ns(packageName, path_item): if importer is None: return None - # capture warnings due to #1111 - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - loader = importer.find_module(packageName) + # use find_spec (PEP 451) and fall-back to find_module (PEP 302) + try: + loader = importer.find_spec(packageName).loader + except AttributeError: + # capture warnings due to #1111 + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + loader = importer.find_module(packageName) if loader is None: return None @@ -2270,8 +2287,8 @@ def declare_namespace(packageName): __import__(parent) try: path = sys.modules[parent].__path__ - except AttributeError: - raise TypeError("Not a package:", parent) + except AttributeError as e: + raise TypeError("Not a package:", parent) from e # Track what packages are namespaces, so when new path items are added, # they can be updated @@ -2328,7 +2345,8 @@ register_namespace_handler(object, null_ns_handler) def normalize_path(filename): """Normalize a file/dir name for comparison purposes""" - return os.path.normcase(os.path.realpath(os.path.normpath(_cygwin_patch(filename)))) + return os.path.normcase(os.path.realpath(os.path.normpath( + _cygwin_patch(filename)))) def _cygwin_patch(filename): # pragma: nocover @@ -2450,7 +2468,7 @@ class EntryPoint: try: return functools.reduce(getattr, self.attrs, module) except AttributeError as exc: - raise ImportError(str(exc)) + raise ImportError(str(exc)) from exc def require(self, env=None, installer=None): if self.extras and not self.dist: @@ -2536,15 +2554,6 @@ class EntryPoint: return maps -def _remove_md5_fragment(location): - if not location: - return '' - parsed = urllib.parse.urlparse(location) - if parsed[-1].startswith('md5='): - return urllib.parse.urlunparse(parsed[:-1] + ('',)) - return location - - def _version_from_file(lines): """ Given an iterable of lines from a Metadata file, return @@ -2601,7 +2610,7 @@ class Distribution: self.parsed_version, self.precedence, self.key, - _remove_md5_fragment(self.location), + self.location, self.py_version or '', self.platform or '', ) @@ -2679,14 +2688,14 @@ class Distribution: def version(self): try: return self._version - except AttributeError: + except AttributeError as e: version = self._get_version() if version is None: path = self._get_metadata_path_for_display(self.PKG_INFO) msg = ( "Missing 'Version:' header and/or {} file at path: {}" ).format(self.PKG_INFO, path) - raise ValueError(msg, self) + raise ValueError(msg, self) from e return version @@ -2739,10 +2748,10 @@ class Distribution: for ext in extras: try: deps.extend(dm[safe_extra(ext)]) - except KeyError: + except KeyError as e: raise UnknownExtra( "%s has no such extra feature %r" % (self, ext) - ) + ) from e return deps def _get_metadata_path_for_display(self, name): @@ -3067,11 +3076,6 @@ def issue_warning(*args, **kw): warnings.warn(stacklevel=level + 1, *args, **kw) -class RequirementParseError(ValueError): - def __str__(self): - return ' '.join(self.args) - - def parse_requirements(strs): """Yield ``Requirement`` objects for each specification in `strs` @@ -3094,13 +3098,14 @@ def parse_requirements(strs): yield Requirement(line) +class RequirementParseError(packaging.requirements.InvalidRequirement): + "Compatibility wrapper for InvalidRequirement" + + class Requirement(packaging.requirements.Requirement): def __init__(self, requirement_string): """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!""" - try: - super(Requirement, self).__init__(requirement_string) - except packaging.requirements.InvalidRequirement as e: - raise RequirementParseError(str(e)) + super(Requirement, self).__init__(requirement_string) self.unsafe_name = self.name project_name = safe_name(self.name) self.project_name, self.key = project_name, project_name.lower() @@ -3109,6 +3114,7 @@ class Requirement(packaging.requirements.Requirement): self.extras = tuple(map(safe_extra, self.extras)) self.hashCmp = ( self.key, + self.url, self.specifier, frozenset(self.extras), str(self.marker) if self.marker else None, @@ -3169,7 +3175,7 @@ def _find_adapter(registry, ob): def ensure_directory(path): """Ensure that the parent directory of `path` exists""" dirname = os.path.dirname(path) - py31compat.makedirs(dirname, exist_ok=True) + os.makedirs(dirname, exist_ok=True) def _bypass_ensure_directory(path): @@ -3286,6 +3292,7 @@ def _initialize_master_working_set(): list(map(working_set.add_entry, sys.path)) globals().update(locals()) + class PkgResourcesDeprecationWarning(Warning): """ Base class for warning about deprecations in ``pkg_resources`` diff --git a/venv/lib/python3.8/site-packages/pkg_resources/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/__pycache__/__init__.cpython-38.pyc index bdf865fa0b29f9529039556bc1b82223993d0ad4..7603f710d9cf1fb01072170333148a1f676027c6 100644 GIT binary patch delta 28518 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 T=kM9w+kK+__D)<?JMRAh!ULv; delta 28498 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 O52krlUKX~{BmW;%#;tz< diff --git a/venv/lib/python3.8/site-packages/pkg_resources/__pycache__/py31compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/__pycache__/py31compat.cpython-38.pyc deleted file mode 100644 index ceca59740b3bb09c17a697335c1c74d5b166b727..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 604 zcmYjO&2AGh5T3EU$tFrePl#98LmQfu8$wl4sv@C+6n@%05Te-7&2HAK@uo_ulmp^H z;K+^V@s$J0D{w%JgQz-|zwy}PnQvxZ@9eaJ<=54Zcl!e1XE5%HWaEgpd(WUjV*%+u zjVW$zkqRxeEaY6J3PHDYq#Iu_jf|Q#s^_|C#H^`6LXP%S$2pWr074p@nBJJER0d|P zw54$bNqfUt;B14833}<W<;j$3-AbSn2tVcRP8qJdHGIW2d_#n{P#!9%Mc$@kgd2fy zeSeMga4lxCmNS)0>VIahM_j;-_$1EZ0!l^=oEp!P$P4RyJfGx7XXJeI#b`)m$w!8$ zw7xMMo<AGCN~BlSq`vgAS!S*t+uTdDoPG!DFrnW^y?S2ts;t_}N>@*cVy}OBxL6MC zq~}b%sA_8q*Q@f6V=~SzXlmG64GyMu&QbTPmG6xIQy32p;!x>!Mkuh0yS%8&cZt}9 zW^7bAOS;F3b_0ZVC3upwDLhe=fg8DUX~QgQLnVc8+Yny9yy*MRl_8hea-5YPtnZe_ oXm?A1qTn3rx&u2QWc+w;^`bCO!mM1#93wB$k?l?cAN&#OFDr0~M*si- diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-38.pyc index ea089a9d6a6ee0f86673dac52a7fd9218023bc57..07394f3bfdd60fe3015aaa211d7b0978469c3583 100644 GIT binary patch delta 90 zcmZ3;xSx?Hl$V!_0SGw%?TVksW9^ippOK%Ns$W!DTAG!qUtE-|pOToDnVOTFUsRG> stXEN4rC*ksSEiqnnWSG(S(1^TXRK$TUz}Nzs#}nloSm4SIx*V}056pvJ^%m! delta 60 zcmdnbxR8-2l$V!_0SKO#ZHSx5W3A$*Uy@s(Uyxa#o0(T!l9-dDYm{M9T49`@s9&5~ OQd&@wpPw_a(+mJ1SQH8X diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-38.pyc index 8335065aa23f871edae2fe966ba466119903456e..c7866cc4fc77bbba5b4ff5bd37f45d1695c424c6 100644 GIT binary patch delta 95 zcmZ3qfbqZrMxIb!UM>b8;QY5Mek0Fp9;amejQreG{i4d!(yUDV;-X~zl*GKu)STq} xqLS2Ny^6{z{j$`&GX0#)B>jTQl8pR3V?7J~;>?m%-GapA?8Nlc&8K<7odFbKA^iXV delta 65 zcmX@GfN{|RMxIb!UM>b8cwV+4ZX?fZ9u-&plH3CQg3JQl%)H`~#GD*mqYRVM3gi4l T{o>S;(t?uw{G81%dBU9mx)2u0 diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-38.pyc index 4ddd85b2074b106fd072134ea820c96aa7d01401..0d946909baa3d0c581f51ff1f384bccf47322874 100644 GIT binary patch delta 111 zcmZ3soae}L9-dHMUM>b8;QY5Mek0EnS*KL}jQreG{i4d!(yUDV;-X~zl*GKu)STq} zqLS2Ny^6{z{j$`&GX0#)B>jTQl8pR3V?7J~;>?m%-GapA?8NlcW)``27CFZ4EOJa* OuNb4Y>vJ%da{~Zw=_OqN delta 81 zcmX@IoM+i`9-dHMUM>b8cwV+4ZX?eXSrvEvlH3CQg3JQl%)H`~#GD*mqYRVM3gi4l k{o>S;(t?uw{G4VbxppNv#_dXSOj@rPZ*BMGU@qqd09xW30{{R3 diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-38.pyc index d97140a3a81abd1e8afc2ff398d6fbeb2305e1f6..124abcd313e958ab26b4224229fb0a15be1ca155 100644 GIT binary patch delta 95 zcmeygk8#3&MxIb!UM>b8;QY5Mek0Eeey4c-jQreG{i4d!(yUDV;-X~zl*GKu)STq} yqLS2Ny^6{z{j$`&GX0#)B>jTQl8pR3V?7J~;>?m%-GapA?8Nlc%_sO*`2zqpY9h4& delta 65 zcmbQRpYhW^MxIb!UM>b8cwV+4ZX?eOeicXklH3CQg3JQl%)H`~#GD*mqYRVM3gi4l U{o>S;(t?uw{G83t_*eM@0MITMfdBvi diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__about__.py b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__about__.py index 95d330e..dc95138 100644 --- a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__about__.py +++ b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__about__.py @@ -4,18 +4,24 @@ from __future__ import absolute_import, division, print_function __all__ = [ - "__title__", "__summary__", "__uri__", "__version__", "__author__", - "__email__", "__license__", "__copyright__", + "__title__", + "__summary__", + "__uri__", + "__version__", + "__author__", + "__email__", + "__license__", + "__copyright__", ] __title__ = "packaging" __summary__ = "Core utilities for Python packages" __uri__ = "https://github.com/pypa/packaging" -__version__ = "16.8" +__version__ = "19.2" __author__ = "Donald Stufft and individual contributors" __email__ = "donald@stufft.io" __license__ = "BSD or Apache License, Version 2.0" -__copyright__ = "Copyright 2014-2016 %s" % __author__ +__copyright__ = "Copyright 2014-2019 %s" % __author__ diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__init__.py b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__init__.py index 5ee6220..a0cf67d 100644 --- a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__init__.py +++ b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__init__.py @@ -4,11 +4,23 @@ from __future__ import absolute_import, division, print_function from .__about__ import ( - __author__, __copyright__, __email__, __license__, __summary__, __title__, - __uri__, __version__ + __author__, + __copyright__, + __email__, + __license__, + __summary__, + __title__, + __uri__, + __version__, ) __all__ = [ - "__title__", "__summary__", "__uri__", "__version__", "__author__", - "__email__", "__license__", "__copyright__", + "__title__", + "__summary__", + "__uri__", + "__version__", + "__author__", + "__email__", + "__license__", + "__copyright__", ] diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-38.pyc index 750d1f5197866ce4bdee3353d5114e160f69bbe2..d04239af216775d99b97c5568c8c7c97b5c09686 100644 GIT binary patch delta 139 zcmX@k`jnM7l$V!_0SGw%?TUY~kvE!=*;3DFayDZrqvhm>jPXwS`WgATsrp5grKMS! z`o%@b`YDNdnW;I+`9&qE#d;N$Rr+PAd1d-JnMwKul_eSZdB%Dc`o)<gsk#M;$=QkN asgqNfT;v&<kl_y&ZWcx$WCB7E$p`=+_$E>S delta 109 zcmaFLdYqLvl$V!_0SKO#ZHT+DkvE!=*-X!3ayDZrquJz#jPWXg`X#vq`URN<x|w;! yC5bsXx<(l$r4`2ciTcH<C8Y%=`T04Mo0weW8JHlD5lsJMVP#<iLM9*tk&FQGx*Grh diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-38.pyc index 4642ae23c110abdeabee9e37ffd30ed9ed0ec177..599eed870f6f962496360002b49a8cb0df681ed4 100644 GIT binary patch delta 111 zcmZ3=a+rlTl$V!_0SGw%?TR<r$h&~iDNjEmKQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+FwiMMh^q9wtT<_yYjr C%OSD= delta 81 zcmX@ivXq54l$V!_0SKO#ZHQys$h&}1B|yI<w?Mxjvp_d9uec;JCr8&P!=$vrI6qOp aIJKm-pd>#(XYzYSXF)b51}J0%)Bgb5#TG{Z diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-38.pyc index 334678eb10ac4dc270ad79b15f9ee5dddd8905a6..56f8305d5b57c7badae71625f0c92839b03981da 100644 GIT binary patch delta 100 zcmcb~{+*pSl$V!_0SGw%?TSy_$oq=XDOW!uKQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+Fv&G?OYLBg<q*<{1FT C^dc?* delta 70 zcmey)ev_Ryl$V!_0SKO#ZHSB6$oq;>#b3W9w?Mxjvp_d9uec;JCr8&P!=$vrI6qOp YIJKm-pd>#(XR{@fDkCHF<ap*804!-25&!@I diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-38.pyc index 0a420694e90d03db238b9caa7153b18892a7f75a..844f7b24e3a92a062e5663586b8529a771a5b973 100644 GIT binary patch delta 284 zcmX>v`c{-Dl$V!_0SGw%?TX*X6VB*VsGpIao2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu zTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo;tam(Tb5{@*&1DM()X$ zOu3AFlMk?nPu|Dm!zc)5adQ|?4rMlF6an*UIQ%AmVCG;H2lE72ycwl{EQ!gHoNAL3 z*kyroEUf9N@$s@i(PBo0$tJ9m85t*^V7<erF<F9Le)3I5gUMgmlo_>wyevk&$rm`} zCof|6WHbb`xH$qDO~9-gj$lS}AS;8>3e1n-^klRJv#zt~PJYKJ$LKJbm&+Gub~INB E0IUO8uK)l5 delta 246 zcmaDWdR~+#l$V!_0SKO#ZHU{*6V9j-tY4B_pkI(#pqrUjT#}fRqid95Qd(i0pQvA) zT2fk2lAoV5c`2h6Bj@A?jAe{GKvH~i9#a@2|Kxit;*;+%`7jEBSq{t@jG|!H0p>79 z2{22K#hXzY$dZ^`&Z#!Jj$L-L0y7J1dTM;U98k2FQE_q*>tsfz$<J8tFltUVW0#-& zozY;j5W6y?4v?3{s6Tljdj_KskW`qg#Sy@03S`Mop2ZQ&XaQ#Na(XgagIQ%jmK~UN SpVOPsak4g-FVNgdt`Y!Fa!Skq diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-38.pyc index 08bb3e41bec5f3c19f20bff265248c4ebe5414ed..11a2d7189cce0dfabc9e73dc78e1d2272ba76ab8 100644 GIT binary patch delta 663 zcmYLGO=uHA7|l1$W`C1xo3zbOV``w%9L&~Mq*78f+Nz)hZL5e#Nt(rMZL)E*DW*_G zq~zkk_VZv-F#$m<6w$p&r6?#~Ja|wcy?F6ZDtHkuYU{*`&SM@kkN15u^JaCRJm?&C zIt3dY{Km7f(I?L1Od_jf^sK5FrDAbHQwqkol1}C{b#h!cOtlcZRGL<%)ZCOZsil;B z$;{}vo>;F^&`fn_J~@6Nd0xfK%r0odq@xelnIc5!Y8g5y2XU3>F~QD57rtjNLJuD1 zZowY>#7)CqJj<UE6?&BdM~MSm;cr4ejtE0yysnZhbxC;ZO#I&)F?=la;)-|-j-VtR z0I-In&j1<R?J9$g%dT@^V8ES%63)0^LK*kV8JM*e<rKhel$sE#SZSK`U$6IUr(^>! z%WV=OY>)=|7h&*_M}-IY$a4Z7T0cFf0G{G-^E$k?_O)CESi={sAK{&~;1dA8;C+9m z;G#_q(pfO@ga34Y+Fo&*Y{gZzrEO_umiTQ|FkymCJMM_XwkSJPb7|T9q?%Q8X42I3 zTn)Mmoz~YNwni`&h=Us|fsqbFtBc;P(8s1!qd?7LW|7uLNzJZN#puSykcVlZ#&6gX z+yP!I9@GIOTxx5D27J{vNMHR`^f4XO(u~p274TV$p?mc(j)vn9#Bz9mMgpv_v6)&# z`1c_kkKe<JI7d}uzD_r+uJ)4v3wUjNzWWVTyo7^4AU^PcL?n>y1peZOotGUHtn88* a3J1<aLYRp3+50z%9q&fM^zi4AZNC8rKC}P; delta 550 zcmYLFO=uHQ5Z>=K$!>PD$(p1!yCEhGR<ziLYQaDoAxH~?KUjaN2MetUB$ArHjjg?u z9!gIV!xU6nXuWt+Q1;+OJ$O+G(VK$On?;Hs6i<3+d}|KA;e9jjo0)Hhw=({9OuekC zvcS*x+s~$w&(*WegXa_GY$;L7mj?2;s^)Z|FmNn4T$?{$oK94;X02oviv?PD4ne0y z*9f^?HAH#z5`7%QG%2oOkba3}3{h5kfMME`7I1>@xUVTk`Jk%AL1MJ!UPX#3@;PP1 zW?6@A$}Khh|6LiRmYk$5<qS?!zb6f56+GKOo+i92n4>S=>sX+qZw5=W=6i!WO=&sY zwcctoz$W$k36JTuzY$oqH4P2|g03EDZN?}U$l?io2wcEZD;B&0yr8-6A81-PdX|8n zw7vf`K3T6qGO$bU^uw};x1X|w3iL;xG)!?*c_d_njANPUf{B}A#<{Ls6ppy4Z0KyK zi|R%SDz%JDG#c*3Z<-1pg4bFO7oq#Xb+msAF$AH(0Vep{4n}HZ91kh2gq(dmZBRL~ zh={ct*#M^-(G+6zF*=3~ii)9q-MmDzr8>VVNpv!nQ0{TI(y*a!&BrEy`_$|$;Tw&{ lL%P5O#%HlThfA|f)O;OJv+=9^M!MQeq4)79LbMY<@E6{0kk<eJ diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-38.pyc index 42af3511dd1e1182d7756a21506feb77e46839fc..2b5d6836878f0d5a6217876fd7409a99e064bdab 100644 GIT binary patch delta 944 zcmY*X%}*0S6rVS{U3QnUmO?~B)l!Uss1yVukSOvMFbWa~0VU8Bc7=Yh;Ov$_*@^)< zsPUkq_twON+zinJHxu<@;vYb~8*iRG7y`a29(0rUdmr<gdB1%#+owODF~-Wubb_CD zup4_Bd}f5edwV`k!&X<m+pH-7kbYuD%-V;<thIVJr8~VQ9VPW=cV5v?(9NRriwjni zt!6UGMATukQ8R8Qtn}<6b1kP~Wi=aJw(R9-Ix!PnT6O0a?dFEIsFQH5i%ap@RD90j zPvl>4nQ!<^=-}UdTgFus!x|B?(#qu2PDZ%|>k43MxFioA6d*^(iQOv`m!@<!0wgB^ z$)0m16Y{bLo|N<nGiepsq9+N)N`Y>|28@$dVj}y#G(m0?n@$jqCQCdLD?zWakFJ*2 zM1&n=PfqHll%ni8R@X~Cxd37*C9z#>B#YzhIzeLFi2fq#&aQ|Z!SJD!;!%PrB5b4D zib;fb%dldwZvykj3MgfcYyz$rZUAfL#kd@!Alnx>ZPVh$ph<A_%22j?IL;g^Y%#XT z!f`hoS!=9exkyKNttt0I#o6u2cN1wVTYlYMj;9l5cx>cmcrJlgkq!J)LVjbezJh;I zn|yoHf-}eW)l<5jVd;#$gdKR5=Cn-WaZU>Y0SX2L5M>Aw`H&tSS5#2I4?0$L^jH%n z1^9cd9Uk+a+Q9U@2YG5rdC4PUvf@Euq_Lwqj`eT;pvdzTdD;=rRK$H20ROpUDC?U< zu~V!Dg=Br#g!11I=9_vAzMI#29rW<8dL*<g)Sf7+RjC3Yv;bNVb?RI#oe6Z{8XH8Y z2iAj*-_t5en6<=Wu}AzxX<O%jAlwo#ETH;-2#K^6VF=9;qgFxotJP{nv0C59OZ{)) z%Fa9g7L@G;2D?UX^o_(u`-Z!CztN|(iS6zDsnHDc{DaYX0Y^$Gp@%Z12eMQN2KA#E TIAY~cmSj*d_tQ%1mvre58`kIp delta 780 zcmXw0%}*0S6rVS{UAFCZ+Y&^KjczM`R3KEolo(_EXcR$WP(p<$sqPA`?Y7Qti78u1 zKrSR6%y>1~dXsR_^l#9UXAi`?@gMM7-_*F9_nY^AGw;2b-}`p@;FP`?iG&D#zcxNU zmE!O81h6kd1=@dym`OABhL|bq=B~7S%cKuU`b_(feucqDqi&@(S}WE@inikx%H@%< z^@;lH@oHhzvD|vityastE&qWjeh@HWnn#tr;5BT*G6?OD${1|_K(C>@#0L*r(4<Sm z&dS84FGFk|NK*pRNV$>;zU+Y~l>)*{dYtUh6Ql*ZumekEl9+gMOUjeS#HM-T(URhk zRRz}`_TE)}Rd`rk_T*BK?I4D_7<9JxMd0jX3rQ3c2QjtBR!kyRH;jzN4h8y=7M5Ql zyMQ~It0Ncf`cd>^?7KjlcJpE;L7C+F#?XwtQ79KpgITZYMP^kj+Z{G)1?E_W#aQ(m zGYYPe+RP+bGxb{)V#NQaEH2C$YsC%APRDsBc<Ce?6w;kVI8y7Z+%0mXIM3Iu3V$1P zhV!`N3?mSrphFB%hTabC^vfzJpy4lfkn2#Y@`=ziG`JnQJDc~wr>5jf9x16U90K6W zQKnj#m%DuMA8!W47+QdDQ|23imCa1^2}@$bMj&fo!27~U9P?E80%ZAWI5kiaSL*9t zNu>%T&|+x4{6qLzWEy!kgOCQ6<(ig&EuPk{gmZ$Q6)?xkT4F%Bj*vzLSyPXxaW;uT z`Zo8qPjIz;FR}-b<=Fij3$wX})rYwUIsQ}6!DW6vIu0-RO7!|gl!DNX3~00ubgH50 SD2~#RB^gwVH3@~1H0dwEvbx>? diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc index 70e92abf2bc97aa0b0a09f3559b5a4edab971538..309f3bd5a028f70555e38b582e484871aaa7f49f 100644 GIT binary patch delta 1108 zcmX|9YfKzf6rS(y>@YjPu&^xPvIDgB0raumLSZReX;BJAY-6;xO4=3a2ul}OXL&Bf zR>T6fJjx+aTa~27{xFe9rZLs}{DVzn!yk=NQyWc;CPp!7LbNSi?|^ZV`R=*rJLkJ+ zzPXEMarrFN1F5Nsz#qrmk3vI{d9|KZM}4iG?YhtC@9u63`(j43?`Ts;SdTP!8eMv9 zOJ9H7*Q0mz_#)wFebN4|*3OQSEdgIF+@)`hHZ>n>YSGO>b`8j)dT|~at#f!N%YGFb z=qLMi6m#^_57H(0X(s7g1Sle3M3uSD;RI?p>7fQ?8Zd7tB6B~+M~kfvh!luWS)MJf z(Ti#}xl*sW8~<l*azbTng-QRhnd&n*O5JKdT4+iA6>apE(@!gQH)+lj=;pi6aDtAc zzlWD7C1V()bS9%0r^(@Z9#b^n>SZ$m<<^x^apqRMMva+Y;hb6MejJ#i!K{4P=#8uo z(;v0YFXSLIktvGoFrUjFvEeuR(=&@dXd-u%{Uy+K?Otjx_0W<xhdR8KxJmDN&#`5J zYPA{mkHt^0I|8-meUP?j2^Opgrg&|%BmWD4?&J@p3E+&x838g>yE$GEOiv!>$(vR# z?xXo~7ya&kr>Ms&%(IfoA{h5ff^?T9L_51JCPYPMIbZ@yaG%yX6#9DGG={0AWIe{{ zm6A%Fp@otWT%>)ay|_dRrAIJL{?eTER<8N6rOqsM7Qb&*;h468ek^y;`1U@0PEy&t zMw~4Y4Vf?BtKnEE+8OII^oZUR(~TJ_*sj^zIQ1PZm(8)iK^Mv|-!se;#%T^u>?yJv zervbYf^mumwz1owxxfHiR9sPmQxvUOk5`E*Hl``oG(ld-{Xgurncq}+p^fo<E*~+b z@<6aI4HS+}mI7nUR4bo?RLp5(h}whu@g{u|^hz7o5;uZ5&Xc^!7_nf~f=No+xj%o3 zhxc2WP96wQY#w-4-%Z%Wj44Vent6WbED)sXsw#eAhN@zypyjGX?4yNUS8#|XcL(q? zUD;iPgS1kUOR3cd@wBN|4+4kj=ZAhl7Y)=rKuZsw!V5fVlqRj?->1%`97j?p6wy0E zp;6x1#~tX|^Cchr!P;g_(D~Y4%#x?>0N$o(-L14wtuaO3D+)}A7ZU2-G_m)|><d<Y z)e@#cw#$%YZi{3l_Uhn2PJiTTa=<Dn;H@%fM}r0r9ctK&5jxorPJZ2*#<G@w?X8Ag X?tt^SU~~Fqg|Ej2r(%<n<&1v;z+*IU delta 1104 zcmX|AZ){Ul6z}i$?d|ooeS2Fe9c#NSOARh$mUXqPQc|Yd7z{R@4ns_+sM9U9YkeJV z_$M<1*}`<p9wKBQe}ai$blG^ih|GY2L_&}y#y`<7gb&CEqbB-+WTdP2HsHH?=brmJ z=bn4c@1A>c21_&0dYw+y!oRz3%<bNvn%B0mKu>Tel?i4BG7STR*`YnjWJ9Pwyl<o_ zy(gIM8`_r{N~e?N4ErANP`@;fYKq&cC|q(K0eV`kqBZgrtSf5w<gXE;^QFHaN{5v% zu-S~;bfBFZKLa!Ks>D1!{P3(MQh);zG^+!S6<MY(w};j_m%IsKuMl>tQqUO7Gg*Sn z2g?_I0@_PR(zv!CX+qgu7&NChl2>+9P=6Qi@YN+uP^SEIOj32lLHo3b$3#3<+<&!V zCytWW^*WBz2d-gu(n9u*2*p;d#~Dhkx`A`%6Ygh$1)5r214gr}FO+wQ7>{zHFo~&7 z#c7Us#;y1#=RJ*kbjCY@W%|qi2zB{V$kU?l1has4`HwOy=x_fNlR=}^3!b0<4`XEo zrb$pOYC)2ywdPycNv<6$Q^60Cxtj$FG|4<x8!IoH7NEp22b98_LAn(3)BVO1fiZ#m zgtJ`&<6O#2&a;9fvt_9u*%hWkqs7p99H4Yl9VaE%v=JZE&8Bf&rk&woT&0`g-T08^ z!<8ldJj^xP_V^XtAT2VF99@ohW#XtYO}8UH+@Y1oEH9sCH(XqEK;V;HJl9@dVl;}? zdLiDYvE~pfWwg-z7HTLIZNp)@UtNcf=ys=zW}}rJm&m%6J1c^O#6uFypQ1kaCpf;A zU)F;L;q3vH7p5}@j0scQxC?TGoBy>?D%OpY^i9ksZ{UD&if+X!_4h;$hlCgxVv0&P zbq9}dH6&uza>WAGT7|0OFG#Cfk)#K+EE>@`LVmm7%xyXi^iU`s$1yVES#;Cy@g=-M z3!ATDkVadYage@hsYi<bZ1YmS<#}Yx-Y4G%vh>4KcX-iz+t$*p)=A!Kd)r=+r})Xn z9A#V{^|#VQBH1^XNSxwZM{t&2ZT}7?J+|d#d_uV`!}yZaj$T}#7dw`nKZ?A?)k};O z=(VjW@1j78&x2`DN)*TnXGqqVv||3TwGa4}p6R?^zvE%S3RB&RO|kOfQB*#-#-Qq) zcdn^^YTe#|Lu70p(2t8G#SIvOGUHP!bb5&G2)LvAsKus-6&s&NEiS&%u6X|gxV<4) diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-38.pyc index e643152705ac0e703e78f4dc3d619d59d9ff614b..e72a749f63c040d3128af8985f43a796a2e17327 100644 GIT binary patch literal 1472 zcmbVM&5k2A5VqZ&?xZJ~U3M3=hdnf~utdXjkHm$;XoLhpg2P;Z1p=#9Pur6?=|60D zW)d<NmM7o|lH*)>03Lxy@D&MZZ+qSYqN*qRGr$Qa{$jhz<*NFs^3`Av5E#9`eoLNq z2>AmyuMP(`AHme018~A=P6|4r1sk!#895ZsSniHo?r=Bn6yC@y{E<(IaMxYl+0aps zd))t-i~`=}J^0<>><cmso`5|vbnK1vL|1uZL?Vm2QpR?<oJ%dM((cwumL@rE%FMw2 z_zA@;%<g_x&eL4-heEY_{&unSzS~ctM|&CSJs-GsVSWr#-vlsZO*vhW4O_Df0aw`Z zGrA9++)lEztV)@I?WIVR7>jf3=;p+B^6E^eA+>Iq7UGhq0oZvqizihfVzp?Rsf@MC zVxE>#<QYUEbacL0#&c25<6NG^^}<Z5@`LEZSW6@J>ol9CW1-`EHin0E)u;@13Fz}m z#aCikj^oD2Tu1f7zIM$wbYm9-VgQ7x8-UlM#&aaLjru7pmVHB3<T1S<Uz75#OAMU_ z>OLj-SrLzX3z_(ajL8LLX3997IqK6DT|1nuT|C*)4Fyd&F`c!CWb@A2zoHi8-A}+a z=s2wwnf7>h)>FT<7F^KlVF`d<Z>xv4$P`Kfw0>>1g7%$Y`wp4zw6fn@*-k6lc_Hh! zvOil{zm@f`WE|dFfgix?VEI!J!uWC`bqL?NP>WE@LguLoO%-lyCQ1@*RFb?Oo-`($ zq&loh5d!HZ7a^CYr$UJmxM^*jNizw}M1*JQB9y3J@?7ZlNQqpe8m@|QAxaaq7Zg_C z(*5z^;?1T1-uKbLaPPh)mPY>~3;Rstd;?%b9_?OGAdEhy4}qW`7zcVT>G36nf;8%q zSr#2wdfpb|6<|5o-r-o3;=EQz56~9Yy-OHbKDbsrkP7UZ=rFIK*7Z^J;@0v1@k`x; zXVh(k*AcKeUizf&!gdelOK-YSU1<YJS^5zdb6mK4fWv|E@vaA8JEE?#iS^RDhNiII zX{CzPSf+%+!nW?TlBM;xX}3<Tgmuxbb-*UJEW`$X7XCI`+o@A!^gq0_cm69g7>j-j zfOw4d=`IVH>jd<c`!3);Ts@ymy#rdqz6}!ipE8XSNusd%6cVbC0Cf-HZ3GOg4bl2p qRn#&Us)t9|zOA8Gylb=AlG;5iD&FMc2(4)h{toN1n@-?#JAVTc`fPsy delta 218 zcmX@WeT|tfl$V!_0SKO#ZHQaSIFV0=(P*N!yhJL?0@f7fg^W>bDJ&_hEeuiYDNMl( znrsuRj3=JW(gbPw<*Q$kTcBT%S)iMlS6q^qlcQ^tVNzOQoS&#)oLW*^P?DdYGr5k@ zwvY#?x|j)M3sVt@t;unVD?UE0w4}5sH9o!wBvZr;B3OXLEvBN>TkOgCxdoXysYPrc jVUV68kd;UTH%KXmO>TZlX-=vgNMkWbtq2nbGZ!-ese?2X diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-38.pyc index 4f27ed88ef24556fd73b28b5e2e4fc9134d2257d..125fbfc24a91b381e6b3e969bee53788cf5e90ba 100644 GIT binary patch delta 2860 zcmbtWZ){uD6@TZw=a=XB-?QU1wv*V78<LnbcH0yZl{9Oi9Z-r1lv4hTW^UeF{@d<- zX-M5P6B-kIp%OX>&;+b(8c=DPG*y}qU!W4&hke-iLJ>jQ5Z^Y0G$A3_CXt<U?H3GN z#Rs1C&i%b}f9KqL?mg#TUp)TDQ{fY#P`g5p|Eo8r|5W&WIH}#bT%4;eJ4JEs?Ae9+ zqAO;KcDXX|EX`EKisKg6ⅇnPGz;YG=I8SJGU}dt&A4Ni|+i2Gg2$hES6^-yi3~y zop?dJ27P$H{#O{nQQxm&7ryWNF%08h+Pm?eJ{?aQbtvLSdlEk}#-JeelWiNYSL&{{ zjlmwN%bOc;lhj=`$6%k-#r+#FE_J{4kHMJKZISL4(oMmB`u-gpz>UCKV34A7EfOXm z1V`X?EC#1bj$udb*b~an;Nc+Q4m&P!h;XO9L*g*uE;}J{gmBVMNo*1BwtFOw+P%k> zd>Wq(J`G1O7diuX;<KTb;27==FTp+d%Ww^jqZK(40OF~ozi-ilS0hP7glI}9aXpgq zIkoD{97e4So`~c!VbVXsb5=<xYQ6KAGh3cH_kbhZ`D&$r?bZPE`Z%QN7GCt5yqZAE z$})3jlvpz@%-FY>Rd>Z3Jr^O~Yzy~WUTtT!NgaSin*1_U@gI?+`av?Guu@id-kq+I zL*XnrW!G`>v^7K)J3U4^KrWh{kCADw#xBp~lK7(4kFTZDfkWg<+{)rM{3w^$<tKQU zUUx4E6HMLIOihLM|My<`!di#!Cz;L5qd*vfY7kV_Qp0Lc6DROu?BxOR1L_iYvnY|M zx83-Y`AT_dWYgT;eDVfS@9UU^`|+8ME_mU}<&F<Ecn5#pb-v^Tx3eWi*vpm<!d|w- z347VnN!ZJl9fW)Bw9K3?J3|?fy<#Mu2lyCYPL9D*yq0`2@F>rV6F^MiT<WR84+y%u zNGKGE4q=Kr1w9Z46-*_zrD|~qerX1AXZPdqIsT@5<fjI4Z)2;sNz5u2U|m^IY*^Gp zb{#H(tzJ@D^9sBIph%5&Nwam^_k==v{V)|pvrk#@*~+3{oR%zuSZz&~?;9*bvNj~k zJSE*5+b-H<=PzWZU-q?a_nETq53;Xa_L+@7n+98_Y0w%4N&+a5f9vOWU+5D@@o$-l z!OI{<Nq1QlTmqZ0CgRjKL?@#%2?g+A@1i02+og@{7-g+a&Rm^=qAGQ>z}ZTk>um+f zL<agW$-G|{sCXEibP;~U*7<QV`jTEZMM42xYloQDLz3T^_p0>>z8cEnyJ3IIBpxsI z0>vS^=_9X-ebk5$TH&sY93sy1Y1Vqkt8(v1NL}AWm|dg<9~X%h7ZJ||9Ta`nx3<{2 zS8$c|v{(l`>zZ)z>OkjSnMVm?HNp__Mr%V-Ij-3BURF!ONBv%8QFfdbeCA|Z90#`@ z^Jzn#i{I&4thKm}u-iGo$5Vfc+wJ+%-p!DH`(ezREJqn4(42qPhD)lg+M3LD+L%Tj zH)7#<@_I?;*nyV3IaDSG!#wPE-ekRamZ~%5rNV@4+{wbktW$B;YGN|4HFi2irec+6 zk5hfV=n#A10##HK5^6n!7b9u>JiW(H3&<%=RZm<)93Wi8W0`#q{gBZ2sp6JWYHO5| zIKu;RCACKB<0vO^fA;3SvxM@#W(6>JKZ{isoNwYWu7@3y1V=d@`42*E)&stk?Z-b4 zn8R}Exh#3<xz1}bLcr+jYTykOG8u6y=YxazVc#uX?9Vgus32r!8S-j4j1S~;oJIJl z?(g_ts?3%f1<&9Po}hP?dYeX<)YsQgDWAaexv|6oPvvG76D+ve1z$Y)YAVyo+aWk$ zafrqC{nRt|9(}u9)TY{_nmu$o^<3w6GMf4zx7fGyjo~Bgi)&Ea&f-oId3940&gv!z zSwoZ+C%NlU)cbGnEfc&O3;lUm#s~ZV6>D@!D|rwKzOOpuMy}xb8^(wD9@$Jz%j}$9 zZTy9pcAZ*Tlvk?46;o^rBF1K275b?1a`CaH=ycbr=2xPEzJbqRMLO;${o`m2RuY^c zCCc&L)CzfJaZ-y@OpBHY{)!!W<$`YxX5bOr94x{-Ge)Y!s52u?K%s?6ZRutLXz}P+ zHNoIkrQ!WCRaEi8q2~(s5Kr98;slGESOi$`WCbsb;Co+i5M=UEuIsK%b7Hw_pIve$ xc^)orXq>8!;|gkFO$Sv8Z|OcWXc<<oHO@C{^Y<UaZ$`~tJ!`F*nRd+#{1+;LX8iyF delta 1980 zcmbtVTWpj?6#mcu&;Rf2wR`J*yS-nw?Y5O-3j&p*1VmV<^;)qP*$Ufk+humCSXz*j z1YSg%lX%y(@d=+wki-X*h8JFW^Pwch2csbo6Oly4r1hM?wNzgHH}lPzGvAprbLPz1 zTm6@NeJ^>vE{(pQCl~u`;@5n|M$O^Y+*qbHlgh+X<JsI$Ivw9~V(Y2X?Gr<-+2P!& zOm1Q#jVa>^D8f&T@1O>i_#T?E$NbW2qm_QwaKRNupS2HKvD*<rWz9f4UUL?s)6ofA zNcS;x*y9H@ev-zexKEyi?W8NgA7lq?vvpgXXJIGlj=&CkT;@6pPuq4kT%FKm>!cf@ z8$WZOb~lpite-&YSni3#ARh7zxRZfiEf!Qx(&L;XAH&`(9KcK7laRoN-p`>2Kk}vF zMKtp=@G4H`?ZtckDl<s*qj)DUMyos*JV0LG_eXFs=!YcU3^o{vm<NxA+TF}kyBWH1 zDHQSVCox+>AayCEA+H<ZX#j=q<`+XRev<!1-Q89C)bng|kYLKu_*QCsC>>vxZR=mm zQoYz;&;>7GcV!3{3k1wwzfo|<fN7j7Ib$V5bfWO}zS0i?ZsYw(C+x?@vWxDcyk;Lm z0>3T0)P9S^>^1^T_kaMOp+gBoKnDqOMHk!$*Lxm&ev=^_jh=_QcrO}1C&}&^Ug1}Q z<Jt^NYa`kSBw^H0HPbM!C-r$_O}79G0Gh2c=0#E@%?p}6V?L|R(wsfZ)>cv*b*i+@ zw20~0U|Nqc9p`N76`Ly89XXQDVr|oM(&l_^b6o2j`54D(bAGfr?s+508}w|rb^hy? zx0s|YP19y6y559W0iFAyIMX&$srKXT+MVvJpxQ}yRagDkRZ(CK(%^xHeHEkDNfMRf z>uP1~pVYE~Kxn!)C0jBR*&HpTOj1obT9U()G@24kgm^i!-Ju@Ymk$!hB;OnMF_+p( zI^|_}4Fi>}@H%-atp9}+*(iYq!tg-Yh!S!uT5kd(t3u$J$|}5F?ZgK)4NlrTpMf$Y zP+es1BGH9=YPSw>D*pdV-V{Mc!VaLyus4q1u1!HQ2T5CqjddM$Ig%*hH=U3To?<w~ z;A5D?^L2$mA4kP5Rr>mQ@vFL;b2>3N)^@VikdUL~n}r!l)oB>DR0Z8V$w_^IQnpy@ z)soa=Mnb*KOY@be(*!YHl~dQ}n;cfz)WrBeHm6eK$5ogKHsrI!55AN)Vv(Tf5`=^) zFWw78@kqV1nThOw1V;3X-|mfB$|zMz6EU$Y-lWpGcG^6gt12^hlfDw8^*gFPn@k^> z80sC;uUP~T>LXB#@6}gP0SaPeLuX5hXFC{nGVpU(dl>j`RTsm5YgAE;U-lBUY!!jj z1-QVqB1~CL^(v}^i|T~SL(RlL8ou#!SQS@QwU=QZF2(Y#msvcD%duKBO=2U8#u%ir zrSY%e+7u}%p#4m<tC)S`J=oK<t${1la`8ZV;@D7nU?bSWnPD}Qn^0MmU|Uc@eocjA zG&soN=1pr9YpSa&Y7Fl*-N!&(*yQ^j#GjhSi*h6-Vuos?UfHFPZ%Dnt%LE2Vys+`8 zbbS@C#LJ-%7vrsP0<Sd{cD};1%|z2Ior<LZ3#=7=Rjdkc5l~?0iAk`y*J%q*sp~7! zRO49D@`3vhS*gPey?C=F<mZs6iwwMdA}xgq@$Z(rgZ%Fhrkvqpc!W;H!TzlZQ&3s< htq4nc{FXoJucWa?zRgD*%aj2b5f%PXS?)5V`yZ}QsXqV! diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/_compat.py b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/_compat.py index 210bb80..25da473 100644 --- a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/_compat.py +++ b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/_compat.py @@ -12,9 +12,9 @@ PY3 = sys.version_info[0] == 3 # flake8: noqa if PY3: - string_types = str, + string_types = (str,) else: - string_types = basestring, + string_types = (basestring,) def with_metaclass(meta, *bases): @@ -27,4 +27,5 @@ def with_metaclass(meta, *bases): class metaclass(meta): def __new__(cls, name, this_bases, d): return meta(name, bases, d) - return type.__new__(metaclass, 'temporary_class', (), {}) + + return type.__new__(metaclass, "temporary_class", (), {}) diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/_structures.py b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/_structures.py index ccc2786..68dcca6 100644 --- a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/_structures.py +++ b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/_structures.py @@ -5,7 +5,6 @@ from __future__ import absolute_import, division, print_function class Infinity(object): - def __repr__(self): return "Infinity" @@ -33,11 +32,11 @@ class Infinity(object): def __neg__(self): return NegativeInfinity + Infinity = Infinity() class NegativeInfinity(object): - def __repr__(self): return "-Infinity" @@ -65,4 +64,5 @@ class NegativeInfinity(object): def __neg__(self): return Infinity + NegativeInfinity = NegativeInfinity() diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/markers.py b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/markers.py index 892e578..733123f 100644 --- a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/markers.py +++ b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/markers.py @@ -17,8 +17,11 @@ from .specifiers import Specifier, InvalidSpecifier __all__ = [ - "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName", - "Marker", "default_environment", + "InvalidMarker", + "UndefinedComparison", + "UndefinedEnvironmentName", + "Marker", + "default_environment", ] @@ -42,7 +45,6 @@ class UndefinedEnvironmentName(ValueError): class Node(object): - def __init__(self, value): self.value = value @@ -57,62 +59,52 @@ class Node(object): class Variable(Node): - def serialize(self): return str(self) class Value(Node): - def serialize(self): return '"{0}"'.format(self) class Op(Node): - def serialize(self): return str(self) VARIABLE = ( - L("implementation_version") | - L("platform_python_implementation") | - L("implementation_name") | - L("python_full_version") | - L("platform_release") | - L("platform_version") | - L("platform_machine") | - L("platform_system") | - L("python_version") | - L("sys_platform") | - L("os_name") | - L("os.name") | # PEP-345 - L("sys.platform") | # PEP-345 - L("platform.version") | # PEP-345 - L("platform.machine") | # PEP-345 - L("platform.python_implementation") | # PEP-345 - L("python_implementation") | # undocumented setuptools legacy - L("extra") + L("implementation_version") + | L("platform_python_implementation") + | L("implementation_name") + | L("python_full_version") + | L("platform_release") + | L("platform_version") + | L("platform_machine") + | L("platform_system") + | L("python_version") + | L("sys_platform") + | L("os_name") + | L("os.name") + | L("sys.platform") # PEP-345 + | L("platform.version") # PEP-345 + | L("platform.machine") # PEP-345 + | L("platform.python_implementation") # PEP-345 + | L("python_implementation") # PEP-345 + | L("extra") # undocumented setuptools legacy ) ALIASES = { - 'os.name': 'os_name', - 'sys.platform': 'sys_platform', - 'platform.version': 'platform_version', - 'platform.machine': 'platform_machine', - 'platform.python_implementation': 'platform_python_implementation', - 'python_implementation': 'platform_python_implementation' + "os.name": "os_name", + "sys.platform": "sys_platform", + "platform.version": "platform_version", + "platform.machine": "platform_machine", + "platform.python_implementation": "platform_python_implementation", + "python_implementation": "platform_python_implementation", } VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) VERSION_CMP = ( - L("===") | - L("==") | - L(">=") | - L("<=") | - L("!=") | - L("~=") | - L(">") | - L("<") + L("===") | L("==") | L(">=") | L("<=") | L("!=") | L("~=") | L(">") | L("<") ) MARKER_OP = VERSION_CMP | L("not in") | L("in") @@ -152,8 +144,11 @@ def _format_marker(marker, first=True): # where the single item is itself it's own list. In that case we want skip # the rest of this function so that we don't get extraneous () on the # outside. - if (isinstance(marker, list) and len(marker) == 1 and - isinstance(marker[0], (list, tuple))): + if ( + isinstance(marker, list) + and len(marker) == 1 + and isinstance(marker[0], (list, tuple)) + ): return _format_marker(marker[0]) if isinstance(marker, list): @@ -239,20 +234,20 @@ def _evaluate_markers(markers, environment): def format_full_version(info): - version = '{0.major}.{0.minor}.{0.micro}'.format(info) + version = "{0.major}.{0.minor}.{0.micro}".format(info) kind = info.releaselevel - if kind != 'final': + if kind != "final": version += kind[0] + str(info.serial) return version def default_environment(): - if hasattr(sys, 'implementation'): + if hasattr(sys, "implementation"): iver = format_full_version(sys.implementation.version) implementation_name = sys.implementation.name else: - iver = '0' - implementation_name = '' + iver = "0" + implementation_name = "" return { "implementation_name": implementation_name, @@ -264,19 +259,19 @@ def default_environment(): "platform_version": platform.version(), "python_full_version": platform.python_version(), "platform_python_implementation": platform.python_implementation(), - "python_version": platform.python_version()[:3], + "python_version": ".".join(platform.python_version_tuple()[:2]), "sys_platform": sys.platform, } class Marker(object): - def __init__(self, marker): try: self._markers = _coerce_parse_result(MARKER.parseString(marker)) except ParseException as e: err_str = "Invalid marker: {0!r}, parse error at {1!r}".format( - marker, marker[e.loc:e.loc + 8]) + marker, marker[e.loc : e.loc + 8] + ) raise InvalidMarker(err_str) def __str__(self): diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/requirements.py b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/requirements.py index 0c8c4a3..c3424dc 100644 --- a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/requirements.py +++ b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/requirements.py @@ -38,8 +38,8 @@ IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) NAME = IDENTIFIER("name") EXTRA = IDENTIFIER -URI = Regex(r'[^ ]+')("url") -URL = (AT + URI) +URI = Regex(r"[^ ]+")("url") +URL = AT + URI EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") @@ -48,28 +48,31 @@ VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY -VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), - joinString=",", adjacent=False)("_raw_spec") +VERSION_MANY = Combine( + VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), joinString=",", adjacent=False +)("_raw_spec") _VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) -_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '') +_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or "") VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") MARKER_EXPR.setParseAction( - lambda s, l, t: Marker(s[t._original_start:t._original_end]) + lambda s, l, t: Marker(s[t._original_start : t._original_end]) ) -MARKER_SEPERATOR = SEMICOLON -MARKER = MARKER_SEPERATOR + MARKER_EXPR +MARKER_SEPARATOR = SEMICOLON +MARKER = MARKER_SEPARATOR + MARKER_EXPR VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) URL_AND_MARKER = URL + Optional(MARKER) -NAMED_REQUIREMENT = \ - NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) +NAMED_REQUIREMENT = NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd +# pkg_resources.extern.pyparsing isn't thread safe during initialization, so we do it eagerly, see +# issue #104 +REQUIREMENT.parseString("x[]") class Requirement(object): @@ -90,15 +93,21 @@ class Requirement(object): req = REQUIREMENT.parseString(requirement_string) except ParseException as e: raise InvalidRequirement( - "Invalid requirement, parse error at \"{0!r}\"".format( - requirement_string[e.loc:e.loc + 8])) + 'Parse error at "{0!r}": {1}'.format( + requirement_string[e.loc : e.loc + 8], e.msg + ) + ) self.name = req.name if req.url: parsed_url = urlparse.urlparse(req.url) - if not (parsed_url.scheme and parsed_url.netloc) or ( - not parsed_url.scheme and not parsed_url.netloc): - raise InvalidRequirement("Invalid URL given") + if parsed_url.scheme == "file": + if urlparse.urlunparse(parsed_url) != req.url: + raise InvalidRequirement("Invalid URL given") + elif not (parsed_url.scheme and parsed_url.netloc) or ( + not parsed_url.scheme and not parsed_url.netloc + ): + raise InvalidRequirement("Invalid URL: {0}".format(req.url)) self.url = req.url else: self.url = None @@ -117,6 +126,8 @@ class Requirement(object): if self.url: parts.append("@ {0}".format(self.url)) + if self.marker: + parts.append(" ") if self.marker: parts.append("; {0}".format(self.marker)) diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/specifiers.py b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/specifiers.py index 7f5a76c..743576a 100644 --- a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/specifiers.py +++ b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/specifiers.py @@ -19,7 +19,6 @@ class InvalidSpecifier(ValueError): class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): - @abc.abstractmethod def __str__(self): """ @@ -84,10 +83,7 @@ class _IndividualSpecifier(BaseSpecifier): if not match: raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec)) - self._spec = ( - match.group("operator").strip(), - match.group("version").strip(), - ) + self._spec = (match.group("operator").strip(), match.group("version").strip()) # Store whether or not this Specifier should accept prereleases self._prereleases = prereleases @@ -99,11 +95,7 @@ class _IndividualSpecifier(BaseSpecifier): else "" ) - return "<{0}({1!r}{2})>".format( - self.__class__.__name__, - str(self), - pre, - ) + return "<{0}({1!r}{2})>".format(self.__class__.__name__, str(self), pre) def __str__(self): return "{0}{1}".format(*self._spec) @@ -194,11 +186,12 @@ class _IndividualSpecifier(BaseSpecifier): # If our version is a prerelease, and we were not set to allow # prereleases, then we'll store it for later incase nothing # else matches this specifier. - if (parsed_version.is_prerelease and not - (prereleases or self.prereleases)): + if parsed_version.is_prerelease and not ( + prereleases or self.prereleases + ): found_prereleases.append(version) # Either this is not a prerelease, or we should have been - # accepting prereleases from the begining. + # accepting prereleases from the beginning. else: yielded = True yield version @@ -213,8 +206,7 @@ class _IndividualSpecifier(BaseSpecifier): class LegacySpecifier(_IndividualSpecifier): - _regex_str = ( - r""" + _regex_str = r""" (?P<operator>(==|!=|<=|>=|<|>)) \s* (?P<version> @@ -225,10 +217,8 @@ class LegacySpecifier(_IndividualSpecifier): # them, and a comma since it's a version separator. ) """ - ) - _regex = re.compile( - r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) _operators = { "==": "equal", @@ -269,13 +259,13 @@ def _require_version_compare(fn): if not isinstance(prospective, Version): return False return fn(self, prospective, spec) + return wrapped class Specifier(_IndividualSpecifier): - _regex_str = ( - r""" + _regex_str = r""" (?P<operator>(~=|==|!=|<=|>=|<|>|===)) (?P<version> (?: @@ -367,10 +357,8 @@ class Specifier(_IndividualSpecifier): ) ) """ - ) - _regex = re.compile( - r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) _operators = { "~=": "compatible", @@ -397,8 +385,7 @@ class Specifier(_IndividualSpecifier): prefix = ".".join( list( itertools.takewhile( - lambda x: (not x.startswith("post") and not - x.startswith("dev")), + lambda x: (not x.startswith("post") and not x.startswith("dev")), _version_split(spec), ) )[:-1] @@ -407,8 +394,9 @@ class Specifier(_IndividualSpecifier): # Add the prefix notation to the end of our string prefix += ".*" - return (self._get_operator(">=")(prospective, spec) and - self._get_operator("==")(prospective, prefix)) + return self._get_operator(">=")(prospective, spec) and self._get_operator("==")( + prospective, prefix + ) @_require_version_compare def _compare_equal(self, prospective, spec): @@ -428,7 +416,7 @@ class Specifier(_IndividualSpecifier): # Shorten the prospective version to be the same length as the spec # so that we can determine if the specifier is a prefix of the # prospective version or not. - prospective = prospective[:len(spec)] + prospective = prospective[: len(spec)] # Pad out our two sides with zeros so that they both equal the same # length. @@ -503,7 +491,7 @@ class Specifier(_IndividualSpecifier): return False # Ensure that we do not allow a local version of the version mentioned - # in the specifier, which is techincally greater than, to match. + # in the specifier, which is technically greater than, to match. if prospective.local is not None: if Version(prospective.base_version) == Version(spec.base_version): return False @@ -567,27 +555,17 @@ def _pad_version(left, right): right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right))) # Get the rest of our versions - left_split.append(left[len(left_split[0]):]) - right_split.append(right[len(right_split[0]):]) + left_split.append(left[len(left_split[0]) :]) + right_split.append(right[len(right_split[0]) :]) # Insert our padding - left_split.insert( - 1, - ["0"] * max(0, len(right_split[0]) - len(left_split[0])), - ) - right_split.insert( - 1, - ["0"] * max(0, len(left_split[0]) - len(right_split[0])), - ) + left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0]))) + right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0]))) - return ( - list(itertools.chain(*left_split)), - list(itertools.chain(*right_split)), - ) + return (list(itertools.chain(*left_split)), list(itertools.chain(*right_split))) class SpecifierSet(BaseSpecifier): - def __init__(self, specifiers="", prereleases=None): # Split on , to break each indidivual specifier into it's own item, and # strip each item to remove leading/trailing whitespace. @@ -721,10 +699,7 @@ class SpecifierSet(BaseSpecifier): # given version is contained within all of them. # Note: This use of all() here means that an empty set of specifiers # will always return True, this is an explicit design decision. - return all( - s.contains(item, prereleases=prereleases) - for s in self._specs - ) + return all(s.contains(item, prereleases=prereleases) for s in self._specs) def filter(self, iterable, prereleases=None): # Determine if we're forcing a prerelease or not, if we're not forcing diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/utils.py b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/utils.py index 942387c..8841878 100644 --- a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/utils.py +++ b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/utils.py @@ -5,6 +5,8 @@ from __future__ import absolute_import, division, print_function import re +from .version import InvalidVersion, Version + _canonicalize_regex = re.compile(r"[-_.]+") @@ -12,3 +14,44 @@ _canonicalize_regex = re.compile(r"[-_.]+") def canonicalize_name(name): # This is taken from PEP 503. return _canonicalize_regex.sub("-", name).lower() + + +def canonicalize_version(version): + """ + This is very similar to Version.__str__, but has one subtle differences + with the way it handles the release segment. + """ + + try: + version = Version(version) + except InvalidVersion: + # Legacy versions cannot be normalized + return version + + parts = [] + + # Epoch + if version.epoch != 0: + parts.append("{0}!".format(version.epoch)) + + # Release segment + # NB: This strips trailing '.0's to normalize + parts.append(re.sub(r"(\.0)+$", "", ".".join(str(x) for x in version.release))) + + # Pre-release + if version.pre is not None: + parts.append("".join(str(x) for x in version.pre)) + + # Post-release + if version.post is not None: + parts.append(".post{0}".format(version.post)) + + # Development release + if version.dev is not None: + parts.append(".dev{0}".format(version.dev)) + + # Local version segment + if version.local is not None: + parts.append("+{0}".format(version.local)) + + return "".join(parts) diff --git a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/version.py b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/version.py index 83b5ee8..95157a1 100644 --- a/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/version.py +++ b/venv/lib/python3.8/site-packages/pkg_resources/_vendor/packaging/version.py @@ -10,14 +10,11 @@ import re from ._structures import Infinity -__all__ = [ - "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN" -] +__all__ = ["parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"] _Version = collections.namedtuple( - "_Version", - ["epoch", "release", "dev", "pre", "post", "local"], + "_Version", ["epoch", "release", "dev", "pre", "post", "local"] ) @@ -40,7 +37,6 @@ class InvalidVersion(ValueError): class _BaseVersion(object): - def __hash__(self): return hash(self._key) @@ -70,7 +66,6 @@ class _BaseVersion(object): class LegacyVersion(_BaseVersion): - def __init__(self, version): self._version = str(version) self._key = _legacy_cmpkey(self._version) @@ -89,6 +84,26 @@ class LegacyVersion(_BaseVersion): def base_version(self): return self._version + @property + def epoch(self): + return -1 + + @property + def release(self): + return None + + @property + def pre(self): + return None + + @property + def post(self): + return None + + @property + def dev(self): + return None + @property def local(self): return None @@ -101,13 +116,19 @@ class LegacyVersion(_BaseVersion): def is_postrelease(self): return False + @property + def is_devrelease(self): + return False -_legacy_version_component_re = re.compile( - r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, -) + +_legacy_version_component_re = re.compile(r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE) _legacy_version_replacement_map = { - "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", + "pre": "c", + "preview": "c", + "-": "final-", + "rc": "c", + "dev": "@", } @@ -154,6 +175,7 @@ def _legacy_cmpkey(version): return epoch, parts + # Deliberately not anchored to the start and end of the string, to make it # easier for 3rd party code to reuse VERSION_PATTERN = r""" @@ -190,10 +212,7 @@ VERSION_PATTERN = r""" class Version(_BaseVersion): - _regex = re.compile( - r"^\s*" + VERSION_PATTERN + r"\s*$", - re.VERBOSE | re.IGNORECASE, - ) + _regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE) def __init__(self, version): # Validate the version and parse it into pieces @@ -205,18 +224,11 @@ class Version(_BaseVersion): self._version = _Version( epoch=int(match.group("epoch")) if match.group("epoch") else 0, release=tuple(int(i) for i in match.group("release").split(".")), - pre=_parse_letter_version( - match.group("pre_l"), - match.group("pre_n"), - ), + pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")), post=_parse_letter_version( - match.group("post_l"), - match.group("post_n1") or match.group("post_n2"), - ), - dev=_parse_letter_version( - match.group("dev_l"), - match.group("dev_n"), + match.group("post_l"), match.group("post_n1") or match.group("post_n2") ), + dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")), local=_parse_local_version(match.group("local")), ) @@ -237,32 +249,57 @@ class Version(_BaseVersion): parts = [] # Epoch - if self._version.epoch != 0: - parts.append("{0}!".format(self._version.epoch)) + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) # Release segment - parts.append(".".join(str(x) for x in self._version.release)) + parts.append(".".join(str(x) for x in self.release)) # Pre-release - if self._version.pre is not None: - parts.append("".join(str(x) for x in self._version.pre)) + if self.pre is not None: + parts.append("".join(str(x) for x in self.pre)) # Post-release - if self._version.post is not None: - parts.append(".post{0}".format(self._version.post[1])) + if self.post is not None: + parts.append(".post{0}".format(self.post)) # Development release - if self._version.dev is not None: - parts.append(".dev{0}".format(self._version.dev[1])) + if self.dev is not None: + parts.append(".dev{0}".format(self.dev)) # Local version segment - if self._version.local is not None: - parts.append( - "+{0}".format(".".join(str(x) for x in self._version.local)) - ) + if self.local is not None: + parts.append("+{0}".format(self.local)) return "".join(parts) + @property + def epoch(self): + return self._version.epoch + + @property + def release(self): + return self._version.release + + @property + def pre(self): + return self._version.pre + + @property + def post(self): + return self._version.post[1] if self._version.post else None + + @property + def dev(self): + return self._version.dev[1] if self._version.dev else None + + @property + def local(self): + if self._version.local: + return ".".join(str(x) for x in self._version.local) + else: + return None + @property def public(self): return str(self).split("+", 1)[0] @@ -272,27 +309,25 @@ class Version(_BaseVersion): parts = [] # Epoch - if self._version.epoch != 0: - parts.append("{0}!".format(self._version.epoch)) + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) # Release segment - parts.append(".".join(str(x) for x in self._version.release)) + parts.append(".".join(str(x) for x in self.release)) return "".join(parts) - @property - def local(self): - version_string = str(self) - if "+" in version_string: - return version_string.split("+", 1)[1] - @property def is_prerelease(self): - return bool(self._version.dev or self._version.pre) + return self.dev is not None or self.pre is not None @property def is_postrelease(self): - return bool(self._version.post) + return self.post is not None + + @property + def is_devrelease(self): + return self.dev is not None def _parse_letter_version(letter, number): @@ -326,7 +361,7 @@ def _parse_letter_version(letter, number): return letter, int(number) -_local_version_seperators = re.compile(r"[\._-]") +_local_version_separators = re.compile(r"[\._-]") def _parse_local_version(local): @@ -336,7 +371,7 @@ def _parse_local_version(local): if local is not None: return tuple( part.lower() if not part.isdigit() else int(part) - for part in _local_version_seperators.split(local) + for part in _local_version_separators.split(local) ) @@ -347,12 +382,7 @@ def _cmpkey(epoch, release, pre, post, dev, local): # re-reverse it back into the correct order and make it a tuple and use # that for our sorting key. release = tuple( - reversed(list( - itertools.dropwhile( - lambda x: x == 0, - reversed(release), - ) - )) + reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release)))) ) # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0. @@ -385,9 +415,6 @@ def _cmpkey(epoch, release, pre, post, dev, local): # - Numeric segments sort numerically # - Shorter versions sort before longer versions when the prefixes # match exactly - local = tuple( - (i, "") if isinstance(i, int) else (-Infinity, i) - for i in local - ) + local = tuple((i, "") if isinstance(i, int) else (-Infinity, i) for i in local) return epoch, release, pre, post, dev, local diff --git a/venv/lib/python3.8/site-packages/pkg_resources/extern/__init__.py b/venv/lib/python3.8/site-packages/pkg_resources/extern/__init__.py index c1eb9e9..bf98d8f 100644 --- a/venv/lib/python3.8/site-packages/pkg_resources/extern/__init__.py +++ b/venv/lib/python3.8/site-packages/pkg_resources/extern/__init__.py @@ -43,13 +43,6 @@ class VendorImporter: __import__(extant) mod = sys.modules[extant] sys.modules[fullname] = mod - # mysterious hack: - # Remove the reference to the extant package/module - # on later Python versions to cause relative imports - # in the vendor package to resolve the same modules - # as those going through this importer. - if prefix and sys.version_info > (3, 3): - del sys.modules[extant] return mod except ImportError: pass diff --git a/venv/lib/python3.8/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-38.pyc index 2df720bd915455d297e37c8825e4098a530a9409..9cef2ea00006ba9d8785133b81faf9b9665da6d4 100644 GIT binary patch delta 270 zcmaDQbVZ0Sl$V!_0SGw%?TR<$*vR*f(J5I!BR@A)zo@dbG%HiTxF}gaB{45EH77a0 zs3f&mucER_zbrMcOg|?xNxz`7BqKl1SkFSgII|>Gw;(Y&J25?VvjNjJCdQh{?5ql` z9<{7hdXsfnRn6JM8JHLt8G;#D7)sc(xr&k)fjmZrNQOe02p}$DOJT}lPh%+IXlCeR zY-Vg?OkoaY&}5lBk2PrWAJ&<SoRg=qX-z)ImMbg=axse-BNrnRBL@(2F>*}~V&BUs zGg*Mcn9*{w3r7W;GEhm8+T=qVMvP*UzjEk_%YX!!fW$4<yu{qp;v#j33M)=sW?L3U E0K|4gmH+?% delta 290 zcmca2^h$^?l$V!_0SKO#ZHPO>xsmT5ql&A3Np69DL1uw&W?pegVor{(QHDurg>inO zesO9^X+cSTe$Hk;rfW=$lP0UODzL`YvR1iF_F`4_Wi5&+VaZ}kVajF!vsi1`Y#D0U z!x@+u7#V^YSQtv!v$={Y7=b)ShDe4&nFt^*VNYSs;z(mC;cRB;V{B$@VoYHPX3%7v zyo@!7Q<Lc>GthNK(v!ck&SB)5Jc&(<m!~YXs5mn}FFrFbEr0TEwmfkqkPleI7`Ygk z7&(BDi;;_skC9`t4f|e3*~!1yjTs##>v2@Dse+8sn7oF=2q=7?Lr+{5B)|kDZn5Si T=B5@GX+l(}aOyI<urLAuzG6qF diff --git a/venv/lib/python3.8/site-packages/pkg_resources/py31compat.py b/venv/lib/python3.8/site-packages/pkg_resources/py31compat.py deleted file mode 100644 index a381c42..0000000 --- a/venv/lib/python3.8/site-packages/pkg_resources/py31compat.py +++ /dev/null @@ -1,23 +0,0 @@ -import os -import errno -import sys - -from .extern import six - - -def _makedirs_31(path, exist_ok=False): - try: - os.makedirs(path) - except OSError as exc: - if not exist_ok or exc.errno != errno.EEXIST: - raise - - -# rely on compatibility behavior until mode considerations -# and exists_ok considerations are disentangled. -# See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663 -needs_makedirs = ( - six.PY2 or - (3, 4) <= sys.version_info < (3, 4, 1) -) -makedirs = _makedirs_31 if needs_makedirs else os.makedirs diff --git a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/INSTALLER b/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e..0000000 --- a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/LICENSE b/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/LICENSE deleted file mode 100644 index 6e0693b..0000000 --- a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (C) 2016 Jason R Coombs <jaraco@jaraco.com> - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/METADATA b/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/METADATA deleted file mode 100644 index 96f2587..0000000 --- a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/METADATA +++ /dev/null @@ -1,77 +0,0 @@ -Metadata-Version: 2.1 -Name: setuptools -Version: 41.2.0 -Summary: Easily download, build, install, upgrade, and uninstall Python packages -Home-page: https://github.com/pypa/setuptools -Author: Python Packaging Authority -Author-email: distutils-sig@python.org -License: UNKNOWN -Project-URL: Documentation, https://setuptools.readthedocs.io/ -Keywords: CPAN PyPI distutils eggs package management -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.4 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Topic :: Software Development :: Libraries :: Python Modules -Classifier: Topic :: System :: Archiving :: Packaging -Classifier: Topic :: System :: Systems Administration -Classifier: Topic :: Utilities -Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.* -Description-Content-Type: text/x-rst; charset=UTF-8 -Provides-Extra: certs -Requires-Dist: certifi (==2016.9.26) ; extra == 'certs' -Provides-Extra: ssl -Requires-Dist: wincertstore (==0.2) ; (sys_platform == "win32") and extra == 'ssl' - -.. image:: https://img.shields.io/pypi/v/setuptools.svg - :target: https://pypi.org/project/setuptools - -.. image:: https://img.shields.io/readthedocs/setuptools/latest.svg - :target: https://setuptools.readthedocs.io - -.. image:: https://img.shields.io/travis/pypa/setuptools/master.svg?label=Linux%20CI&logo=travis&logoColor=white - :target: https://travis-ci.org/pypa/setuptools - -.. image:: https://img.shields.io/appveyor/ci/pypa/setuptools/master.svg?label=Windows%20CI&logo=appveyor&logoColor=white - :target: https://ci.appveyor.com/project/pypa/setuptools/branch/master - -.. image:: https://img.shields.io/codecov/c/github/pypa/setuptools/master.svg?logo=codecov&logoColor=white - :target: https://codecov.io/gh/pypa/setuptools - -.. image:: https://tidelift.com/badges/github/pypa/setuptools?style=flat - :target: https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=readme - -.. image:: https://img.shields.io/pypi/pyversions/setuptools.svg - -See the `Installation Instructions -<https://packaging.python.org/installing/>`_ in the Python Packaging -User's Guide for instructions on installing, upgrading, and uninstalling -Setuptools. - -Questions and comments should be directed to the `distutils-sig -mailing list <http://mail.python.org/pipermail/distutils-sig/>`_. -Bug reports and especially tested patches may be -submitted directly to the `bug tracker -<https://github.com/pypa/setuptools/issues>`_. - -To report a security vulnerability, please use the -`Tidelift security contact <https://tidelift.com/security>`_. -Tidelift will coordinate the fix and disclosure. - - -Code of Conduct ---------------- - -Everyone interacting in the setuptools project's codebases, issue trackers, -chat rooms, and mailing lists is expected to follow the -`PyPA Code of Conduct <https://www.pypa.io/en/latest/code-of-conduct/>`_. - - diff --git a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/RECORD b/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/RECORD deleted file mode 100644 index d999f14..0000000 --- a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/RECORD +++ /dev/null @@ -1,186 +0,0 @@ -../../../bin/easy_install,sha256=7L8MxSdJ8B5NVwhC8PdWc-NeaUmZjD7v3N2LndiAiik,259 -../../../bin/easy_install-3.8,sha256=7L8MxSdJ8B5NVwhC8PdWc-NeaUmZjD7v3N2LndiAiik,259 -__pycache__/easy_install.cpython-38.pyc,, -easy_install.py,sha256=MDC9vt5AxDsXX5qcKlBz2TnW6Tpuv_AobnfhCJ9X3PM,126 -pkg_resources/__init__.py,sha256=6Kq6B-JSGEFSg_2FAnl6Lmoa5by2RyjDxPBiWuAh-dw,108309 -pkg_resources/__pycache__/__init__.cpython-38.pyc,, -pkg_resources/__pycache__/py31compat.cpython-38.pyc,, -pkg_resources/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -pkg_resources/_vendor/__pycache__/__init__.cpython-38.pyc,, -pkg_resources/_vendor/__pycache__/appdirs.cpython-38.pyc,, -pkg_resources/_vendor/__pycache__/pyparsing.cpython-38.pyc,, -pkg_resources/_vendor/__pycache__/six.cpython-38.pyc,, -pkg_resources/_vendor/appdirs.py,sha256=MievUEuv3l_mQISH5SF0shDk_BNhHHzYiAPrT3ITN4I,24701 -pkg_resources/_vendor/packaging/__about__.py,sha256=zkcCPTN_6TcLW0Nrlg0176-R1QQ_WVPTm8sz1R4-HjM,720 -pkg_resources/_vendor/packaging/__init__.py,sha256=_vNac5TrzwsrzbOFIbF-5cHqc_Y2aPT2D7zrIR06BOo,513 -pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/markers.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/utils.cpython-38.pyc,, -pkg_resources/_vendor/packaging/__pycache__/version.cpython-38.pyc,, -pkg_resources/_vendor/packaging/_compat.py,sha256=Vi_A0rAQeHbU-a9X0tt1yQm9RqkgQbDSxzRw8WlU9kA,860 -pkg_resources/_vendor/packaging/_structures.py,sha256=RImECJ4c_wTlaTYYwZYLHEiebDMaAJmK1oPARhw1T5o,1416 -pkg_resources/_vendor/packaging/markers.py,sha256=uEcBBtGvzqltgnArqb9c4RrcInXezDLos14zbBHhWJo,8248 -pkg_resources/_vendor/packaging/requirements.py,sha256=SikL2UynbsT0qtY9ltqngndha_sfo0w6XGFhAhoSoaQ,4355 -pkg_resources/_vendor/packaging/specifiers.py,sha256=SAMRerzO3fK2IkFZCaZkuwZaL_EGqHNOz4pni4vhnN0,28025 -pkg_resources/_vendor/packaging/utils.py,sha256=3m6WvPm6NNxE8rkTGmn0r75B_GZSGg7ikafxHsBN1WA,421 -pkg_resources/_vendor/packaging/version.py,sha256=OwGnxYfr2ghNzYx59qWIBkrK3SnB6n-Zfd1XaLpnnM0,11556 -pkg_resources/_vendor/pyparsing.py,sha256=tmrp-lu-qO1i75ZzIN5A12nKRRD1Cm4Vpk-5LR9rims,232055 -pkg_resources/_vendor/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098 -pkg_resources/extern/__init__.py,sha256=cHiEfHuLmm6rs5Ve_ztBfMI7Lr31vss-D4wkqF5xzlI,2498 -pkg_resources/extern/__pycache__/__init__.cpython-38.pyc,, -pkg_resources/py31compat.py,sha256=-WQ0e4c3RG_acdhwC3gLiXhP_lg4G5q7XYkZkQg0gxU,558 -setuptools-41.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -setuptools-41.2.0.dist-info/LICENSE,sha256=wyo6w5WvYyHv0ovnPQagDw22q4h9HCHU_sRhKNIFbVo,1078 -setuptools-41.2.0.dist-info/METADATA,sha256=_t0DvK_bLLT2yjvvNOCXiSIoNJvjX6dTWT8fLNVrUQk,3305 -setuptools-41.2.0.dist-info/RECORD,, -setuptools-41.2.0.dist-info/WHEEL,sha256=8zNYZbwQSXoB9IfXOjPfeNwvAsALAjffgk27FqvCWbo,110 -setuptools-41.2.0.dist-info/dependency_links.txt,sha256=HlkCFkoK5TbZ5EMLbLKYhLcY_E31kBWD8TqW2EgmatQ,239 -setuptools-41.2.0.dist-info/entry_points.txt,sha256=jBqCYDlVjl__sjYFGXo1JQGIMAYFJE-prYWUtnMZEew,2990 -setuptools-41.2.0.dist-info/top_level.txt,sha256=2HUXVVwA4Pff1xgTFr3GsTXXKaPaO6vlG6oNJ_4u4Tg,38 -setuptools-41.2.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 -setuptools/__init__.py,sha256=WBpCcn2lvdckotabeae1TTYonPOcgCIF3raD2zRWzBc,7283 -setuptools/__pycache__/__init__.cpython-38.pyc,, -setuptools/__pycache__/_deprecation_warning.cpython-38.pyc,, -setuptools/__pycache__/archive_util.cpython-38.pyc,, -setuptools/__pycache__/build_meta.cpython-38.pyc,, -setuptools/__pycache__/config.cpython-38.pyc,, -setuptools/__pycache__/dep_util.cpython-38.pyc,, -setuptools/__pycache__/depends.cpython-38.pyc,, -setuptools/__pycache__/dist.cpython-38.pyc,, -setuptools/__pycache__/extension.cpython-38.pyc,, -setuptools/__pycache__/glibc.cpython-38.pyc,, -setuptools/__pycache__/glob.cpython-38.pyc,, -setuptools/__pycache__/launch.cpython-38.pyc,, -setuptools/__pycache__/lib2to3_ex.cpython-38.pyc,, -setuptools/__pycache__/monkey.cpython-38.pyc,, -setuptools/__pycache__/msvc.cpython-38.pyc,, -setuptools/__pycache__/namespaces.cpython-38.pyc,, -setuptools/__pycache__/package_index.cpython-38.pyc,, -setuptools/__pycache__/pep425tags.cpython-38.pyc,, -setuptools/__pycache__/py27compat.cpython-38.pyc,, -setuptools/__pycache__/py31compat.cpython-38.pyc,, -setuptools/__pycache__/py33compat.cpython-38.pyc,, -setuptools/__pycache__/sandbox.cpython-38.pyc,, -setuptools/__pycache__/site-patch.cpython-38.pyc,, -setuptools/__pycache__/ssl_support.cpython-38.pyc,, -setuptools/__pycache__/unicode_utils.cpython-38.pyc,, -setuptools/__pycache__/version.cpython-38.pyc,, -setuptools/__pycache__/wheel.cpython-38.pyc,, -setuptools/__pycache__/windows_support.cpython-38.pyc,, -setuptools/_deprecation_warning.py,sha256=jU9-dtfv6cKmtQJOXN8nP1mm7gONw5kKEtiPtbwnZyI,218 -setuptools/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -setuptools/_vendor/__pycache__/__init__.cpython-38.pyc,, -setuptools/_vendor/__pycache__/pyparsing.cpython-38.pyc,, -setuptools/_vendor/__pycache__/six.cpython-38.pyc,, -setuptools/_vendor/packaging/__about__.py,sha256=zkcCPTN_6TcLW0Nrlg0176-R1QQ_WVPTm8sz1R4-HjM,720 -setuptools/_vendor/packaging/__init__.py,sha256=_vNac5TrzwsrzbOFIbF-5cHqc_Y2aPT2D7zrIR06BOo,513 -setuptools/_vendor/packaging/__pycache__/__about__.cpython-38.pyc,, -setuptools/_vendor/packaging/__pycache__/__init__.cpython-38.pyc,, -setuptools/_vendor/packaging/__pycache__/_compat.cpython-38.pyc,, -setuptools/_vendor/packaging/__pycache__/_structures.cpython-38.pyc,, -setuptools/_vendor/packaging/__pycache__/markers.cpython-38.pyc,, -setuptools/_vendor/packaging/__pycache__/requirements.cpython-38.pyc,, -setuptools/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc,, -setuptools/_vendor/packaging/__pycache__/utils.cpython-38.pyc,, -setuptools/_vendor/packaging/__pycache__/version.cpython-38.pyc,, -setuptools/_vendor/packaging/_compat.py,sha256=Vi_A0rAQeHbU-a9X0tt1yQm9RqkgQbDSxzRw8WlU9kA,860 -setuptools/_vendor/packaging/_structures.py,sha256=RImECJ4c_wTlaTYYwZYLHEiebDMaAJmK1oPARhw1T5o,1416 -setuptools/_vendor/packaging/markers.py,sha256=Gvpk9EY20yKaMTiKgQZ8yFEEpodqVgVYtfekoic1Yts,8239 -setuptools/_vendor/packaging/requirements.py,sha256=t44M2HVWtr8phIz2OhnILzuGT3rTATaovctV1dpnVIg,4343 -setuptools/_vendor/packaging/specifiers.py,sha256=SAMRerzO3fK2IkFZCaZkuwZaL_EGqHNOz4pni4vhnN0,28025 -setuptools/_vendor/packaging/utils.py,sha256=3m6WvPm6NNxE8rkTGmn0r75B_GZSGg7ikafxHsBN1WA,421 -setuptools/_vendor/packaging/version.py,sha256=OwGnxYfr2ghNzYx59qWIBkrK3SnB6n-Zfd1XaLpnnM0,11556 -setuptools/_vendor/pyparsing.py,sha256=tmrp-lu-qO1i75ZzIN5A12nKRRD1Cm4Vpk-5LR9rims,232055 -setuptools/_vendor/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098 -setuptools/archive_util.py,sha256=kw8Ib_lKjCcnPKNbS7h8HztRVK0d5RacU3r_KRdVnmM,6592 -setuptools/build_meta.py,sha256=-9Nmj9YdbW4zX3TssPJZhsENrTa4fw3k86Jm1cdKMik,9597 -setuptools/cli-32.exe,sha256=dfEuovMNnA2HLa3jRfMPVi5tk4R7alCbpTvuxtCyw0Y,65536 -setuptools/cli-64.exe,sha256=KLABu5pyrnokJCv6skjXZ6GsXeyYHGcqOUT3oHI3Xpo,74752 -setuptools/cli.exe,sha256=dfEuovMNnA2HLa3jRfMPVi5tk4R7alCbpTvuxtCyw0Y,65536 -setuptools/command/__init__.py,sha256=NWzJ0A1BEengZpVeqUyWLNm2bk4P3F4iL5QUErHy7kA,594 -setuptools/command/__pycache__/__init__.cpython-38.pyc,, -setuptools/command/__pycache__/alias.cpython-38.pyc,, -setuptools/command/__pycache__/bdist_egg.cpython-38.pyc,, -setuptools/command/__pycache__/bdist_rpm.cpython-38.pyc,, -setuptools/command/__pycache__/bdist_wininst.cpython-38.pyc,, -setuptools/command/__pycache__/build_clib.cpython-38.pyc,, -setuptools/command/__pycache__/build_ext.cpython-38.pyc,, -setuptools/command/__pycache__/build_py.cpython-38.pyc,, -setuptools/command/__pycache__/develop.cpython-38.pyc,, -setuptools/command/__pycache__/dist_info.cpython-38.pyc,, -setuptools/command/__pycache__/easy_install.cpython-38.pyc,, -setuptools/command/__pycache__/egg_info.cpython-38.pyc,, -setuptools/command/__pycache__/install.cpython-38.pyc,, -setuptools/command/__pycache__/install_egg_info.cpython-38.pyc,, -setuptools/command/__pycache__/install_lib.cpython-38.pyc,, -setuptools/command/__pycache__/install_scripts.cpython-38.pyc,, -setuptools/command/__pycache__/py36compat.cpython-38.pyc,, -setuptools/command/__pycache__/register.cpython-38.pyc,, -setuptools/command/__pycache__/rotate.cpython-38.pyc,, -setuptools/command/__pycache__/saveopts.cpython-38.pyc,, -setuptools/command/__pycache__/sdist.cpython-38.pyc,, -setuptools/command/__pycache__/setopt.cpython-38.pyc,, -setuptools/command/__pycache__/test.cpython-38.pyc,, -setuptools/command/__pycache__/upload.cpython-38.pyc,, -setuptools/command/__pycache__/upload_docs.cpython-38.pyc,, -setuptools/command/alias.py,sha256=KjpE0sz_SDIHv3fpZcIQK-sCkJz-SrC6Gmug6b9Nkc8,2426 -setuptools/command/bdist_egg.py,sha256=be-IBpr1zhS9i6GjKANJgzkbH3ChImdWY7S-j0r2BK8,18167 -setuptools/command/bdist_rpm.py,sha256=B7l0TnzCGb-0nLlm6rS00jWLkojASwVmdhW2w5Qz_Ak,1508 -setuptools/command/bdist_wininst.py,sha256=_6dz3lpB1tY200LxKPLM7qgwTCceOMgaWFF-jW2-pm0,637 -setuptools/command/build_clib.py,sha256=bQ9aBr-5ZSO-9fGsGsDLz0mnnFteHUZnftVLkhvHDq0,4484 -setuptools/command/build_ext.py,sha256=Ib42YUGksBswm2mL5xmQPF6NeTA6HcqrvAtEgFCv32A,13019 -setuptools/command/build_py.py,sha256=yWyYaaS9F3o9JbIczn064A5g1C5_UiKRDxGaTqYbtLE,9596 -setuptools/command/develop.py,sha256=MQlnGS6uP19erK2JCNOyQYoYyquk3PADrqrrinqqLtA,8184 -setuptools/command/dist_info.py,sha256=5t6kOfrdgALT-P3ogss6PF9k-Leyesueycuk3dUyZnI,960 -setuptools/command/easy_install.py,sha256=telww7CuPsoTtvlpY-ktnZGT85cZ6xGCGZa0vHvFJ-Q,87273 -setuptools/command/egg_info.py,sha256=w73EdxYSOk2gsaAiHGL2dZrCldoPiuRr2eTfqcFvCds,25570 -setuptools/command/install.py,sha256=a0EZpL_A866KEdhicTGbuyD_TYl1sykfzdrri-zazT4,4683 -setuptools/command/install_egg_info.py,sha256=bMgeIeRiXzQ4DAGPV1328kcjwQjHjOWU4FngAWLV78Q,2203 -setuptools/command/install_lib.py,sha256=r5NuasaSxvmIrjgZNj38Iq-1UJG1o1ms7CuHq6MCTbQ,3862 -setuptools/command/install_scripts.py,sha256=UD0rEZ6861mTYhIdzcsqKnUl8PozocXWl9VBQ1VTWnc,2439 -setuptools/command/launcher manifest.xml,sha256=xlLbjWrB01tKC0-hlVkOKkiSPbzMml2eOPtJ_ucCnbE,628 -setuptools/command/py36compat.py,sha256=SzjZcOxF7zdFUT47Zv2n7AM3H8koDys_0OpS-n9gIfc,4986 -setuptools/command/register.py,sha256=LO3MvYKPE8dN1m-KkrBRHC68ZFoPvA_vI8Xgp7vv6zI,534 -setuptools/command/rotate.py,sha256=co5C1EkI7P0GGT6Tqz-T2SIj2LBJTZXYELpmao6d4KQ,2164 -setuptools/command/saveopts.py,sha256=za7QCBcQimKKriWcoCcbhxPjUz30gSB74zuTL47xpP4,658 -setuptools/command/sdist.py,sha256=gr5hFrDzUtGfp_0tu0sllzIyr3jMQegIkFmlDauQJxw,7388 -setuptools/command/setopt.py,sha256=NTWDyx-gjDF-txf4dO577s7LOzHVoKR0Mq33rFxaRr8,5085 -setuptools/command/test.py,sha256=oePJ49u17ENKtrM-rOrrLlRhtNnrzcSr0IW-gE9XVq0,9285 -setuptools/command/upload.py,sha256=GxtNkIl7SA0r8mACkbDcSCN1m2_WPppK9gZXJmQSiow,6811 -setuptools/command/upload_docs.py,sha256=oXiGplM_cUKLwE4CWWw98RzCufAu8tBhMC97GegFcms,7311 -setuptools/config.py,sha256=lz19l1AtoHctpp1_tbYZv176nrEj4Gpf7ykNIYTIkAQ,20425 -setuptools/dep_util.py,sha256=fgixvC1R7sH3r13ktyf7N0FALoqEXL1cBarmNpSEoWg,935 -setuptools/depends.py,sha256=hC8QIDcM3VDpRXvRVA6OfL9AaQfxvhxHcN_w6sAyNq8,5837 -setuptools/dist.py,sha256=MRrBrgBFEwzUvrJrIgW79IepDuAeRxetGuSPky-MawQ,50248 -setuptools/extension.py,sha256=uc6nHI-MxwmNCNPbUiBnybSyqhpJqjbhvOQ-emdvt_E,1729 -setuptools/extern/__init__.py,sha256=TxeNKFMSfBMzBpBDiHx8Dh3RzsdVmvWaXhtZ03DZMs0,2499 -setuptools/extern/__pycache__/__init__.cpython-38.pyc,, -setuptools/glibc.py,sha256=X64VvGPL2AbURKwYRsWJOXXGAYOiF_v2qixeTkAULuU,3146 -setuptools/glob.py,sha256=o75cHrOxYsvn854thSxE0x9k8JrKDuhP_rRXlVB00Q4,5084 -setuptools/gui-32.exe,sha256=XBr0bHMA6Hpz2s9s9Bzjl-PwXfa9nH4ie0rFn4V2kWA,65536 -setuptools/gui-64.exe,sha256=aYKMhX1IJLn4ULHgWX0sE0yREUt6B3TEHf_jOw6yNyE,75264 -setuptools/gui.exe,sha256=XBr0bHMA6Hpz2s9s9Bzjl-PwXfa9nH4ie0rFn4V2kWA,65536 -setuptools/launch.py,sha256=sd7ejwhBocCDx_wG9rIs0OaZ8HtmmFU8ZC6IR_S0Lvg,787 -setuptools/lib2to3_ex.py,sha256=t5e12hbR2pi9V4ezWDTB4JM-AISUnGOkmcnYHek3xjg,2013 -setuptools/monkey.py,sha256=FGc9fffh7gAxMLFmJs2DW_OYWpBjkdbNS2n14UAK4NA,5264 -setuptools/msvc.py,sha256=uuRFaZzjJt5Fv3ZmyKUUuLtjx12_8G9RILigGec4irI,40838 -setuptools/namespaces.py,sha256=F0Nrbv8KCT2OrO7rwa03om4N4GZKAlnce-rr-cgDQa8,3199 -setuptools/package_index.py,sha256=F9LBC-hQ5fkjeEVflxif0mo_DzRMrepahdFTPenOtGM,40587 -setuptools/pep425tags.py,sha256=o_D_WVeWcXZiI2xjPSg7pouGOvaWRgGRxEDK9DzAXIA,10861 -setuptools/py27compat.py,sha256=3mwxRMDk5Q5O1rSXOERbQDXhFqwDJhhUitfMW_qpUCo,536 -setuptools/py31compat.py,sha256=h2rtZghOfwoGYd8sQ0-auaKiF3TcL3qX0bX3VessqcE,838 -setuptools/py33compat.py,sha256=SMF9Z8wnGicTOkU1uRNwZ_kz5Z_bj29PUBbqdqeeNsc,1330 -setuptools/sandbox.py,sha256=9UbwfEL5QY436oMI1LtFWohhoZ-UzwHvGyZjUH_qhkw,14276 -setuptools/script (dev).tmpl,sha256=RUzQzCQUaXtwdLtYHWYbIQmOaES5Brqq1FvUA_tu-5I,218 -setuptools/script.tmpl,sha256=WGTt5piezO27c-Dbx6l5Q4T3Ff20A5z7872hv3aAhYY,138 -setuptools/site-patch.py,sha256=OumkIHMuoSenRSW1382kKWI1VAwxNE86E5W8iDd34FY,2302 -setuptools/ssl_support.py,sha256=nLjPUBBw7RTTx6O4RJZ5eAMGgjJG8beiDbkFXDZpLuM,8493 -setuptools/unicode_utils.py,sha256=NOiZ_5hD72A6w-4wVj8awHFM3n51Kmw1Ic_vx15XFqw,996 -setuptools/version.py,sha256=og_cuZQb0QI6ukKZFfZWPlr1HgJBPPn2vO2m_bI9ZTE,144 -setuptools/wheel.py,sha256=94uqXsOaKt91d9hW5z6ZppZmNSs_nO66R4uiwhcr4V0,8094 -setuptools/windows_support.py,sha256=5GrfqSP2-dLGJoZTq2g6dCKkyQxxa2n5IQiXlJCoYEE,714 diff --git a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/WHEEL b/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/WHEEL deleted file mode 100644 index 8b701e9..0000000 --- a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/WHEEL +++ /dev/null @@ -1,6 +0,0 @@ -Wheel-Version: 1.0 -Generator: bdist_wheel (0.33.6) -Root-Is-Purelib: true -Tag: py2-none-any -Tag: py3-none-any - diff --git a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/dependency_links.txt b/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/dependency_links.txt deleted file mode 100644 index e87d021..0000000 --- a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/dependency_links.txt +++ /dev/null @@ -1,2 +0,0 @@ -https://files.pythonhosted.org/packages/source/c/certifi/certifi-2016.9.26.tar.gz#md5=baa81e951a29958563689d868ef1064d -https://files.pythonhosted.org/packages/source/w/wincertstore/wincertstore-0.2.zip#md5=ae728f2f007185648d0c7a8679b361e2 diff --git a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/entry_points.txt b/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/entry_points.txt deleted file mode 100644 index 4159fd0..0000000 --- a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/entry_points.txt +++ /dev/null @@ -1,65 +0,0 @@ -[console_scripts] -easy_install = setuptools.command.easy_install:main -easy_install-3.6 = setuptools.command.easy_install:main - -[distutils.commands] -alias = setuptools.command.alias:alias -bdist_egg = setuptools.command.bdist_egg:bdist_egg -bdist_rpm = setuptools.command.bdist_rpm:bdist_rpm -bdist_wininst = setuptools.command.bdist_wininst:bdist_wininst -build_clib = setuptools.command.build_clib:build_clib -build_ext = setuptools.command.build_ext:build_ext -build_py = setuptools.command.build_py:build_py -develop = setuptools.command.develop:develop -dist_info = setuptools.command.dist_info:dist_info -easy_install = setuptools.command.easy_install:easy_install -egg_info = setuptools.command.egg_info:egg_info -install = setuptools.command.install:install -install_egg_info = setuptools.command.install_egg_info:install_egg_info -install_lib = setuptools.command.install_lib:install_lib -install_scripts = setuptools.command.install_scripts:install_scripts -register = setuptools.command.register:register -rotate = setuptools.command.rotate:rotate -saveopts = setuptools.command.saveopts:saveopts -sdist = setuptools.command.sdist:sdist -setopt = setuptools.command.setopt:setopt -test = setuptools.command.test:test -upload = setuptools.command.upload:upload -upload_docs = setuptools.command.upload_docs:upload_docs - -[distutils.setup_keywords] -convert_2to3_doctests = setuptools.dist:assert_string_list -dependency_links = setuptools.dist:assert_string_list -eager_resources = setuptools.dist:assert_string_list -entry_points = setuptools.dist:check_entry_points -exclude_package_data = setuptools.dist:check_package_data -extras_require = setuptools.dist:check_extras -include_package_data = setuptools.dist:assert_bool -install_requires = setuptools.dist:check_requirements -namespace_packages = setuptools.dist:check_nsp -package_data = setuptools.dist:check_package_data -packages = setuptools.dist:check_packages -python_requires = setuptools.dist:check_specifier -setup_requires = setuptools.dist:check_requirements -test_loader = setuptools.dist:check_importable -test_runner = setuptools.dist:check_importable -test_suite = setuptools.dist:check_test_suite -tests_require = setuptools.dist:check_requirements -use_2to3 = setuptools.dist:assert_bool -use_2to3_exclude_fixers = setuptools.dist:assert_string_list -use_2to3_fixers = setuptools.dist:assert_string_list -zip_safe = setuptools.dist:assert_bool - -[egg_info.writers] -PKG-INFO = setuptools.command.egg_info:write_pkg_info -dependency_links.txt = setuptools.command.egg_info:overwrite_arg -depends.txt = setuptools.command.egg_info:warn_depends_obsolete -eager_resources.txt = setuptools.command.egg_info:overwrite_arg -entry_points.txt = setuptools.command.egg_info:write_entries -namespace_packages.txt = setuptools.command.egg_info:overwrite_arg -requires.txt = setuptools.command.egg_info:write_requirements -top_level.txt = setuptools.command.egg_info:write_toplevel_names - -[setuptools.installation] -eggsecutable = setuptools.command.easy_install:bootstrap - diff --git a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/top_level.txt b/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/top_level.txt deleted file mode 100644 index 4577c6a..0000000 --- a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/top_level.txt +++ /dev/null @@ -1,3 +0,0 @@ -easy_install -pkg_resources -setuptools diff --git a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/zip-safe b/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/zip-safe deleted file mode 100644 index 8b13789..0000000 --- a/venv/lib/python3.8/site-packages/setuptools-41.2.0.dist-info/zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/venv/lib/python3.8/site-packages/setuptools/__init__.py b/venv/lib/python3.8/site-packages/setuptools/__init__.py index a71b2bb..8388251 100644 --- a/venv/lib/python3.8/site-packages/setuptools/__init__.py +++ b/venv/lib/python3.8/site-packages/setuptools/__init__.py @@ -1,8 +1,11 @@ """Extensions to the 'distutils' for large or complex distributions""" import os -import sys import functools + +# Disabled for now due to: #2228, #2230 +import setuptools.distutils_patch # noqa: F401 + import distutils.core import distutils.filelist import re @@ -17,7 +20,7 @@ from setuptools.extern.six.moves import filter, map import setuptools.version from setuptools.extension import Extension -from setuptools.dist import Distribution, Feature +from setuptools.dist import Distribution from setuptools.depends import Require from . import monkey @@ -25,13 +28,13 @@ __metaclass__ = type __all__ = [ - 'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require', + 'setup', 'Distribution', 'Command', 'Extension', 'Require', 'SetuptoolsDeprecationWarning', 'find_packages' ] if PY3: - __all__.append('find_namespace_packages') + __all__.append('find_namespace_packages') __version__ = setuptools.version.__version__ @@ -123,16 +126,33 @@ class PEP420PackageFinder(PackageFinder): find_packages = PackageFinder.find if PY3: - find_namespace_packages = PEP420PackageFinder.find + find_namespace_packages = PEP420PackageFinder.find def _install_setup_requires(attrs): # Note: do not use `setuptools.Distribution` directly, as # our PEP 517 backend patch `distutils.core.Distribution`. - dist = distutils.core.Distribution(dict( - (k, v) for k, v in attrs.items() - if k in ('dependency_links', 'setup_requires') - )) + class MinimalDistribution(distutils.core.Distribution): + """ + A minimal version of a distribution for supporting the + fetch_build_eggs interface. + """ + def __init__(self, attrs): + _incl = 'dependency_links', 'setup_requires' + filtered = { + k: attrs[k] + for k in set(_incl) & set(attrs) + } + distutils.core.Distribution.__init__(self, filtered) + + def finalize_options(self): + """ + Disable finalize_options to avoid building the working set. + Ref #2158. + """ + + dist = MinimalDistribution(attrs) + # Honor setup.cfg's options. dist.parse_config_files(ignore_option_errors=True) if dist.setup_requires: @@ -144,6 +164,7 @@ def setup(**attrs): _install_setup_requires(attrs) return distutils.core.setup(**attrs) + setup.__doc__ = distutils.core.setup.__doc__ @@ -191,8 +212,8 @@ class Command(_Command): ok = False if not ok: raise DistutilsOptionError( - "'%s' must be a list of strings (got %r)" - % (option, val)) + "'%s' must be a list of strings (got %r)" + % (option, val)) def reinitialize_command(self, command, reinit_subcommands=0, **kw): cmd = _Command.reinitialize_command(self, command, reinit_subcommands) @@ -224,5 +245,9 @@ def findall(dir=os.curdir): return list(files) +class sic(str): + """Treat this string as-is (https://en.wikipedia.org/wiki/Sic)""" + + # Apply monkey patches monkey.patch_all() diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/__init__.cpython-38.pyc index e85cfd3f62e4fd6a681b848928ab3013be7b4c5d..1b21c90b07d0b4d2468e68c800546a4e2cd12489 100644 GIT binary patch delta 3459 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 D2Yn%$ delta 2565 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 diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-38.pyc index 68f1138df3ff50acb6d44b41e4e0f76734fdb6b2..f8f22d835b5a3a41125e31c259633e8e448bdf3e 100644 GIT binary patch delta 92 zcmeBRS;oQ>%FD~e00f->cExYxNoRCQ)z8S!P1P@|EG^B-)Gsbd)=x>y%S_El&MzuS uE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPn|rSu@C@T79Yw0 delta 62 zcmZ3+(!s(L%FD~e00hs=HpFe@NoQ1X*DuK}&@ad=(9O&%E=kPE(KX62DXlQhPt-3? QEh#N1$<NQ3yp^#K06p{+mH+?% diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/archive_util.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/archive_util.cpython-38.pyc index dd06cdb0912d1bc4c8529eb1b4769a95582de974..07ebec9aac97b738b22772c0a00c74b2c438bc84 100644 GIT binary patch delta 628 zcmXw0&1(};5TBX-%u6;lAN`_U1chGgVy)sqL8@3m5LBe8Qj#>gwb|69-QAWpytQH# zJcupqRb&^>9weRw{{a7k(zAFJ&mLN5OMQ=-_xsJ8H}huZ-Q<r+>#=1C;FUZ2R{#CQ znxol8d!_f>wf*gl4X<qne#>^6-L|{h>iMA?Ol@uV?M=74X|J}I?6vK1rPsYYb<Gai zp?h(y+3GZ(xq~gL>o__%Fz*uH9GuHvRq$zCE8f`2bEYiaEtX&t0s6%d5|of)q|8Hi zMuiYO>Ii=pAyN_g)lhNxei=t#7p3}&=HUuB6sa%N8Z1DUY7nZ4CY2QTaqldGqd4ko zkV;*b%5B((#lMjzHP482sqZAFqoo)$941LF!yUtKgu=^v1&Pb}-};f>Lu5$Jp-#^K zBeldzA^6H?F@=nKXCm{I{S1eaQkH;A$T2R+oHSF4OvYtK$ev14IYB$x`iIk?4Srrt zVIKp*Xqdw`BuQNwyA%m2n2BVBKQ@}x<xflDkYl`|afn2Jhy#vEO^TEd=3%{Y(zWr9 zV9zHA*<N64jV0^W19%9Zz%d_znZX*jZy<)I5%0&>OZRXuep{M}zn2as@_vQq;#V^@ z%<51Nn|^P}J484BT%No1l5N2qR$veov5bV~F%cbAl_CigsM8pZsV3^jlnKS-m0y-l ONJrv)VWM!MVE+Sqx}jD8 delta 574 zcmXX@&1(}u6n}4avR}=vNz=v@J!uP7sDWBN2ogb|q9D;ylL}fQW3an1Nq473!Yl!+ zw^9oW9%UE(1C$)RdiCx>JcuVfc=u2b^=;Z2-kab1nBTm4@5}t|ytC>!HqiRL{o&E) zkIpiitySf-ezm{RU)bn|veoG<EIwV@dVaCjs)kSGR$umdozWY%u48%h*SyKFHmXfr z*6=~R?Oq*bWSLwi3EK!Ta3v(DAjL>)KzEjd1dsW4u!xXtsR@d<u?#!-0@t9+njm?S zQ(B7q`1&-0U_yHdN?X^Jb_4d|;X%X|_lzi~a)~K;ieX)3*b;o0qHhFsX?qi1USS)L z+$p|gdl2c03*EPZpNc0=3gLS?-4rt0I}sVj)>m0birE8HvPn3vOl71jG6+u+Ldw*V z(irj0-DA!=-JVK^R9|>NaGGfAim9B^cUWX8i!3WCQ(-5we+6fhC3IoDVlxm~g8~s& z6jxTt5E`&qA9rcSw<+`1QJ>bx+azhgCAbUs;2j8aWsI62^c6T~4gRfmN7oAHG4_kM zaWDQ<T*5o?pW?TQ9h7Js!BnQENqyI4E9gD;;vbXCbHi*>S4e@u(8U5WG!JdfWj5NV avkF#t1>^grUrvr8JG9T{Pvz(G7ybi%%8`)( diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/build_meta.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/build_meta.cpython-38.pyc index ff29053022256e0562e23ff476e822649e779d5b..2a97c5d267d9d6f8ee647e4cbe6108807bd4b9c1 100644 GIT binary patch delta 2398 zcmZuyUu;uV7{BNCw!OV=Z@aBq+p#}I6jxyD+&~~1LpQb&Cj$ikP>h%Ep1bXquC3?Z z0b2^gATJssaH5G1M)1LeXiN-=4<yEfcTMoYm>VB_F<@d$j3y?SFu(6~b7isZ{oU`J z^ZhyB`F`i??UCO{^p~SiO@dG8(H-OKt=IGpB3;{lYS~W%G)Pq%q8bg)2J_JgiAHGn zZHb00{gN*qgK?DVFxIVLF<xwfxh5K;@wcUXGi{>H@NS_kGy(4fZKZASZUvhpO@U3y zY6JZwjMKCo#_d)T#wkE4pSIG)_O1DLcx}pW0_@0l0Cwg(0lV^DRtl85seDYzZn`~0 zsGolxxJNX8AviV_fkbXeOo!LQlexLdyp>~%3kyX%=P)xz3uW6XnHA<*PT#r3rQ8{- zd?r`2r*qXscdk+%?Aw!bY}e|o7R=LyS&RP}Jl7rvU&3Jn#BfgIm(`CChC$5wJ*8wj zuIHOCR6U>LGUgK+xaMO~lyPTy-KkopJ!4zUK>bFKw@aZk=}e%7?D@=+<0%zp&o-*? zPqba}CUn+}(1MWS_qE>sP82ce1`vBhe|z9@Q~;HzewiqQCHT!qioYKIizNBcNKenY zB^r4_!>t&wyD2mb07!w9PbaJg%-$k8-x3`N2$L8;89m;W6*ia;wHeF7sJ;s!#rU_; zJ~GHNT?ro7=M#8bw}_`&W$K)@-ML#b>*d$<#G1p;^ofCIKqsqsA#i7zZiOwfy)ctk z=L@bmXP0L^WyUU9^&prWi}5F8y=0%rsu-IN;Evcf{yj_%Uymok4f*lz_|s&ZPsIP& zjAij+W~Dr1&l-;9y5QPrJV1V;>DS?dpp{kGi|FzRv``9c_6);=Wq9mfh%J=Se4)zl z9*II{m3q-9`Nihe$HL!ee$YBD+%T&^y&$uyrGja(SNKOQ$(@2JW4Npu1}143OcZ># zFfl81HSPNGW4I&yLCfOMQ4rxM#V(KG^a}_LdE?Lza1|a$+;^e@6=X?S;r*@K`Q60+ zEpMQbf$)FU3M{<O-%af1CtL56LwvNY(6tklpGDXZsvqWV^1E%-K0Gsa7@-H@2!g23 z07#y%WR=+<&TT{3!A~W3kSM>BOp!_cY4WLo4Stc0AHw5c07;IMz=|rXvLYuGZAF&# zN3x&)lbq}P0#<9%4XLKwB<B^E6y+Pfnh#_j$oxWThP=anNsXU41bRzaZ!ZP*0x%}Z zt=A8-P9xCpf`w_PT5#t);NWQs^c*I`ydXq9Ig!^soZEr0pD(A|AdwH!yCIS9(*2W< zC*mcH=>@w)4ZH(}Yt2^;@OlSKovi?ptdR&@xd_1wWjXLD;8SH8$|bKTG9PWfD5&Da z&dym@2~Afo$|MG#L3lhK3&Pwz{&)M;T%Gm~X1vjGgAMkKANW_Bb}k<WDNCkSfAW-& zB6Vu6_o8+7iPJ#3F=P$Hs<AQxZiAuUhW&}C*m&3kz?<+mDFCReUyW*E&9BA$(u%fO zO-cmbem23+br|F@|FL66(K49~AMQL_7v5VFe(v1gjhi;HOlu$95K<p|vvZLTckNvU zHUue2OXrmusmnvsQk$!~p_+6_E^0MG<tv0puS&b5nv6W65|u8?L%^&x{nuay{)>E5 zjDTZy03aJ?ttbof3uf1wBowM#n75b>i(bGkFFO`<1%W)jvrx4dTR<~BzO29ALdH;4 zbru~137FR$li5{KIgnu%yOGfkEj45qW~tyf&@$Ff6g}OC$LRo&6irURwb%U`(SS_~ zi2$95yrQW(S=!9M=}0d3{nyR1go&~THk29u9t>JBAq+bAqN`y|t5jMGE#fc1DidYJ zoPL7GK{BXB(L|Qn46C8aa|q(9!D)3#Y!t^PLN|b?iPq{?DkX=duV)7NOPTZ}R?$<C z!u3WhT8n5S;tG!Aa-cF@gj*p<B?9JEW90eK$+4*eq7$xClYg0M*&;T)4!CPi9h$Gu qg_1RlRdq)AZ<$mtUcvS6LnRdVC)(5~5H+N#@ze2aKn{@AuktT8Q2spt delta 2352 zcmZuy&2Jk;6yI5|?e%*7k;G2?6~`qi;HFO8BvomFet)-w7Frb++U?e}Nu2ttv+L4U zsY2Br5Fpet9Jo;~g-RTtIdFsjpaS&*D<On900(+O9O!}Y-Z&*rRIlf^Z{EClGw;3M z%s$+`xI20>64501{dV!oGgsH&isp!ZYvk+#q5fK=9yOvwq5&GDDh*MMhN(UiG-3xN z8ln0PiRyOzy3go=ew4<bAG3pVy>oq_>!Wenb3-x`w3qh5J4q8X3GaT|PY2*V0CQ3_ z4Rg|V3hdL+&(JLNvv&HrZ`{bhOER){b}nb+00)ghz`T(M95RLg3r4}tfXzB8zbX}T zi)Gkzv`9R)Zk@Mjl{sFHA4}%=y}%*~^XcHeas=YME3p{79=$l`)>~t(YO7RjIIdNz zmBwc$+m|Mq)|g|v?UvhY*7!fcOPL<97E`()j=C^^PyK}Gd?b|J7zRbr$D*jmRg9?9 zvMbf;s?E$=)p5J$F0xRX3?^}g?D;A+$5WcDI@4{!Ki4+Ld(l}RLINSp|I|w5Jc<}V z7l_@UzvrMiDu7B<zf2Uul8cAKIw2{3N`E%IGA+*E)pMlCKhv*~7%xV~17a-Bt;mVt z4dB2F;;tcytPH)*T0+9Lyg_~~G8lOSL`MdY2%F?`^xCKn@?9u^-Js4}Rd@ET%tk@w zk!jF|>`SiQaH`El$6cI%6+N(J9L9@^7lNhiirZwD**4G^P(!yeTW!pE%5=46cV=vb z5hgZ};NL|Pd`~Pvw)4Z`LEes?4&b)g2>&5gD(nCeR@6lyO{c=DtyLA^>*LSx4|7Rw z#eX7EzN06(DmP}&A7>7Mi=xV2LZ`z3o?@|?iwv{Oum)a;wHu~bfMM}P)r(4p0Y}k5 zXZD3QL{+yNuH%vA7?$&Vr}y`>2hd7kwne=lvs*Q*VzX1I3s#!-7DVj@YR!sObBckE z+x<AGnkHt%G@0NBmfTY+O}ffIDA{rTu<!DQS3ra^h&WE5`UpZ76R;ZqxXH`OExh3O z^9PA-!zQZFB0S074+9@9mXmoxrufVKR(>;DZb4Y%c@yYv^ZWg+QA{E`hEPN}jvz`l z0g~sd*$p;{x)FpDuMKR>;A!%D>$YoA%eBlEiX7$l2G*C?EENRnkD)n8IZ2L_z>+Gf zvLYvZI*BgHJ|0TVX1{>3dFi$^uY5|bDlVCmZ~NwbAp2bYL28=3!~ah0Uzh@`D_W^U z;Sc~YCg>3Dq_IOZu<(M`Ij3d0vrK^=!=oU$(g{;UxE*yRgq;9h0O-)X2!&;K!>Zdr zFpSZNbchONuUidj#QC@BVRDrJnl7*6Wj>Q$_cho%1prCbhz^nI1S6H@z`p^X3Oar! z^EPn$=S(t>G-NXfYf^<*#C_hIy*VaQ9CI+v?)*MsP6%`l`1je#g_9r^$<*>+o)VJY zq2tPRwZb@&2&5Q8-Y~2aYark@82atnpV%p$adr^k0yHND0G0Hs5iP7KTFfskX+!FO zMBwdb2RYA~WDox<H_cBE9_RO<1@k+GaF-QvJAr^dtdR!I2hBOh?fh2#O1~R))p_Z< zJQw2M<TJ0oCQ%8#CB7*}z>4hyC~B-9Wx-!TPOQHd1Xf@P*&Ox)@C~t<>-n8_%Vw;N z6EN(@7s7tNb13~hUV^4ssacK#$9E-CwEP8{g9}NDCMSqSqB36K@)9;p<#&dj?j%02 zCedEdG-<N}4$+MlSze%G*J_U!5i4DRQE_>S-TeqX2Q#7)B`7q-r`SB2>_QL}7ZLBp zE=4Hx0D9X0A4i8}_?v}^oRMmspD~&3G~29VJEN`36Pxe?vs|X|_Y1j&FwRquVx8+# zoPTlF#pw{&V4!(!4(@+Zbg>;nHFxjYb7bGtUU55hQD=oUSj{I<$5UUZH)*?OZ^tSg saxexZ2j9fUkBpKo!{LD>cRi03HSSOJs}UeuNLAyr@q9oIkmX1D54zFr00000 diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/config.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/config.cpython-38.pyc index 3c62572125c231f988856bf23e13b0b14c289651..96de966a0fa4cf1f303a40af2bfd0eab71d4686a 100644 GIT binary patch delta 6121 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 IJeofJKLw7!Z~y=R delta 4390 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 No1NWJ=GqwD{eN|I{N(@u diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/dep_util.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/dep_util.cpython-38.pyc index e4a929c09c83a83aed99eab0deb0141da9aee24d..1ffeb2e612fd9427e9dab3cd9695e5fe1ffb62d7 100644 GIT binary patch delta 119 zcmdnac9V@al$V!_0SGw%?TX*JkvEUYDN;WpKQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+Fwid?r0%cA%lfVj!d0 T1Q?kZnf|k|OuoYu#mEK#D}E$F delta 85 zcmcb~ww;YPl$V!_0SKO#ZHQaGkvES?#ah24w?Mxjvp_d9uec;JCr8&P!=$vrI6qOp kIJKm-pd>#(XYyVqJ$^QzwqhZWW;Ovv4(7@Kn4%b20c6e?761SM diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/depends.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/depends.cpython-38.pyc index 0e3806c418d1dff62ea5c2251d2c20af25e01443..d6c22696341f9f152e42a2b1e9a822a2ab4e8ad3 100644 GIT binary patch delta 1444 zcmZ8h&2Jk;6rZ;{_O5qr=d)1?ZPYJPEWifRiXI9=O;ae)q$K2{D}>qXY?Dp)!^}>i z+FHv3=L%KXD@d_=?JXxba6uG_zW}Yo1y1<`xS^Ien@G@(HE-Yi-n<XLk9k!4s#aaD zR1AWv^yJ6p*C!rSPr-K&UU|8vGU^wCqE!UKR95h{K)3XuWR(KLG6K^wbG+!61I^Nq z*O<;q%-En-<vqeortKltSF9>4v&tT^hS(SzVx>K>hS@k9W(IO2Y=n)XY}6g?6SM(K zq;}#^1~cEQK~`B3+;hZ=%VRGJ4*_vR^=ob6IuUbgG&ApdA!`N^+wtAZynUxRyKw9F z&5!1;XC*w`SX{8?=5uywVR><O4z-O|`^~qUC}`Ot(-z$?c0BI#0$R?-He7LRs_8`O zEPM&Z!7p$TuB|mTqrh$O_Rh|h*NC~(V0P%az7uib#`SycPGi>%cN@O9-e|SOW)#lU zuQXy$xUaQrXWQOz(_!_jIgVc9VI+j6SJhwPd`jsbP&@dOK2o5N-q&2Hr+;fd!_D*u z{dc&Pep~wfye!R#RFv8}P!;n;$P;5oFX{#3MT0t!zN%05&LJwu7BFDS9_d3D5)w}) z&?ifX?<)xz$n2`~4qkj_Nqe!}(iI~svJj|LgLyuQ$n)eRVp+irTB5xowI~vz^or1V zA+X!)ZqxCj*sWjnBggjRck21gnwl9-6bkpAz$9hWV?MA$Ob*X9spEwkHHBY5YrG-J zf6jB4=KriOqdX6n00l#(Q0ysu2EoIpxSTvBJjqqYE&tdo?)Wz(ohd;QlBj)!l26qx z?G}(0yINQ8mR3nPL5YBEgI@y71CTp;Q?3!AB(x9rJ3ta$sM`wvETQ|9DFXl^3j4)g zLI=<_!W9&2C>BEBFG)881<`jAH4yzqm{M&(k^)ovDoUpDURmBtN&~fPib`T8Si`=$ zN)&RLd`uR}LoCMXF^_>%6C;5{>8n^G+WF@O4#1g<!NKFQ0@hI8$^0z-%{(2vh+Iaw zYqLxXY#wjgen$PsW?YkZN>V%``~EJEI&RpE*0)?oa9!e>oD$D>Edwv4Z&W9soW5T@ zmB!|o4>BqT(9*r2C1-#=S1fL#fzNTrQ%H!Wz!X#!T`@oh1IkFNxJT70oICib`j_&O ztXNizTGDE!+I%A`IT21_7>l@Oa#=k7cKUc^;pB&seYQ2Yta10CK6)7nnHsm_baTw@ z4G@f_glH4kB@`X%z%4vumtDfod=2t%ZH#|{M}9?;*OB0}<i%n~cz#^pJ$ie%B5`~> zW@e7w4lX0k^LLbTndqaO%G~h^IgNBpva<P(iXoGd$I7jAeSCUaj;styhq6*uCZS9f TEIR(4(n9sRZW^bJ3;NK%&SFl+ delta 1461 zcmZ8h&2Jk;6rY*>^g7<eNopl>j3ewfd2&Aq|QUg62yt5C?~n#!xKBvq`qGz1!I_ zG|@&zbp!`aWzR@Xuk?VFBN7)RIB`I5Kr3-V2t`8t102G84wZlz&2NA6-n_Rvzc;gw z@=x>jolM3e(0>2m%lE&}J+?>bXOAykY!R;1Xk9C5b-kq5jgnC}OC}{;<ytLOw@Map zog3Wbscp5CUMAe)`XSibtklD^Jk5<mTFUT#p5Z1in-6fCr-1eHUfy>|N_}o$n?M%2 zM)HFv_z5d{nq=0b@T#))jw?dXZ{*b^v-<jSdEr)ZasKT>aU)5uZj|Q>Z?4{YV{su# z!DOv)r#QdZrAx&^X>sL*LM}*U-rSRJ)#q+v6x|0+Pq;~X%WLp*-RI4kn+$Bb@*iHV z`i)Rl8Zzl~A4*ZF#$_7P)bWpWl8(<!$$Bsqc)=A97u9N4uJ63qd^qh_rb1UX1L^y< z_+{lnx*y&f_Tf&Hct`n;I`K927y81ntvzMbioY^kdMUnOenXey-^`!s?fC1|=dBbh z@5R7D0F$Z=G$G{FvQ6F8tn-#yWiWr%uv99Hc^KgiKtwtq;SoJx5feOO9m*NZ6v;YD zq(t<HspLK7Kt0d^^#kL;JV-^RRCk$JiCD1E;>tD#Yk>5D1xYNaaW!HQ*<v};rjO8? zf*NW2v$va}bZXwN>r8s};Of7`yqKT7>})or^PwkqoS;(Ot!%qa*bD++$b?=MxG6CL zus<+gX-rB7gPjTSn&UN`i7>AxS{T$knJ9rDBnqS#xL2VdTmZ;h;vDiZfJ6%_LWYTo zk9gFcXo(^8bzvA8#uj08RV9kWRBF*tW&)bP``O7Uv?@yZtYL@=qbu!CK=wx@$Qvnb z_Fn<lNh7BcNp~%AjY733*?{W;$M`PU{}{AYK-*%Zc2ukcB~t6?kqR|QH8^+;@NP-7 zlZr^!whA^2Y#+%q#vGAI<4RkB)i)v{d+uj;4bg%1HhhX2X^|cok-4QDsgSuB{Sg@^ zV-e-Ft*nzL`Wjg$Gq6;A3+dPqeBE6l`=ZowtLGf`vS+HIpu#~w1rk-b6`mONiU@Zq zwM4D?6)tpiUq^QqFUpqi_uWR>-@NZurO?oBRQ-D3!A(-ay%55?*D6fX7#{zb$<3aX zEYZWg`leqK&tpccpBP7&LAZf1i|`UaqT+px-?9fUyD$xL9WfXkp*AxaqgcNlKpg#w zMRRmSfyy3#YX1t(*v~$vFGGY_isNiyxPbJ32crjUpB(>{ouQhz2|S(|aOb`N5~7C~ zIjTZ8p^JMk&(oDW6LY}e=hS`Xv)#C^GUAo^hk^62o*hzDva3s1xsny^O;4jh6)Eso yiFXn3wx5+CjSSx@?!|vtL-ER>J?_91UyU0aVm<IL==M`pv*)b=Ys?xqd;bPFtWvT7 diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/dist.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/dist.cpython-38.pyc index 851c88624fc43bfb630410383b8216a55a6646ca..dbcb00dd8f281c15b226a4607e8679aab58f8d92 100644 GIT binary patch delta 9802 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 delta 18876 zcmbV!33MFCd1iOdU}i8l34#Q`18joFU_cNcMM|Vdh$6*PmIRU_B}*exqsCMN7+@|| z_mBiMa7!X((}ym%le~SAY|u{D=GxBM3n#mq^_kdCoMhu?Ct3S-lIOLvwiB<FwbySq z&rT%n_g8h#0aA9}0uR;I)m7Dh{r_Ko{a54PJ*R#2Yg+pwZEbM{KR>+qsV7f-`IYu{ zYU?Z8KJMh#q}HekQ(1GaHNQ5sR@CFUb@}zF^`hRA>(6gUZ4mWV)b*4u>TS7=`GM3x zep6~wesgLw+S*x1ZcBb^YO8qOnM>pcQ-h+uBA3h$rG`YkE4M8_oEjGOl{sg7ek3&_ zZnWHJYSi4py056Jg6k@}vem5Ts*>8tdRZT?cd#{VEv~!RI<_9y-R7O<U6WdB59?<e zaKD%7Y$L9BvjMgV*L`d=+k)$Uwv{Dt9b<zmiR(RVh;765fWwB_c2w?VBWx7cgKP)e ziR&SD2it|~eQY<o6W7D$uo;^<GIR8bnmTq|VRtd*s=^fW*p*P~DDL;Ly|~|dMN1vW z-Q8>-?)I5m@$>}K&M3+KUh9#pW%KMr+0GUV|3H)&PpY1KzxL2j$m^zuc#^YDmgxCW z&WqezU2Q#;GwjJC&$}PfPP?(t;aK!x^Flex&7~8ekh-S_vthDOCTHDH_<G#^V$Z0Z zFO8P6rR~{*WgEHN_B*C`moM)s8l#qJmrHiBm~$7yn>&Wl+X|yl)K-;maDS5NUix8p zt*W-Up~%c#Ivyl7FKn5)Nl(jP6tl~sACJ85Dbr5pP1|6GZKN-n+yeMJ-H$|esXLdx z75QCNUGKgSThl{8aWSGL%}s-)C$nabJ>Y&m<_zwli6R$`T-mhvoz$_`J1%?YfS=Q@ z*?dgh<$j{sIk$;=ZKGm{3R*;R6^~K9jS8I#nwO7Jagd4wR3uP%tw!0NF7mXQH?lcC zNKK(K&+&Vy$B6r``1;2WQDbw-$GgS1)1zfC4D(Uy6`suIOumOY?59EiFP0(J+a{J< znw`RubLMgPjrd{pfu%z&f36MgM)w;Ue;bXWsp{6<a*1bcQ)20gyQiHc9z=(v${(VB z<FYOWR&m8oqxGHcAG9AlKY*GSIV4v3i&lBvE>@ciCpCVS<{)&S{s`5Nih3&kkdZCe z_%pdcR8pJotTo9A_@JBaIH2C=ez4=Py3ze!$DznhnxfrJcHRr7$#!nuycrE%3vos+ zn=uQP$w#P5lA4>ath~ir-A{MEv~eRfZ=qr<ie#I_f>@TI+iBNWu}w|6FRbWYM-<_Q zQFu+}Wt$rkS*NJA-~G~xmFj}~S1W9{b0F;g`O0SXl>7Fsfy8iFv779O9ks)g;n_HU zo2t;S9b;NWt!R_lYUPUhoa%n6>*G!ffe`k>j5g{8nwRL~X=X{js)}f@Gc#>wX4Bbx zsmN_(B4_>?I$B*Q6jf6@)pm6?u9_OTsomrbS~DSf=KoNg-bHJ%QYhvJZKa~Q-(9(> z4&IP}_v~B1yTAMCJEt&|&r|U<6%{II-WwslK=tYp>cMw^(%sYdEj+f`Q7D=g>e5yV zaN{@m^Glmo8EWtIc;IzT8&*0~EZAnjw$czjyv2QOwcfP`50kO_H@IJ4J+ww3r-q?s ziJ^j3`o6oeC%NGzjJgF0aWo1f9CV-PS+{;5pw(mul-gHaxhg31TRnfGKIayDx1KgJ z>~`zsSLwkrKw2drf@7?ILI<lA1=g+hs@+7So7{DO)cacz!W@6j{XpNAy+UrhfO{{J zH~1_zL*u0U{dg8qF&7COMGzda^Zo8m`)*{aSRYS@yzm6XtRRXPA^C0C$#6aD=pA7Q z>fEw7crAv7U1O(de4O4Cp*Lx*YFOp3xo@mlug<t@*A8zR1J1zRlNvC_RAm8B&97nF zLfDQ~!ZXd_@em8Wpa~4xYk%Mnbl5+1yo@K~{5jn6G8Ml;#k2Gj{GYMC5Kf6YBn#~P zCLZ5tS_VJ=5RH75ibgDXT@v+No>Y0_qqQq&EuH906llk9tJ<w;H?=VTh*;Ib?#un% zVpYnFIzxQ$V0Be0Ru#son#8I!e^sO1eXhO!a`Oi<=Xf&0JKX=Xe#g-&y!^wrfviJ9 zW|hoL7UvL$c2nbv&H$p1f}Y*+Iwl2ZeM3OF&z=I=tpF(`(EEjcV~k#VD}`0_El>lL z@VRuU2%&3jb06AJI7}4av@^X{(iRF+X?w1OQ&FtvcKq#&BHOg=v{i;|-L(|gbL!i~ zM2j?A4HaVJ(B%B%RM0k0E+?m_&U$LYDer!9V~@Jm{r1KmpLjP7dk+;t3f#iVQJiuG zBY(?s+a<nBMrPKSGOgoo>!zVN=^O{~XPt5nZd&EA(5s<TglVZL3$rGuTru_#i?HZb zHPy^wtQjqF7H2KEwwSG~m9<@k=uWkf+KIMy*2z}j+QG(I7h8!@o#@rgR*7CK*h!&D zs;Mq^iuJKIc)pUYW$Q4ao2_U4R~;p_ifv#z8dkH7Yyj6Dwux=VwU=#STXF4U2{wr9 z8kS^3xUOZ}*f6f^*mgF8>v}fIcHr92cCtHg-N1IS-MH%PPIecr8>N<*8j$*7Y7^Vf z#?Zc*-NOzzsBB^PvV*v8Wrx^(xF*<Pb_CZ!c9b2%HOY>%6Sxks``O!Y-NqhZ58^s3 zRLs*HT&x%`btp=`s;OVf+S9sKF40+~LkQ`UreT-4X$|YdHMkfBrZ0VN^L$fp@F<}V z4KbX1X2!5hHZ<h^W1`O~3e{960$aLWjO+eSqN-3@Bgf?2iR#1R#EhA-tr1=KA6dG= zP2JE59H@$VaZ<OZO<f$izIKcT!`3rKL7y<I6J?!3CRb)A)3F5evR|JtENUs}Wr#~% zLWmV%Lz#TLzZxAYF$>HrWU^RvbwXOTaS;ljF_Fz>?Kzr-Ajy<D$HvsHISZN!06!{U z=CCT}#1e}6tPSK;=bPlkybeWM7wFJ4#e5#G5Wo<y*vq<AEb|N&k2g<b3kIKSST?#^ zHLT7R%K`-%sE@X(=gUsc&X#hGn6h;7Rs!1sS%MeX+%!k3fcc2`31>|g%Q?K?)S+-^ znSN>xs&GNi0zbA8h5!TTHA}W61LmI7^Tu4<3Fu8q0dz!xti<+&KA6uI%2rahvQve6 zI!gkA7Pr!^3fsl3A(1YzrRSh~24vI|+qV<*ZhtI6D071QV%bL1uzqRU1Sci%G;38S zBvcTG27Kl70N{H2w26lttQYV_)~W$F0a}=oMmcAT{ZO3`FA<~WicVQ_ZZ2261fH{t zATi{3F^2_UrYa$P!i%MV6KkL`6HEzQVKClCfCiM2n*=bPF-?h9|4Bm6<e&+NZQGkK z^1AI%kop9+(9+1zjV4g%EK!O!7xqH+6~S7q@`Pk)AMnZS6l4IsOf0ow`;m|!@T!y} zhOKTne@06(7_=Orz{iDlFVuMVjnNk)()My+*`cfF-T$!T+(uz4H5s<eEq)S$N~#fc zDuX+^bFKOz_ko=!+Ud+~#$O13)*rjqcW!V<U!RRw!z@HszT4IoL)W3nPbt@wbT~_8 zlc+~3>LMK>%5@EGv1`gAw4m#7C5U$P5$$nt7xC{}?AFCL7QL<>QO>Vk2-)q|aI`FT zR6;YIG>@uWaIV@b7Q3z~?@}gJaT>)i!OH8(5p<*u*OZxVd4K-Fb5Oq)n$WUpW_3lK z)G+Cqg-9h_i2(3#S5WIy7NV;1vU)+g@a;+yf3wnbMJZ?ut#%KML*M8XsB#y+Z1;+J z`W$=B%-Sp3%PLmBPBvXp>6-47cTAaW#?#NvpRm`@^ey(w*6Zp*%wAWCT~QaBWlN=b zHiUlH><x=LiwA9F2MHXBUg^HKD}^0UbTHG*MtcC-<+(Tp{l2e~)6f<<R1SL_&_4zo zEN&u_Fa-{e)^V@ZKkw7z8t`HP-*}zAMwkv-+^^j6Jlq5i?7Dj`afwuxgzX$3BV`mj zs&wFU?uT~mUo+o3PHJ>6J5Ta7vBgRdKhxD6*>mIcW?rNTzJS7u9+PL0*Kx_<g>>yW z<6ojaU!*>9;(KA2TVAMCEb%{}N1vzS52^UF8{0hsm&2aj>mx#Y`l_4St?v|yvhXZ; z(Ly;t0k4M_85b3Pp2l@hafXUMD%Q9+_w@F9U3gQ0U^n5^5bhfbI{2vj`Q7^*VQPlp zKS^~J{1uuk@TW+Oe2u0ewD7+`@d=#v);UxZH4dvFqQ+o{#Bjy0){ZvPuG?Ybbixdc z#k$1Pm>R>gPOVGp#Fb3d82W@&tq;SrH^Vo>kyaQ+Xb45#&~C;f^Q+uX?^?C=?!C?G zeH-zvaj#vPQo#!N2hhqj6j%z`{hYe-zog<jD7^5jIcM<`bidX8%ex=y7bLdmzHal= zt%u@=OZV=ZQuolv@no}{FiH=fL*cDV!&XW!13=J4+A!|l?q92px<B7P+`Vk>?_u~q zyLXR$cc*~&8QjA6@o#Vu1iJy}8A!4mqVMB*eCdIEEOm4*sy9?Q;zu;B@daL6)=FD& z2;>B9*SW7Bn2d-nA8;SP_qknEh4bb-&7$!?rV0N3HnYUX$k8SEeb8+`SlaMM)JYIt zOeQu(^VpPGFfW(*frR_o!82zB)(Jm#mfQ-uC5HqjV@opSKT_>~P$Aa+1F9`jAuvcN zPe!E!=5_b*p?!Td0BfB0cj(pS{`#T+y5+~zUz7d+C(R-NtU}3uind|*+I{z~`WtX6 z9L!oy$*T*Hm9{n$;!A&X-=MnU+ZAP|m-Y53i+v<Z&%fxdI&yw3Ic?U@lEnEYjK6l6 zw5@i3rJby-rI(HjYR$qx3Y~g<m;1$ICpVB;>P2$JjFGdvX5YD(Grb5^Crj?O<M$k- z9piQQM|0ZO6UD;4)`B@@*x8FFHS_;QOQCZ|I#uWtN_Jq6e(d;x$PcNx)&24D&7F5q zwQj|(exet0;_eflQ2EjiPW+mBNZ47Bh5!wkXOWp+*CT~2RgQ{V;o=2L^r1`rOf)f; ztXyzE`?llilWzEded>UF?*nhFcofKhF967Bufzp1PCl5@1_cyN1gB&yPc1H=?<aWr zs{4)c_jb0?+sN|bO;j`8+{raN$S9X0t!5n7@E{~A;Xz;|*#czz-pS#XzowSIrDC`H z`pHeV!N{pT_4%cJr+U@tF1!H#>24^9&|!S^r-c{78i&2SjsWPTxjLyvf&glT5EL|& zC#k5zHlBN3C4*Zgd8nYuND=-S_xDflcF?!_Lvo3Tc^H4zIuy3Ds8(>)EufsycyC3K zYD7iFnWfI}I>n0_lN2s_cEDJfgwm$dyXe5F*X;r|74Ux(GY0@U0h5s`%fBd|)Z~6J zufKDMM=j`_%NEDCVG&;d@Y2Dg#f5mE-%xMYjRfl#W(FLs1v5j-b?_&C=!V!rtevC) zQ=zjcOk<(zS`VGk;racCiv^rHunXmSrRpqHTNpuBsaOzpi*Nan@<t|_)UZ=cq@1Vu zKVxeCFDM`$J5(h_0#1-_7d==;wH3jkpQg!3QU59}lVDY}`Tm9l-qO{5{q%2Y@Xx>R z;lA_aukt!3O*=E4o+xK?ENxCr@$aG)^boJ#hI*<Ut0?9!;wYt)-nvEUq**$b&0_tD ztDQOG{^wI|&NVy_SOywo1IyUq#U=*L5@KuLf@()9&@gABOt}(T&?->oW}Eo{T4EU0 z%(NGz1{%MPS*Tw{6AIn{jbkAi#or+vAL!pgYGp-9uWKnlMMb4W=v0w${uKZOJnsa5 zxL<ku_%T8+{ES-B^1>y<p7x@~ghdq)fle7uUGBW*Bn-YwNGCB6f%9#Cr`z{P!i}Gd zhm)=Ro9>23S2>b#`_r&x(^I+Pgps3N3qLT7+<-2YJa4{^Y2-mo1oxu8YQuK}MlYNz z8jSBjHQ3Papzgb=Xk-n34?6u7!3E#aTA|fIr-7EzE_9S`wN;B~;Wy(=?(s*5mpUJ> zsE7Ar1izaKa)o;lSne##A#X1et-YrFEN=N~JWDlC!@w0%f<yCGL==S>#r=9}+dv~A z-U<p_fSb}81AZ$o4*z?1-4pjaF-%0kC9$DMN31{8AV{#WSa?d!f+rS2mCz#YP=m*E zF-&SPu1&0oMXrLN^4Vg<Hz0^Nl$j{MN+rYZ^BPQqCI%laOoq#qFpKpm53}YzrP9<x z58{=kNsXGvXtLOK1@?soS8vOdT8WTv43o6sSNO?T`wJ}#(Moi&S%49R1O$lK{~hj& zPb3|$)ikWRv>zt)TC5Dumh7~_r!0OPxXR$K`a{B${z!kb22fOB+`!<$!Cq0p^AYaH zRUXBPFKCQjqa`C=9GWj9AvKF5+M>u7(28odaE6(e(+IwKF_JQQD903}LHG!+l;WlI zbP=Q+m%JjBp+;iy{|y-4Ag&<?c~}F>yg5JWww+t&jEqT@;J`>#UmEB46Y*D~tJfsl zG@g3-?6G9r3)6DF79R-&T&lyjc+(OgRtgYZGUg~KQkqM3NTGv{aBmg)oEI}$R>Xq5 zXt^}S4TqVjwmf8eHqhcz&4nV=W^#P-{|gY3@zjPo*O`BAjMP&@5Ws6rr-d6Jo#u3Y zdrg^~X@JkmC0JJQfnY9at{kJMod~$Ww0Ek94nw#`NJOEg5lMv@^un~Gy(U2vewv1c zGI_RqThccECqgi3z!ZV#gl!R1<67&Ru~<ax&Q5soV-!nK!U~1GGzGt{@}g+}5{bmz z_&L4dU?zQnC?@vOS5cW##F32S8O*F<9|-#%vh_XSt`K&SvIs{z<Si6P+DUYXQ*9=K zLp(ea#iq~}A}j<(57UOQ&cV=*YA~tMijh5vgYDWx`==7=Q6@tyLXBvPinb`VO==5d z*Ed&UG`SoGQ7(FpDHnPXcu;2IJy<4Wa-8IHMH6+pZxzfQo8NzkF+K2HjmiqStenRJ zjX|$^E#<*#<bw0p8lR8rgT5mw$)5pY=EX6)eLm)UWAynLox3#Se9UK29g$N~;=C~N zrjXsfZYu=1Jlq}AiwTz>ct&ovB8*Xf5byB1{K?Z3b1;;J8;ry#Vt>qQugQNno2(QL zUEx0twCGfO&;Ugm3xe53+?LX&ik=32Po4^srXxmqP0YlGN=5KSyeWmZ(A5hS%uCBz z?*Nw64QXR-#(YXB45sS>tHrU)Bd}4!#D<}6wfoI*IIec#+5EOf1)|~f>RNt$WmNa( zXs`1O<_1{>=YikGd}#)GPGXWIxwV5hZ#Kr`6~UF_3XT*UsDKw?+z?-0083Qo8El-# zdKhDI*4K@J8b+R_hXvn+=kEsJjB+zyyl7V0LAZ*26{f+B4galu$uxx%Ha{*Tnl!?r zb<|%O5C*ns;LGD_;*)ql?`+{oevVpN18GMme4s)R={U*%RMad`ock8(fIJ>$lt@Ij zrV{RgZ0IK6gQ&&T`3>%O9_y*Pe%$1_|1x|RhKwg;UJSxUh_yO3;$A!xiUU7LwQste z=lkv;Zt|kOcua-NlEsA*F+*LJ9S5^$I~a1GIPY%Eq6&jncm{-yB32^??UIvsJh^(4 z5R7j*T>%{*a!)*YZDamd&i2zMSN9cZ;$<L}(DsO{r|)n-d8*GLZ3NMN{K{ik>Vfi{ zobNwlR#owY@0_N58XXxtb{VFUChgN51dMMWiR~4U9hSeED0`l$1Nlw*b>9&Ono*F1 zG*TxVr0qbx=!d#Dm=5(2U!i;^b^g%9NF(9}eW#wC4EPn^?yA#xSl>ZUe70i4dSbj- zFdaDSC-rh+wotrOz;bA3b6O4`rD7TCCedcp!LK)L@7r*<uz+X<^n-zr)czTB3>Dzq zf%1J_#b(y{R%}*iLVY-D7Bo8qIS;Fd%<7;W2hJ_qm4&hRrupQ<@ZTYLCRZy+ggBND zkT9Z{o*?TcA$H~b9fTQDj2-9;zy*vb{gPo-u|qK}^e7bVAS8v1qLl!dBHDxnxvLMN zg$q-BirR?0^=v>H0LyXcbp%^oK(_~xAwnn_`bvnx@06ty4t1*Y>l%>TFba8Qr_<9R z=>pyCeqmzOPO)!3NAP@-ir+!uMg2j`$!G(tlG~K|k@`-gmmS$dREEbb4yNU{MW-3x zk1jVfFY3FD;f$TUET`$G>B(k!uRF`GY!Vz&rghQ~eu)avR_*tSyTW{Ah}ytkV$Wav zW!-<nec8NwNG#`abuuw6&FEFNKp(Pqx<50&fpvUka^on?8;D9Vc8(?(tIkq`>s^@Y zRd?0YSUWK!84|>t*8AM_)bLRq?k>trI^nz5!H5-A<|RqTI^}S{nw-Hd4B6@x&6=@E z+YU>1E%aAH{MyogpIWbO7jL8@F#p1oZ3Tm|W^h&U^n315_K@=|I(spT*tw7~WwL<S zlodP>(k57;KqbxNg^D@<Ah<$n6?kfcTUNyR()p~F`EBAc9eow}E;Ka`4wLB~#BK3V zm*BbxPIUKY*<>S5KIjh33@3jjPOiaf#)<rt`_fF0dfENx%!Zbb4Xv<(s7NK`eq-iB zj1<ms{*3DWG_%q@Kf85H6+8S{JOWnUN#NJ0L|pb~z)HXSM6T66o9%vxUqz2w5Wvmq zxNB4sD78@gPqb{po)WsvvX{nk{oyX5tqTmli{@^E4Vo*hTkfxZH=cdneYNzl2cN}k z{CV6;+B`?Mom4E)aNpH3PtR-16BJodrAUx>@q?w8FWjR#{1lCh^RqO_ph7qRrD<VJ z=giB}T`#;^E7OgBCbAhgow7o7Q}}{l>81vnmglH=FBNO3SWCqVD7+@byJ2EAXWS>P z=H<(M5j|dCdfIwbTlGE~LGC2!SfZnduW*MiZgV>6i9jFROxT%ZrU%Y8L{Q}_o}f;T zQXz0WN5j8?g8Y`acq-#5diod@y;KM|$qSo`KqH}vw&I2q(kY4wSpi<d=-cmp=VGrG z4KMxt;*jbP!jU3YWaXSWp8dtmn>V3v2vR&v6IZBsmH@ayg*d2V(5QvPgIpKzgpe}B ze_gzg;u_Q`)hukwEJb)5Y0BS$j-vp?A~j;^!<UoV1{f+bV~C$ao7XmN=1KutEND<a znqSvWKzPs*7_0^!al4=1q8@hlJ>7p)fY2(fkaUqVxManAKgR%mouG<BFBhK757T>= zf%8GM9SXazJzY|_yX}>vvna+<K{g%#EES)p;xDKmzb^kC3QBH*%RPg<;prmd->3G! zqk@74(i==JaE|P8B=}N64pFHm+(|X^74c(Kka^0<P~cES9YwMxscpPO1s##{0Hy30 zPA8GrIGiLhrya;?<8s<>{5@0<EAn5Xf{@K=iFL~s2oU=n?aCPx)?=u|)bJ75z4xfv z8<9v@i?zk~$GT%3kbKeDnpiY`0JW9z(RfQN8Vko-Vk=`EvGuXFu@$kl82yB))h#Y; zaY*eth(C)I7E?*Vsgi;l1!`}YJhxY&p`@CS;S^;t<S<28Gm9ewD9Tz`E3Ps4eA;ns zW*w{(*Em}NePt#8Q%q+3tOe059Y2k^J+M_NbwGdW80<O+o`a|KNh2duVn|0RnD7vj z=Nqvt+sw`BBFaVSe17r^bQeFph*X=WkT(idhrArfLdaSc^d#}tv1!{bS^Gvur*Pnx zCq^*iXlbrgmyd3ZW*yOg^v=Bpo=OYj=Ta6KHAq&Gh7l$#h{=$|QKlp&-Oo55iHqh# zfMfzzUy%JlPTxS?MM^_8tEi@U32n4snn)}fy<`*|T9lZIuz?rIbS0UD!;o1)Q2^vd zSf-A+<|S+yWL!*@MRMalIZ)RV!o-CW4XS&B&}-<(y5YzynJyzI2x~#MJgg~Lbkes( zD!$Bvasnk1$yv2rAVPph>Oj_wh??j~!LlfoP9|^34Xo4FuRifH0%)+;3e4b4fP(ef zyli56kUUUWYiheA5=VR&0IBL(=(x2MmYR0@mf2D#F)_cCwQhYyv5=b+s3jh(+6nX$ z(u|=^gI^p<2r?SuEOlu>a-qXQU7oDXWk7MJ)E-~|tR`xSiJ@`BDzQgIf=rO)LrGdT z(Gp8f97EvHObCQI1X{vR3(J|m6lK+3B0a}<9YU-TF@<4X1Mrrdva`T`faQ8noU<T~ z1Vun17i{F-5|9QnF(Xpug1jV{>(#8JI#B8|t%hq1?I%|`BHIc(+DE#~wF(?pz~TLM zXrCm!HE>b`G}0y|4A*5o;meC6(x9^l*5>AF$#{WF%qdi{kB=pg<W=Kd$?8EqmQg^$ zo*=r<#I+Ur0f=8g^ks<l2SsFX!!2(abYQ;`hxqf?Z2}=k{5(3Kph(-Z%6hcHL_U}w zQLF7O2J{_~&b5a8N!`qskbX#!fAo0BKoS>Cia?^wvr9aT?Ex-M=rT_XgGrKA6ZvW@ zHyDYrKvY&U((0vPO)SW6fqW9l#<Z^p3=&3`+qo_p;2_W-DcPnbjB78x?W<^KFGs}? zcIr?SS%RNP64lM*qirZ_p<j^mNlXSr2BMaDO2(22r)L`;$>2|ILO>iOzls&tlT;#d zAj6B6l_}c;kUaIc8rB`FoSD{*I@)8?W(zcjp(jN8Y$9L~Ihn*NK*h0zg;hJ@Tndm_ zgRR7i7ZH~dGPi-5DPNXE1cC^{87m~rEhxZl7pzm8(C4AS@uF?+6YnP{1Vj8<WL^&< zOA{oP8monzQjl8U3ltH($uV7<jo~=19iP~Fe$FQZR=G5o#LCNsjF5MN$+LErHZ`(V za}Yfv$>2DYEAx*_OPq(*&3nrsDiRni0})%=?`;G+zJ#E3%ed~2J+&_IT;lca@MxbC zKvjeK)<dl!Wq25e0ww-a#z$@rcs^4c7U(rE8>He4>&U#V&6W|_vIK;l2ncx369dM; z@W8~t`Gi9|B4gli4seWqhR9dd6B8mituBXI7aNpF@Jsh77*01zV2%>c!dYL{ZGx2v zx=DfKm^wrO!a=lYkvf|Qgdd4ce}{|XQV>BbYdOk+f|Ddj<(ZB19;ZkGeyGVwAW3jV z{hlCBA=!&a7$tz>yd++e5=)4sAa5BAFLPHD$K;k4$ndk7(Fxhwm*Ci>PcTGEoJ^z+ zmMFe@z{{~XaBFr_=F2Vzq-Z;I>{C>ZvVoDsT+1~UYYn`QL}ov=mK8Jd%L<uQOMCR9 z!L!9O_Jc4-Ea*{CEGY?=GH&VcLXx=5c0FWayH*cX3~<PRffh#7kbYAY2Gv{%Us~6L zZt1yVaaI6`^-;!dqsB<-wu$P=FW;Pj24DRl+k*^+!<6k|QQ{0!7vNTgKNHziWGB23 z^7Amm<MZ4nfK+8`d5~|RUqiAj)2#*WZm+#Njq1D9-tW3|<R3x+3MoJ2<IBwEU_#{J zsq90e_;iFLz^~MO>RB_Z=u5iS$ij`FqJ-$vp!ptu0VB&2Igg#?!UoSosjvS-?oo_a z9>AaVeiZQfDkAVr85Q{E4<$n7C__lIMeZ=XM&b*>N$rZpcO$T_B9@4V4&wApejY{) zk^SmDLWD8?WF=NXmhsqLd|p_I*bxjZR3aD}LD*4AH&>!4<CTc@Vx<XxQR_v!g*B0P z+0W!~H=3&oX9z~5J0SXrIC>YdNZ`LB4<8R#)K|0%a5f9u6W+XM(MzWB{V%F5GsMYr z_2~d>$mCSw%KYX4YiR_3vUWQC{*&GAC)q0JE#GQ2zLkFhe8%7Eb)Tue4&j2h!oLI% z=BNC3>RYUR@^}&FWlb(Yy^?W2Yq@}G5M$6ks?wG^mgds_p@lo-{EQ$`g*b&DL;?4u zZ{c{&Rh^taNx;{zwu*WajGlv>D+;pl%hUv$Sn(s4Vlw_o8uvR?h#6=I|MzrD-BTLO zuVuI=*T!!XGKNr5LNO7YqzGj@5^+I`n=$y=5vvqgTxfSFG>+!^&gBGZ$h5#KDSJ>x z$myF!iY*o?!YEVKww;k5ax`dI^@?cii-vpQCKM|YYjeJa$(ApIqJn=&iy(g+B1LNg z*nEjv7Z`r)7|WOsrPXay5Jh9EA5g)Ue3Jx!_(c^?8dR{c&bL#_2tuM7g+wn5if@=g z2009miUfw5D1|u8+A@9uHCWi%LTXl}J<g<h`5Gu5y8bvmqQSQ-I+2@`=mxfSQH%;g zu6jV>1TUE!@*bb>FeGunfI~#Sh&Ex&SrF{*{-^pJ93tYZ6Q`0uyF4(&8-RJK_sBy7 zeaH&T)U+u~7pzEHGEniWDm;CDgO7>nTidFFuIux=NYV9Abmqvg5n7-_FE_-|8hooh z4kx6bHho1Qd0M!=1iOEU+Q=0a#EllH;V2rGa|A`0{)jk2go>IYs-vl~o8hK*@bP@t za`pfz1m|Ej`XT9$v66X5P(jL@B3M8r79i%}LsVAz0P#1$2Ww;~)VKq$Z{!1qkP#f{ z@(ljh6aD{#=Hh%NBb?55yvcpwspcqn;4I7y_f)Y5atyQ<dRGS8pUJBOCZ)n7$t<)2 znMF!AL6v9yPS7@>?82ym_F`DGzNSmB#gE^aAjsn%FkCeKk8bGMxP!Qaa9aw(3K2yi zfg65YSP=HP+YojdZGTOKr7)Dz+zuH9igpJS4Z=8N(%nK+I+PFN&jL*mN`*uM0SClJ z#>skJwIWbIXzzoZ__{tMqgWU4Sts0(A>)U5^`j=2>KxGL;{Y3I7Cst_{!;+$O)`Ap z3@0n}_7o-(=#IbpQ1y47|5a7}7=4CpoCy=V8&lgNkyp5bY9^f@LJ;3;fxP!a0j96} z$wb#>Di!b#V2KR^l^RO7?Z{kMeBw1p8gb2+;oI#bH=q#8uk3u&VN{-CB0}sdhNS-C zLrW~4qRHYd4OUpgYJ`$2zqcH8V1QNE4#01bb>zAOQ&rjWwgRtei3MUt0_?l7<hPkV znW_^RQ~3PPav+3sL~s#?X&{r-SBXXEr?x;ZH}G*Y;Sv&3I6YC72QZWbDboB6Rx>qO z(X_}02|OTVa0JFz)qr(C$1*<a<d}z&$i)s2Zhbn_rQrM2ZTSB@+J00OY%OtcKaOK9 z{$~A=93)DOC!3C)JzJBF2qXQ1X8*S$*zi%B{$o_!ph9RQBGN&}DJKcaX}58DWo-^w z6G4PO#axVFAtew&guRFp(6&T>{Ja_OM_d4L1mVBWh_+hcx(gfCweIgOJmUZwh1Y<o zDJY^Q-b4!boAf3U(=k;j;K}>FXgUq4gv7!KO`%fpDRkg_sV3C*Z{ZeSS;H$N{y)t~ zt~kZtjW(~n+U9=d9eMR-cfh$%!{-r()6+v~vZ)oqPeA`@#u}kqGG1^$;Or6kR=k@! zbk%i`-{@ML^fXuv!M~`nWcqIXRQX~7CM@q+{t7S)z66k;5m3^P7l-02{zC_rw*d`& zCl&XQVZd!Fu2AtD6(YV$ne*bKc>WUATq?+b;IC2f5h_0FPCc{f4hoD4l1MY=Ht6<Z zV{)e-Aaq-{`yZd#($O7iMG`aq@DB!XbzgsG^M>|VE5bib2nRK{hB_Sx)!?_M-BH&5 EKb$nFEdT%j diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/extension.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/extension.cpython-38.pyc index bba297119b420971345566b0c1a3367eeb7dbe83..adab1a898451a441a79600509b2aa591c9970554 100644 GIT binary patch delta 93 zcmZ3>f0~~sl$V!_0SGw%?TX*XvzgH;N<Sk%H&wr=va~cSQ@^+<SwAH)FEceKIlrhR vwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ$3VA##5{Svb-TR delta 63 zcmX@jzm}gTl$V!_0SKO#ZHU{*vzbxFM!zJtK))cfKsPh5xFj(rN7pFBq_n~~KT*Fp RwWPG5BtJiAGb7U}RseI06#@VN diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/glibc.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/glibc.cpython-38.pyc deleted file mode 100644 index 2f90a44d4d067d1589db72c7766beca3f72ff053..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1534 zcmZ8h-EJH;6t+FHv(sskrlmv(5LhBe9mo$Vy`ZQRP-%ovv_eTyVfh(NZ13)5XU2o= zNt$SK72bdsNG`eKd3?(S;uW|l$KGs7a#sG?WBZ%q^PSJ%EiNVq?C*m=fB9wsp}*Xp z%SPbO7tr+A&~e0Zi7GtA*v&~vhQyD-Fz{nI40*uA-_Wqfdpv?M;(Z>&*ylHR0%Od{ zE=q6y186A4_Ex^9W!V~$6;&gZ88Ejnw*V$Fv?tK?4s-^cVUEx72|7+Xv`<d(b5yT{ z$OO|weSnes{QyDkqVHkve%Rrx*WpuiLQK>V(?2D8(2+9;0x(GDLJ5u^?g-PWTGMe^ z>@j*ElrCgVwNXVqUZYacfvg2BMzofOwi>*%ts4W|%QY*C^oEU?IckKq;ghenx9#0= z-DYE9GKZL5Aljub4PfrUZJ#P7m5o`(Cb`NQ+gC!n^EN2}UYopT!Uhn5jksWvi!`ve z8zq_0I;-<a=q6`EMUWDE^8!AD?SCM33w-~6vT3SjvniT&k5-oJ_a_h97az-fQ^RE& zBW0;CPyN+5nj?t(a>x!7uIoxf--QnK6HIV|mx4HmaYPcF5Oo{;%uzMB5GJm9+Faet zXzS29ISINzuNra|aMGa_WWsX-wG`|k)9Zq>h==F+6nA(^<kp3!=RIWF1G1vQ@#?+L zzkO8Y`%*pr@uT&JKYy71wBcPv{lDw@v!^c_!HnS7NIfjfgx;r2LbcVRHkx{<jmn)~ zqho14rSI!4+w*Q1oImYbqJ;AqHnH(xu4+gMaP4MxX{W7CQHkd>w+)Kg*xp#lwn;;^ z1lPAqO8nXuO7Lt3y9lsF)mE8@x481G&AMfG;59Z8Y?@u+Vigwj3UsKyfI}Q%@{&Lc zNr>;@<(KLmSYb}Cb90ouqQR{i<do2XWT&yZ<5XgB2Q+{}fPj<?w$d4!9xDyhTX0Cd z?K*dj>p{Lg$qz*4Qkk1#uN1RzAHYuSM2jHA7y?!A!kjtB+%QaBpuRp{1%^5ht`7`k z$%77!+z3IY;qmX!)Dbn3a$$smqzP&!;wrUCLc!)z&M8!RDX1J>=vdQxP}pm8b*J=j zQm_dCj`FrN4qH@>IhybGU`0(?u4msWrJS}69py!-H~i`#B^D_P_W-t?Xj1H@0I%BO z72>YvEuJfE8_v#B75P*V^&WWOF-fv))WVx2vP`)|DMzDn0#vR5{AWBzKDYkVrH{B5 fK>0F?A61gKrFiU0K|2l?NDQQac;Aed<2U{TMTLlG diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/glob.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/glob.cpython-38.pyc index 44c5ea345be01ee4e60976495d0dc507cd3e8583..e325f3087a9a1e053ab63e68895dc8594947c997 100644 GIT binary patch delta 93 zcmbO!yIqzil$V!_0SGw%?TX*X6UOWms-Kaco2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu vTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mp1Qe>S(qCDkH;Uq delta 63 zcmdlkJ5!b?l$V!_0SKO#ZHU{*6UMA!u3wT{pkI(#pqrUjT#}fRqid95Qd(i0pQvA) RT2fk2lAoWmc?q*HHvnNf6o~); diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/launch.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/launch.cpython-38.pyc index 2f69f373bb1eb2dfc782de63f356026a92614012..a374daeedb880d2727fa571987d1a6a402d84db1 100644 GIT binary patch delta 243 zcmdnP_K}S@l$V!_0SGw%?TXi#$a|2F9mD}*XCN+ans~?4sGqNvxrTWG`$C3VmT(4B zhCqfOh6silmIWLsY$@yunQB=}IBQsI7*aTznQPffxN6uYyEFb$WxvH;oLrPyP!gY) zn45Zw6GRplBqpccV$Cl|&5Ms>PRmT0oXDi?6t16<pPQ;*R9RY@m8oA`l&qhUn3tKF zlbl~vl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2&?G%q_bJ$3R5CIx93po<w; cSs1w(nIP~l8><8p50Ec3`5{vTvls^>02oq4*#H0l delta 190 zcmey!wug;3l$V!_0SKO#ZHN<|$a|2F4ai{yVrL*OE}D49Q)vPFLWWxA8s-HYDQqe1 z3z=$JN;qp+Y8X;Dnwe`^OSo!SCx<isQeeBqU7TE$Sx^$6mzbM+ixWf^7bGU9-eS!! zNX?6%T*joVVyRz}TcBT%S)iMlS6q^qlcQ^tVNzOQoS&#)oLW*^P?DdYGx;`?f}|AC edInY&MlMDs2>i>&D#66V$TL}tIf7Y~gAo8XFf;-H diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-38.pyc index 7f7ca194528dc8af0f769c915c77d75685ce64b5..73533e8e5962392351c70be8efba9c70f66ed051 100644 GIT binary patch delta 1243 zcmZuxO>f*p820#U?fuH8Nt=MS?Ib8jE0JB49GU|vAdsS7s-gmw+=JPACL1qfkC_>V z>}nxM<-mnQHR8l2Ie^4pC=%j#_#Yr4ao_|<h<BWj(u%eG%)Ik{dEe);f4lPZYWIUq zr)j}2{QGHqFMQJNpD?h96<Guko1qB7>M%QVA{Uu6mwA~V`SspojVy?QER4e1wplZ3 z5}!0!D{Dt>WbIodAmNu532E@yi8^36Nek>2b-{Lsecu|i=d<QJrBpmi=afA8Mxwhq zKyPjRg5XI8sOsORsw@=eOukDCL6fmcdH!H5@-(05JLt##B?$cU;pmWObR=eFIZa1W zBqK7;Q_2!96qUo{*?e?F^P>?<AB~EcI^_B8aBn12MYoG_^6_{=^|rl*R`plTKrigQ zH$&6j77i?xo8|}n2S>EP5N!h;1E%pg^k7%D7@x!$l@f}r>EG>S=f5>PLLZeAv2vMH zXV;0LNvz#3L;DZ+mQBp6foso4U#5rv9Hx}?0Rj{_fg=Ka%}vqg`U`jCM7d`+vXpn~ z6Nk8`jRiVGYt|V;*1|ds&a8S3>(v&yYED~XuG$N0+IfsVa~96DyD-!v;(hHPD{rf% z)84{@Do~YJK%0N}{rPu0itl1s76l9$rxKG3g6Ihu;yVXe9a3BfKBbAmQl*SxK|d)| zK_$LdbAWgLO@9p+jE*J6SvnD8MX};|j3sc)=yt+kI>sqED-Hda3rw?u@fjZHIL)Ck z1;`ancz#4hN17mLod6v}{fE1Smi0|<y<Y{No-0RIuGxu(nXn;QT+z3^2@3T0-tN93 zy7CTEMr9Nbo`8gutdMwta`7s}-Gp0W0Ly73*Ic%XY}fwF_4T^{ZKoDNL%ae3VpIR@ z4_@!XHd-nrjm-e#gY=jR30kYWqT+=n(TaYrv4U>t?Z!{2uYYY^zdA6rOu@<*G~-8f z0NT_yf{l&mB^mYNm>wsrB=n-o+xny6*2$X5UpMfQ0rM{eHn3sfS&e6Uv%zr#?hCy& z*Mp`oXM=9lh+~*g9E<B<S6z}y1spLsG*}0TE#nC<J$gCZe7Ff`(JILP@|}(^s5$4v hDE$8(r3&82I4K#uZ9Wjvyg+Ukpf+4R8&;>+`UeaSFIWHo delta 905 zcmZuuziSjh6rS1HAG3QuOrqz7kVH>Nv0!qN6HF0}jR+QLj1m^ia+jH$8)k3M+1-%h z1Tg_Ci!h}YNoi-TVCP?8AuNbxN_#8cY&6E;E`0OezW2Vj^L-y0KPKvrYBdkRbG-9@ z<C}9(pWax9jG+KA%nX5JBOqAEM3}J^SY>PqJ9YvmrU5N;OSpl1A2FLb`-nN**&~4m zIb|;7E+>#1%zB7?@8InVHG}WsRrL~o^lPx|=k0bD58K0NI3EqttSiL);?tY?ZYSxs zQ=a9+EJ=jgH|Fq!`c8cH#aLQ#V9qxrfuk^^!B+B)NEZ^R?;<N2H1!G8Au1{&>4z~- z({7(P)C01)c$ULryqEXo_~}eJT@Jc>uq;o)`o~KbbkBr_OaFGCjz}8{nkv-+#gtGY zZ55jlmg=k7T4&_Y9N{C}L`N8-5jwPvP<h(rX~<sYY*RVN+!5OL_V9BuBHNV_1{W|h zUxOcmYF0h0jS#RH-~a+;t<^O}?76G;qROH)lTk0vqGS-zJmukHmUK$B<d}M5_pz-$ z+np7ySYd5Nf~Nsx$!5mWEG@7+r=7e8eKYz#lK_ZRv01)q#d%XJRdnPPD9BlL?D%*} zjnn4!k{b`tQ3V&nu$M=Ig<H`sm*JobmMo|>`l&Mo3_<hH&xU+=Q{;@F^rdo6^Xnyr zEqR>ma32g;_uN+HjL+(s+rUfem3vDxbpK@yO%3`6a$1AF$C;n{YnlNC-SOKrZ=8Bk zfAcGa6NaEp7#4M{EXXR-1&w80wp81@u{^7Jwcr0EFX(cduw3vvSZ}BTm~ItU@t8r$ GSmhTJ2*Gav diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/monkey.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/monkey.cpython-38.pyc index 4278194651a1466258e33920020e39f1a2ccefbb..3ad1c9ecde4444d71a90958d36e91daa9384f005 100644 GIT binary patch delta 93 zcmZ3Xa!iFMl$V!_0SGw%?TX*X!^!LvuAh;go2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu vTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mp1RqR`8^*1id-Nt delta 63 zcmX@6vO<L?l$V!_0SKO#ZHU{*!^x~-sb7*?pkI(#pqrUjT#}fRqid95Qd(i0pQvA) RT2fk2lAoWmIh^@D9{^u+6#M`H diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/msvc.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/msvc.cpython-38.pyc index 597e93e70b347660b556685b0e2a940268b77260..4e563ecf9120036f72dfa14104a0710d08cf7b84 100644 GIT binary patch literal 43204 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 OZ}q<~bR38NAO63mT8T&i literal 34444 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 wfiyv{&mqaxiA3!x8h| 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 diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/namespaces.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/namespaces.cpython-38.pyc index 4c7cbcbe0a96b19f556c0aa2b641b0c6ec379faf..2a5eb30abea660716bbab549ae7643d09a581e35 100644 GIT binary patch delta 147 zcmZ1?b4Z3al$V!_0SGw%?TVkik#{PSQ?!0Yer~FMQDtdqR;GS&QL=tYVqRuyPI7)x zNouiPMP-$KS!!OHeokhRenDkPMt+{Lo`rsKW=X1UL1J=tVtVT4V@z{c7~MA~v)eH; zdTn0B!NJHFx_LEc9V27ZWG(JpjAE0Ya_?izp1g#ogfVZjByTKZ*5q>DHH`59WmYk3 delta 117 zcmX>kvqXkBl$V!_0SKO#ZHTMi$UBuu#a6#0w?Mxjvp_d9uec;JCr8&P!=$vrI6qOp zIJKm-pd>#(XY&)LIV_CMn;Y5f7#ZC*AK>6%WDMMVlCzGHF>JC2_bx`E$;>?a7}F;o V;wfRwnrzM+%a}HKD(@P`XaK$xCF}qI diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/package_index.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/package_index.cpython-38.pyc index c86d913399421f546b23080ea0716756ac9fb597..e9e4edb494bb6c1e70a49c019fbf77ffb8bc18d4 100644 GIT binary patch delta 5426 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 delta 5254 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 diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/pep425tags.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/pep425tags.cpython-38.pyc deleted file mode 100644 index 0b96584e1f994face86183cc4b8af740f3b12447..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7207 zcmb_hTXP)8b)N2-ot<3(iwgmepeSkriy~J7Aqt=whNfsryhyZVkQS*(TFYJzwr7C> zW@nc@vm~&ZwOs|eL^<UYQ{{&|r2s#utT+D*|Au}^%665*RNnHEa#Ufy)3du+kgU8U zvzYFl)2A=z(&y6nXl$%#;Q90Y-~FWVx?%j0K8BwhJ}%>p{}qKWDu!T!hpfRXoKf2h z&5DKE3av)2lIy|jimm(dmAtN<ilgg7rJ(C#rHDEgjx<IqqZnh0d^px9RZ6<;gyW5g z$^<j~{O+VE?6Jy}D2kDXM&*zg6=SHUMM;dKo)Hsb67{T@5{FP97O#pKG5e5Jj)=qJ z2q1G}P8>yjRJ<gPp?*ocERLf-CSDOP>X*d{F)zM_5y$<*J4WRdVcs^%uXUE*^CMq+ ziSK%ma33_~ru!gB*4<mzZn<ZdzU^LVHd<a1tOj9_Y`b^7wRrIfIAoNW8uwP?X4p>r zYS3skWwHX888+8Yjog&Nm%g|f)RHGGLpS4K3thRjFj%d1W=<`>QLdi)Ozf8c)Cjl# za5PA0SMbIkpy-Sy#x6^ZJ@&D2+pvs;Zx-csW^@@dI>!=o7XsSNrEHHS_8!FcvGJ+# z8%qFJ0OzOd6MRSf6MTVmzS7~JcguNIh_~ZfGpYw`s<h@O)vR5;?@5)var2s#O{ts* zo{WNMEmjt_lwEJihL@<)hwUf{8ve&wcbO}b#xehELr!AHe|h`Oq|th_6|_zVQJi>T zczS95Y<p|D>Ae~INxPLan_)cMZ22v)Jt01~wq*fx%o6!pc^PM;Y=TWO4X*({c!+N% zUd^iuXe36$1l!?qLh!B;y_T>IzH16|kI8vq0WwVxk=x{QN!a+dM80dJ#2Ke^@<Z%R zMy|KID*gKbv_rU%ap*VvD1kOKBRBFI{-T;}ZMU|o_k9@yRt=(hQ}I?ySsUJcPw|ay zW!Az#@t~!6tyQ*Ee%*_`B$3Jl)0NW-y@WWair|e*V$wXQh~3(z)iejQVhR+gF_I2# ziS#Wz4p2OS!r(<_gE2Nk%`GNh0qi;E(D~NPSwJJfiQZvEuAEKSjv+YMa7viFJTVh1 z$?X_Bd{6g-9aiUfj~&mjphxzini%3i)D+D`PGb>elx;02y&>?V8AQr#cr6eQ4$KfW zG~)sGfqJJ8e3t&v;Sq0Oh1fx1aEFyhCr+Y$fNbhC@oKU&odBr}q|R&E^Ev3qhPh$s zGFOK|7=m+Q&KY%%vtxk?xy}!JOn~4PhXsB*3^siisvP<*Wa+kJ-wh&H_%*531*gVM z)_u1TL`_+A@$~toxg<$*B}r!m>>|<0mr$tD;WgwT0_7Us2F_wm&osmwI%twKM4mvg zj5j+jW|5be{nRow{5jTGK-8=uC4%7q@jEanJH{S}F7wWJ^ky@vV@(3ApC&O`4`MfN z`L&=P)SfvQi+WVY`n(I{V#+bhol!;NdC{iTzF2YUF99ni!)I8MM0}@4+w4EYropxs z@sU7<p~zMW%eU#s*HTlu3ESm@!%D&erXcCIky<Gf97LI&wT~bk&#l7}t$MXhx8W!2 zO`)k0e&S2;mIQYD<~#4+aO)w=kQ>xB@saNfn1ReXW^(kT3r4gfSTdI+AK}yop|=|P ziz}T=SF}xaVGjcWxhGG=CkOZo?yYUC9J#a(=yn_4w!2E2Q)^1;*AnoKjGr`7sGRUu z+iT^V9H%d*zkB8QTaW^*lN_ZE*xu)ihC_#j2)PD~%wCudbC?Bt!Jk^(X7UVr4rm9l z*~Uw2$Nz?+Z!btgz68tTuO5-ju;o_?EQT;)X1{__MRd^Rcws|Cj(q(?19;9R7lmJ$ z@_VA#W#}3C!l*O&_xwX=sCQkAbvb(B?`fQv$oiT;PjVZ!nEaI`A5%*{7E@hQ9C~CV z`5lNi<*8ZE%^F=Rx(sXf`_$NV#59cj?}dYQLCowiF*|1*CXD02_yeFtiW&Ae>KUrh zV~IIZBB;pG&L_QtPKUNHomDS}>>;j9F-}1z2C^=b?EOX?w%pJ9wRW7k(v$EK$@<oI zc~Rx`=u4#D+1Z~%OBEa5Ryzu6O+*ZTMF8j4cJ=DDcRzaXfKbq*1#%m;KHq&0M~8Jq zO+d~`6CPIj^;#2Nxy<EJplWOK!gJ?b486vx@GkubX#auN=)6qI;;jZ%XyoF>uvzoM z_!1f!o}}%TS*B}DsIiZ4+<Cux>(d{+^T7u<uROO|B9rWvw$hL$46oj*o@ReXUo&Nq z#m^wxjC~uUs(9r&6pA&}I5_gr%8e^GuU@O(zEQdM!nKANvjNxNTP=9{bOH>@*sw&C zYIC_?3|6E`^@>l(#9#;+m>#k1PVq$C|8<;NOCR3Te_^M!=~iq}vFb{BWZ&NnF`v$t zr1PZATc0jzKP6wL&s^L>RH^dPM<7u1%Q--rV88rp8u1+}$Q~+_V0y=YLonL08W|GR z4*`fTqcCu^Z8nR;o&9WP|F>;Y8=*n3g=0_0{~J4J{TH__V3*i5FlH%qcn@>DkhxdT z(bKwv%zgT^9&=S5dK?EG|3wT|lhq)u%63H7wYt2t8YD5zs4YE{H=bRVED*hV*}q34 zF|uXlPsqIQ8K0S5gtT3lc?5M7tC%SqHeCC;#M*%v$r43VfKh<=zJ|SzFprBo0%TJ- za|X%+O1?*K-`>dYI(uX<xG2Ih6vPPC+OdpchF|I#ehC|uS&35TOwUR*+tTfaaXKh; zPd*5u<)xDg?#VES+FRAF^XIDP&Yo1Z@FcqAWssxn3<}j>K7UT-TCLi-v&ux(8E<&C zX1rDXyqo>)2MF>VjFjJ{;iJP-t77&QoI8K6T+B567-2yoHHxkzu~9Qw`(srQL7cRc zAVfG%Rpx^GRLHBqhAu)aLmzfeFRSNT4<aAw0x2y`t8D4V?JyY<xIRpGF#ZAF_y`I_ zr&fvSNCb*z@mcdIE14FTgmpmGC=eo-r)B;=8i}F9wY)3|SdPxLFoh8!Dor5u4RfcT z1R-9nQzCSM8T89ioW$PE3wR+N%h)TK&Ao+5<xLdVHB+CE_B|mrD?55Ss#tA!(YEHM zvR09rsF?xaEhI)+Dj51|<c7}pvgD}r4kG$s6^Wq!mU+ymX4bv?{?L%BPWxaz$=W`{ zF?9ro<An?T1CR$nzGc$M9c5G8Hl>H2nu((S^p6a|Vu@nS=$c;`U$8ny3eF!oUy>U) zi7CQfvv$~*>=9f!xzHU`o=;6=mN-bvc*L$6KYk60&L6SVnls?$FZM7kU|!Ui7Gd7g zZIP#TO6j!I`Mch+@Z1nO<~HkY+-^~F4EO2D+PWXRrx4?WZ9!qynryaPJ$RXdFzq?X z@va5;{Rlx30^Wrzbk_Mf6q=M!4+#>4K5gmKA|6m{H*Zr({aFxtfIVc>iACBYrD(u5 zP%1D@EC7r6CPSc@*^pBM81xP>3wRfMu-s-&!)(BA4e&JV5d*8Xz%(QlVBu`n?6J)R z+wS7VBY)etcUL%IRAEJ~U=L;fgc4g>q2dQrP?`^ex=QW0srWvMJJ+?slr32%(Ca9a zMcl+?0##pgRjT&*99MORtyvpqil$Fx9ix7WH>Rk-m?cGe_9aNCOpYZpReCBv-j4(h zE<)LU-J?K*cHJXL<$@^jLjY;#J$h6Qc<0XcfkY_=6L5J6f$jiP&!Gy4hA8{-Xcm&2 zvb|Qzj|2kX0R!aUW*u6mq@cC5hxDnXJ>=wbg!~45G3CvMW%1Ih9G+1BzOnP8Fi{RW z!bW+K%O)_c*GOCX&tWtMw&`DBH*mOeDaACf9B6A>)wNT)4dcIn{JZ&t;R`Kz6dW+< zgWIKu6dJaxbL=#qI(2qfXWIHOEv07bv&7!PvBivq)M{-|j7uIz{xr4LSX#j0wSK`b z8i@mV5nn7UbVt&W-Qpf;+(LIW9ThmTyCblCO#V78?)D*L6p!z5@_c%=U#ErLQZk-Q zq{SWF1?VGO!0vDhM`_bz9^XlM>)(?}tTdL6VaDPfd(31fnc6*+j=|%W(h|O9TH2k4 zKeoE#-F(;SPKc4+nRGnGTHQ&|F_qwkAvv5nJ4`sB7HeUrXS#=yBY@_2Sb8X((EK^l zold8Ac{&Nmbe+%YeLiOQKE!(|veU6O)}4x8*XP#3%Kwzi?HE*JcSq^IaE}9r1E+_Z z7O>JH_&0@m9#rH&Unw;qH}Hs7Kw>yn$CVJnJokQw_qXW74JJttW3G2+(it(nX=9cD z1P;HqkQM=dy*KCap*d%snUCMIFyA+L|8!veiEMS+!K@()gZ25nGtci&6vSk<zk_}K z{qOfDFHs_ly}kPx@6KZ1MC(L4Q)jfwV3t|3WskZ1$9{i*AAJnah(1`TDX#`K|6i;* zQiNFN%|2{y|4yTSD?s;Ukv8Ucd-oXe-Nm8?TxfaHYxD=i7ht;wt^#fpUZFo?fh;>Y z1G*w}e>A_mJip-1FE7pictOwP;z8=Q(uBcx?+{)f;d6S!ag7^>lu~<f+-_h)Nwe>Z zTngHd+GTE{x1oOcbD>AWwqDxb@@mO`fVbUjyAQkwi+Eum2D|9<0z2;S=SE#`Y(d`# z5fM6@a&dc<_>IAY2X;VN(2G_l_|VPc|9KB&pk+(ab%(yZIj{+&8ZX)d!0!L+!k92y zcjd`bJUa8$QCY`Yq;%&pEUx^N3bMn>iXdfW!@nao?u=x?@rj^%B38L9UPBt)3*Fx8 zSd^;im{0NLxA30nSgmc~n!qU^)AwO2C%tG5H$Jq+JQd%f;#Dg2H5}zaxT^FMWkLcK zeN7d&>-AvEkF)&E^n}o{wX*%K1P)5su?}^VMJk=elw(zj=E*5n@s9+$#7k=Ha*dXu z%Q5BPh8fPz7g#1rwC~ZuoeslQ!H=N4^#6(SVdeBshO(n3%_xu2G<3BouhU$GL9iuH z5pduw5iYC-U=_;cSat~4&S;S}Li{;FEV|QHBT)FZ7iM9EnIJKb2!paw#XObo?Lo0# zN~*oCcDVX}da#3k#(;Pog;BDQmePIGD4%A>;b1M?SX-=wyC;f3O6(Y)0+jBr;eLTP z0jLFMJk5?_<dhD0>CWm^b3*rLZHKw$G1E0Ckir%*hkT5+%KXlqa&G1N%F0UFRrzXF zG;7r=0{d#cO~GQdDq+?PRT`u~i<AM$4*}G7ZJMQuOFzq_9D<L~h>=<|3=whSqCeJA zNkt1?Mmn|6^jAmzdCC)l(3d}>u@p57U4WjT&o`(zLj~zrmY7jGl*yf<4^4}jI(YKw zR%R%3*k`<RvC$Om(7$A2XnY=p1x{ws9r22Oqnv(4({Y?JydzG&IO@zhmUGmZblyhZ KWEfA2cmD_Gi}X+c diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/py27compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/py27compat.cpython-38.pyc index 5dd14787794852adb3728603766b8f7180158a40..5ae3bdf2154b7a1a35e88dde8da8c6a51c3a6fd4 100644 GIT binary patch literal 1783 zcma)6OK%%D5GJ`RX|=L!$#Q}|(snPYE5MZi7pRM(2nslM;xvf`J3;GhfyG*+td;gv zl1eRMeQ9&<Pbi$D|3ZI6Pd)Kepr@RB>mlfnmSe}cl#3Y-XUTbdoZ-`Y-9<2}uYM2y zDk1c@UR)gxEWQR3e*&Y(M-)>MV;`HD_ylGvwi4U7F`_mtJx6|t*`qT5oR;S+a$0$T zXk|>YZT-i0n8SOlnwF_UtFYgltx=cO;##ucFC=xpo-F!{$&$YW7G1gk`i9>~ntl_b zZ&CWdMr?WP@;@-rpNXU8w_vWvt!t-O=ptQuj{ODNpiS`9pv$xcbMpYD<U2&kK5E~X zt-G69l7})njN(X6z5Pj^XIy%NjC;MQ9A>Gv-r4ZNlzJ@Wam2X$63{@8+gMp5I_?v_ znhz~oK$}29V_Tq8RNxmFT;bV$*Mo5{dd5<)=iPtur1yvk5gxHMk25*pppIj2$U@4v z@RCsWhf#Xuh2D`lGiK9{F#)bCM@$B=`;4eca&AOfu;C2x3i$o^`|dDHSeH*HlTp+a zyx*l^8nL(!xiQf>p3b@u#<Ol59d>h*=4YKRx+0S7(>&~tAtuok5K}I*EEce3eWP!1 z>f}?kG<P1%L#^p_4GuQ1g8Y9mIl~%77p%<<aT`vX1kRZ*Kx47>+5=Xlhfz8??qg70 z3@vLixN92)+DBYpfUyHk@bNXX%K0h|lS3Nbxdq$)0YZEc*h_7vZL8WKN@<W}bP_XF z>m3A}yN`N154Y~BDlE45cKxl#M%>?hy0^L2CaS4X8Srez(jYq=vA#5^&26+TzN~%d zO!x}0H$c*%>bOk;BM@}qP$--eQV>2U$SHIltSm`Rt-^wmA~yQLI<Zemz{@9<6X&E_ zIFgL)G2y*}<lEFb(x*$n@sBQ8ab=0x1u4*g+(f_NpS89Mg;|<yJeUaS#nG5~t5K47 zuB84+dv(n_oJjAdNDjSuX?WtiNfhpI4VQ9)AW9<{1hdv=n65(i0C?VQ?nSA0TeQon zBy#93W#w6}EO5b_`dGd9&As66&feDMlij@oRoh8)>uqtK@wThVbMQ;hokO8u;!-GE zPYMsTAcv|fCWAqAtZdlKlsyK&%8pX#Ufl*)sz^Ir1ri#2L|klR7vF-}#SXFYGBF{& zaVc+gvqY!3K)RbvZM6x1A8hd(z(D>`%O7cW&9(l&0d(FX*zE6Hptu-X)?{w~JrE=s zfujK~$ZzCVsBE}bt3dBw6m{D+j#Vwr!q+uwiK&3Mz!a>2YP$?ar+q!9o1ps=Na(6V zxPiIWw4otaR3!*#)(-;S29<L1IFx{A;x{iJgbq8FjHg^fWExaiy@PeQjj50<@t0!V zq5-@bK`8oB1TUrJevK!RGZu(&09O@Ul)<&WFz}dY_y^j$f%p<pBk6Ym8u&cfJGunL l$G~jcfy-R5oJtuxr3GxiBBh2+@H=<~FJcF;5Vzr2{{hRGnyLT* delta 254 zcmey)JB6)2l$V!_0SKO#ZHSX#Vqka-;vfT{7=r^47l#0e6ox2<6vh;$9L6X{AkCb^ zl*=5&%*c?!lET`;5XF+poW)wCm%;|+F)m<R$dJOG&6IBkl8ItZWiRqb<;Y`8;Yi^G zs^?5$WeR4{<eJRFctgcjza+OnzaX<fH#4ueBrzvP*C@lJw8A()QNK8~q_m(UKR;)( z9FsO9*JLlIL`I>>YnY-XrGbw648#mYd_Y2z>lS-_d`f<DeEeipw(!ZT*pwwifZ{AH W985gS9PDh29IQNyEdQ8T1sDO;R5h;v diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/py31compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/py31compat.cpython-38.pyc index 319d93c0f3767f7ff8874a43da35fa1242ba1020..85322db3b833bb1d49f96f9f1ac867ad886dbc52 100644 GIT binary patch delta 93 zcmZ3@d6JVSl$V!_0SGw%?TX*X^O?~pT0bK{H&wr=va~cSQ@^+<SwAH)FEceKIlrhR vwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ$17(QwI|Oyh|Wr delta 63 zcmX@fxtfzFl$V!_0SKO#ZHU{*^O;e_R=*^-K))cfKsPh5xFj(rN7pFBq_n~~KT*Fp RwWPG5BtJiAvm;Xn699Wz6)pe( diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/py33compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/py33compat.cpython-38.pyc index ae02e6133d062621d43a97c97d5fc2ffd07d2d19..c42f7227f4f53e191baf2b0a64be5de9e0ab8c7c 100644 GIT binary patch delta 93 zcmZqSUc}84%FD~e00f->cExYx>0)$>*3Zb#P1P@|EG^B-)Gsbd)=x>y%S_El&MzuS vE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPu;wW@f0%vhBF|D delta 63 zcmZ3)-NMZi%FD~e00hs=HpFe@>0(r|)i22{&@ad=(9O&%E=kPE(KX62DXlQhPt-3? REh#N1$<NQ(e1q{6GXPpU6;uEK diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/sandbox.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/sandbox.cpython-38.pyc index 11cb980a6f293da9d04250cae3c1c3bf41042ee8..4121463c105d51fb8c32713044a4a7e26ef7dae7 100644 GIT binary patch delta 3150 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 delta 3210 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 M4i8apDmNAN|KD;LFaQ7m diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/site-patch.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/site-patch.cpython-38.pyc deleted file mode 100644 index ca75805b1dba7df106f6971162df81c49b8f2d56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1478 zcmY*Z&2QsG6rUM8w&OTylcuFb9CARaa%hXXpxr~MK)Z<LQdZhU+lDR1>zO8Q9NU?h zZfP~Xka8~)e?WTVhBzTk{1Keygv0^ul_Q50ZydH-9L@NBzu)_azi2jn1kYbDe){T_ zhtQvfdGjH_d;~|l0~bXUU!ehFn36H!>kQ2hMqeUoJw|;y28-Kg6{tF#`*4I0Q7EP; zMdjj+ORVrInOl_H;F2gp(byBa3Z2^2g2?w25%-3uBw3)yyau+8v6HSs)K1XMDlM?} zWL=RN#QlzJpwb2_Z|=(mSk{#N03H8aI?7SCF%euj;%ds3HMf+B<SG|3*7>i>od>iA z5>I)R<QL`5n?{16vTHoup7P6Hg}qhQRoz%CXNYgeGpqE=Mj1Rs*}9G7(%9#J8y}30 z(3Bscj2t56o4WWbh|vXKh^u_nP{ECj(NpvR=;zBf;Bk1HOD<7ohQGzKO<n3;Ayef8 zG{ZAoHmmCE6hrkbiWLewia?dE(vd3)yehnh3fbtiqgr<n0SnnxHpLqd;Tb8H%4Lem zHuSZ#h<p4Te7nXMv@2y-b=C5iTx0&5Y8&K+f*yAudmD7kv2%^Z@3*=?RA;_w`iW82 z1$s@jfg>1!g?|?^LH~YGRW8^Zn9?5Huqlm$mu642|LEw+!_N;Mef;F1uAL{@on5_B zL~;}+lOpGm@i30!5!1FvB)fd~etwqHY*Y45l8pA`i1j#&(%z=gZuTZQJxf`PP2~R` zv%5B&$8f6s9YQ~kyCs%LK}RXt06Zt;dor~F6@F=a`&fIEXv_?bKG9_RJ#9n$$&ZMe zKgvHJ?#M~8QzXS!k_j25>DKP({j+cG<k5~`@~n_~o{ImG;JpRW;?Z_-q5Zuy5i-sv z#eUzQGVmOj)aBb@_&m?$_FkIDQ7ZO<cx|W~VaSF<$j7+kjsf|Ww#0?dBp2Fc*^7kd znYM;ZYOhEmd6M&qu8AT|q;^dqf)&~YbtEO%wvlKnWtnzq!n0_?v=@daNy@@dH%xQG zMKg6H&7)h!f~n}nXVqvv;XLQM7N@y@@z5leya~9pA5m(?0dcu&1Wr^GETh_4pzp8p z7Kr(hxy*P5R*}R5S4e754Qi7M<7z$}+IzhP+A%N~=jIcn9U)=t6TW7c8f7Bpx-ri3 z^DL}N)lQz$0vdzqfMj$~Ut|s=Ximn?D<h2yO|qhz=;CTrp%*hSYaqUc3t<m_0baun z2}poDI3R{6*atZrVh#a%9k(hO!Gv@xsR!=>{J@^H$TGIE4e|h_puvF^0L`}`2d}|( i&|ffS5N04@_y#t!cf11V?JWkgUqLjR;C<?02mcFWxqhes diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/ssl_support.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/ssl_support.cpython-38.pyc index f41d1cee22a5e0008d1177a14933e98b3eea8d0a..e74eeeefb803c9fba519a7a39d1990c1d0882e77 100644 GIT binary patch delta 309 zcmX?Y`rDK@l$V!_0SGw%?TU}z$Sc9(6r-P!pPQ;*R9RY@m8oA`l&qhUn3tKFlbl~v zl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2(-keHmEn4UV>lSP5iY;zXN113hB z$=>YBjO?59*|#yX6#*?OwwtWYtuDpH$iyi0pXomvGY^o(#K;9=vjAEDHz#njFfz`c zoXT^Jap`0m-aNs@AZ;8VS2D6NaxpUfo4lJhfpN}e89qry#<iQx_zRgBH%?w5*u%JL zvZ>HD#!HiVgwHbGo_tF<it*NFQ;{i*jISr365Yo5esZH&Bjc;d%;F7<k0-Z?e`5SS xxm;o;BkN{GNgqbWgvohQh8#c(7(i~ByiiI~(2PS%fKNb!i-Us`=tgl4E&zOvTG#*p delta 267 zcmexudfJpXl$V!_0SKO#ZHUv|$Sc93Vy9n{TcBT%S)iMlS6q^qlcQ^tVNzOQoS&#) zoLW*^P?DdYGdZ0_fzfnx2g?H{M(fF$?8=O+n|s-}F|*|ZjVd;p?8&Xp$HFA^kAs<q zk%fut9|z0kE^Zb^#@Unmd9E=ooSep+Cp;gdlmlcpBMT!J1JnO1g~<iH3X|FS>=<Wk zcH@&|WL&X1fxnQ6an0mQf<25&C&vq2V>~<AO!zG0waF|ZQH)nN$BRs1WPCRHi|97S zSCdzZH8MV(tSjEYcyIDL@lTB3CNGp&$;hzTThfP-F>3M*DMKa^=E)bOBn3@4GzEAC PG`Ki8IGGr^#5uSClafwc diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/unicode_utils.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/unicode_utils.cpython-38.pyc index c54a2966237127d2ff3571397e632d9b94b783be..4c4d2ddaff046881cfa0aecf1c5a3d9c12860e28 100644 GIT binary patch delta 93 zcmZqXT*%22%FD~e00f->cExYx31D=J)6dAyP1P@|EG^B-)Gsbd)=x>y%S_El&MzuS vE!L~3tkN$_%`4N-$xPBOs4U6I&okDu&@av`N!2Y#OwLYBPu<+W$jl4?ajG9m delta 63 zcmZ3;+04lk%FD~e00hs=HpFe@31C!l&@ag?&@ad=(9O&%E=kPE(KX62DXlQhPt-3? REh#N1$<NQ(Jdcr?830V!6czvg diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/version.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/version.cpython-38.pyc index c08a1a1301f6dcf84476a23091fe25017fd5772d..2b8eb383b86ccb7cfe937c24d2b9d3c137088918 100644 GIT binary patch delta 90 zcmZ3%bc~57l$V!_0SGw%?TVksbId71KO;XkRllgRv@|PIzqlw_KP53QGc_kUzo;a& sSg)e8O1~^MuS`EDGfBUovLquv&sfhwzc{lbRkt89IXf{ub>cT809l40Q~&?~ delta 61 zcmX@cw1SBzl$V!_0SKO#ZHSx5b4<lbza+OnzaX<fH#4ueBrzvP*C@lJw8A()QNK8~ Pq_m(UKR;)(2%`}IOn($3 diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/wheel.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/wheel.cpython-38.pyc index 4d963e1ddc3800068f4b3890d85f6004287c47bd..433be1c8003e4cefb810ee5e511248a7a9025aca 100644 GIT binary patch delta 2483 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 delta 2166 zcmZuyU2GLa6yDk0yLa#2pI-X^2fanxvJ~2;1zHfQAf+H!fePXpUANus?Y8%i*(oig zM4=>xMA0%2CK|Nm!AOjWr20lQKJlm~zPN8b>ANu)64Z01zcy~N-<&<?%*;98IWv1_ z|Lxw?xn$Ci;Q8&+S8sgMG@oiD-_Ez!ow5{{xJpj7R53=Zh!{0X6Jykhicz<8F~+Qz z7!AvSQO(8jaVt(FkR!Ro{0B9IMm}w&g+kA5$(LK@MDi-EN-w%l<;J||MD?OPQDfD* zhE?ar-NX&asvnfxq?@`Sxv4qXYH*cd$t;_H+*&?lk}z3vXyDnGJR11L0v{kvaiipw z_H^%MPB!2U`Ple~(aQ&n3_Sb^>3hkW8TCpmb0S|VQZ_(okuDo;yX3HO+s+)y*tRdM zw!NdRG?|@Zey+{z@Mf4-aD~^7Rp(uqrFOYYHk*LB$9<hFU+OIRrQLoZU`{T#yL)`k z)J#v&=?pwJRbs_rj$c!^k{14{+D4j}9;!Qu7K5oY&L2ev+gm{lBYB67j)!D2B$p_z zy9^n$=@41LXSRKa``YjIJJ+njPq?U<_W+-a_U(Kc%uHG!i_%Sr$?r&G1j-=a&}XFu zWl=gR%|T)3WMEU}zeJDopY&Zva2-<)<&Lh9uzMs-1yd#D$#ZR7cS9(#gITZO&6H^W zX_yme0IDQQI{#2N&mJ>XikdK)^_ac3MySFJMti|R_aTU|51^C*2$Ozbj~4S#2Y)2z zy$Gs61(0N&@awT_WG`0@v-dD)=n;gy2r@vZd)cgAaPr=Ub=Nqd1K@I&yT)H<aJkTc z;!qY$`)r(w#aciM5hI<Ud}S=u@?L(#qx3i^HkUwT<oW@FN{kgR@Gs-{Nh`M#HHXCX za@Px(Uw{mX1sj5LeM(RM&oZf%7O|ZG-A4FQ;z9j-W|%u&?hKTY{ATi4T$K9^exKxF zvZqocxSl1}A<LUn2T}$|QFs-2gVrTK6({O!Y@v$ZDy!ySm%SSw1OrVXMEJ?{@$Ijm zxE^K(KEni-F7GkNb(j<IZ_<ZI$p1)R>%K>ZphdL2Lnl2NDgmQ#4i)NM+)P!JI@31j zZ}HE!e7`@7dtkJtO#4utK$(Q;RVKi5%BS9jCZh+zh4Z`R&K{f*MzDJvQwdcp0L|el zlL%`hgvLSFA7$7?{kM5<#d(tBw<@-_yb4}d6019Ouo-4nQ=}(UAWe!5Kx6#JikfsB zMM2H;C>`aGDw@-26!QoLgd*Qj*-E1PT4hy(vCNw&i=Yv=qAq~N?^l}7F_a8({%sMp zpddmoqMMkoo`$GE1`RI*phs|un^nhRnoM*elf;vyx2uK;8RkD%AMHazO=V-3pkjsG zZ6Mzx^a2d)><B);<ELxh9NN%Z=u(a_4G>0iKrMFd3H;Kg3OT<pNoUbsDKuk#j=|Yz zh7VJtBJT_Q@0zZ<I`k2hxQ<c=;T*she6V(6+h-s#X@V@sv+y@ql&{L-OPQ4y3BAjI zsBIx5{Lk9%4DDYrXp1E1XX>oxs&n%D>8r}DvJhoDKU3GWuM<|g5?{RyJ4%;BGHu2- zaj~40g>k%w(8C|pwKR$PVAxhUUKl~i8TH^&ADwiv(0e1d>l=GS5^Ft0&x7+rc!PQX zN!Exg$^WQwf*7P4>QYNmq?QlYzwlNEn3r$2XHmjyhl-PY79~8NVFK<R=8wX;8ZWw{ z%z`7a$1-`FHs21jo`F|vuFE<;5na;_Ktm?Res~*XLcvdw%tqeSu+5~e<9=NTqRx2S zLz#MX2vwr5ucD;zI}L5y@lLd=*8Wg|_|efqN8r!U2)b$f*M??jccroYa62lVLU<1W ly8yRdDg1w95A}ojqC1uI`U!Xhy8u*~Uu<lNXsWJP{|nvM`D_3H diff --git a/venv/lib/python3.8/site-packages/setuptools/__pycache__/windows_support.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/__pycache__/windows_support.cpython-38.pyc index da477ec599a6aadebe2e3a0328f3bd515be2cb9b..78c3c9359762a458254b9435850d0e6c9e8e23f6 100644 GIT binary patch delta 92 zcmaFJ{-2#El$V!_0SGw%?TVksbImD1KO;XkRllgRv@|PIzqlw_KP53QGc_kUzo;a& uSg)e8O1~^MuS`EDGfBUovLquv&sfhwzc{lbRkt89IXf{ubu$~|Z6*NA4<N<> delta 62 zcmey*{*av~l$V!_0SKO#ZHSx5b4|rbza+OnzaX<fH#4ueBrzvP*C@lJw8A()QNK8~ Qq_m(UKR;))3gc}i0EAE#k^lez diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-38.pyc index 53f28fc31f171808407e7eacd33b12de9d2ca5fa..34ab5f7cebbfdae300b21697e15bdcd212f4969c 100644 GIT binary patch delta 90 zcmbQoxQCG^l$V!_0SGw%?TVksW9^ivpOK%Ns$W!DTAG!qUtE-|pOToDnVOTFUsRG> stXEN4rC*ksSEiqnnWSG(S(1^TXRK$TUz}Nzs#}nloSm4SIx*WA04%K^G5`Po delta 60 zcmdnPIFFGhl$V!_0SKO#ZHSx5W3A$>Uy@s(Uyxa#o0(T!l9-dDYm{M9T49`@s9&5~ OQd&@wpPw_a(-;6BeiQxx diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-38.pyc index 4c71bb659f431d8ac82cfec8142fd890a6c3c21c..ce8b493c9cce0afbd2388ed77341e89880169584 100644 GIT binary patch delta 111 zcmZ3yoaf+j9-dHMUM>b8;QY5Mek0EnS*IlZjQreG{i4d!(yUDV;-X~zl*GKu)STq} zqLS2Ny^6{z{j$`&GX0#)B>jTQl8pR3V?7J~;>?m%-GapA?8NlcW)``27CFZ4EOJch OuNb4Y>u@laa{~ZtCM8Y) delta 81 zcmX@OoM-WJ9-dHMUM>b8cwV+4ZX?eXSrr%klH3CQg3JQl%)H`~#GD*mqYRVM3gi4l k{o>S;(t?uw{G4VbxppNv#_dXSOzN)~Z*BMDU@qqd09Y*=^Z)<= diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/six.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/__pycache__/six.cpython-38.pyc index d72d8b1beca8789850c234bdec93e61834fc23db..87633008718db9ef0d0c80c1938af28f046f3691 100644 GIT binary patch delta 95 zcmaFAkFj?@BTpzVFBbz4aQ@pBzmaDKzf+8UMt*Lpeo<v<X;!9waZ$2<N@8ASYEE)~ xQAujCUPWb<epzZ>nSM@Yl72yDNk)F2v7Uu~ab`)XZb4#lc4B(!<`ewO{Q)yxBB=lX delta 65 zcmeC(&-i{HBTpzVFBbz4JTKc2w~=QCzlxoHNp69DL1uw&W?pegVor{(QHDurg>inO TesO9^X+cSTe$M7+{LB3T&M+5s diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__about__.py b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__about__.py index 95d330e..dc95138 100644 --- a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__about__.py +++ b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__about__.py @@ -4,18 +4,24 @@ from __future__ import absolute_import, division, print_function __all__ = [ - "__title__", "__summary__", "__uri__", "__version__", "__author__", - "__email__", "__license__", "__copyright__", + "__title__", + "__summary__", + "__uri__", + "__version__", + "__author__", + "__email__", + "__license__", + "__copyright__", ] __title__ = "packaging" __summary__ = "Core utilities for Python packages" __uri__ = "https://github.com/pypa/packaging" -__version__ = "16.8" +__version__ = "19.2" __author__ = "Donald Stufft and individual contributors" __email__ = "donald@stufft.io" __license__ = "BSD or Apache License, Version 2.0" -__copyright__ = "Copyright 2014-2016 %s" % __author__ +__copyright__ = "Copyright 2014-2019 %s" % __author__ diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__init__.py b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__init__.py index 5ee6220..a0cf67d 100644 --- a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__init__.py +++ b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__init__.py @@ -4,11 +4,23 @@ from __future__ import absolute_import, division, print_function from .__about__ import ( - __author__, __copyright__, __email__, __license__, __summary__, __title__, - __uri__, __version__ + __author__, + __copyright__, + __email__, + __license__, + __summary__, + __title__, + __uri__, + __version__, ) __all__ = [ - "__title__", "__summary__", "__uri__", "__version__", "__author__", - "__email__", "__license__", "__copyright__", + "__title__", + "__summary__", + "__uri__", + "__version__", + "__author__", + "__email__", + "__license__", + "__copyright__", ] diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-38.pyc index e53dba19cfec8ae8c79abbaf85aaaa5f26304cb8..09398433518eaf78847573b6739579f9a688f93c 100644 GIT binary patch delta 139 zcmX@Y`iPY`l$V!_0SGw%?TUY~kvE!=*;3DFayDZrqvhm>jPXu6`WgATsrp5grKMS! z`o%@b`YDNdnW;I+`9&qE#d;N$Rr+PAd1d-JnMwKul_eSZdB%Dc`o)<gsk#M;$=QkN asgqNf9OW6Akl_y&ZWcx$WCB7E$p`=&CniP! delta 109 zcmaFFdW4lXl$V!_0SKO#ZHT+DkvE!=*-X!3ayDZrquJz#jPWXd`X#vq`URN<x|w;! yC5bsXx<(l$r4`2ciTcH<C8Y%=`T04Mo0uHs8JHlD5lsJMVP#<iLM9*tk&FQC_Zsv7 diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-38.pyc index 24d9583196ad80fb3d8177cd00a37fc9106aa551..79cd6df659b075f349e6358dc8b8e5282636b942 100644 GIT binary patch delta 111 zcmZ3)a)5<5l$V!_0SGw%?TR<r$h&~iDO*1yKQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+FwiMMeif9wtT<_yYjn C_93PK delta 81 zcmX@WvWSH@l$V!_0SKO#ZHQys$h&}1#aF*1w?Mxjvp_d9uec;JCr8&P!=$vrI6qOp aIJKm-pd>#(XYzYS2SGL_1}J0%)Bgb2{uVm` diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-38.pyc index 4158f76734b6a46d127f71d353c4ee084b572e1a..948a5acbbd10d22f12503b6f85b12270678f75bf 100644 GIT binary patch delta 100 zcmcb{{)L@4l$V!_0SGw%?TSy_$oq=XDN8>iKQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+Fv&G?Nk|Bg<qv<{1FQ Cnj#+n delta 70 zcmeyuevO?sl$V!_0SKO#ZHSB6$oq;>#Yev+w?Mxjvp_d9uec;JCr8&P!=$vrI6qOp YIJKm-pd>#(XR{@f5+ft?<QV1|04g090{{R3 diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-38.pyc index 7da372c293a19a4a580cae6552bd7eaa06391239..1f90f677924108094d43de221592c2813295d681 100644 GIT binary patch delta 275 zcmX>j`bv~1l$V!_0SGw%?TX*X6VB+Ar=O9Zo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu zTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mo;tam(VUTE@_xoLMs6S} zKG~NkjFE5hUKa7myP13#1;H$N<_ty=Fl#<@7*GvJmY2nwQ3}YCm>kBbHaV7Ec5(m< zD@$s8yev?#m{DP}A?svD#>q!n?=Wgi7G;;8e2vjy@<%phMr|N3i&1ZK1A7LeA&^v< w%*heJXaZ!(Pp;$$W;6%0-f(y_T7g-ioSuxfVAeiPZ$^j7TwK0Db0fG)01T~DMgRZ+ delta 218 zcmaDQdPbBdl$V!_0SKO#ZHU{*6V9j-pkI<(pkI(#pqrUjT#}fRqid95Qd(i0pQvA) zT2fk2lAoV5c`2hgBj@D1jAe{GKvH~iHd7cQ|KvkV$&5mi)tKuUMJF#~&SjLCEW(n+ zC_TBHC7Drf@@<x4M#ahgtdkj;CO>Aq!>Bp=09z5G4v>@w>erZD#jeb#KY1Q|2BQ&> zRG6&J5x{5)WXVsS&JoOL0cL5ls7*HDRA#gW^NKk=8STKVJDlE(j*~UGe1T?{ag_i7 D&WJ%! diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-38.pyc index c584305408bcdf0736ed21078fe95a4d915d62c3..2140f866b92e5a89a5f5bd7a0c5490063c5c3cf3 100644 GIT binary patch delta 644 zcmYLGO=uHQ5Z-T_&1QF-bZt_bG_7d^mU?KmQjq$SN~<k`wOahE2MuYnn5}I#ZZ^df zR0@_}JlKx-gBF`hE8<1>AW9MGLA-cS5uxBwuqcA)Ma0GzbMOuC<Gt_Ad^2z6ecyDy z_qf+9b8JZ)&k_TVyoZF|F)eLQ=$ci?=f?~!XN_v9WX90PM@`GtbFmABDQ!~EOlsrC zh?XtbX*1Iq>(X+Dt+!{Bqvw)mb-E<P&`4+8yXmu#N0gmb(8e%KFJy`Kiu358x8iwp z(tgh^?4XaHDeR<S>6D_eQgR*!9?*((9o;k}4=V98%U9S3@@sGJ|GO2VhjJIKC<8b^ zQgsjD9IXBXq-ncv7A8IQorXpAH6tj{RLv@8DXyk5<1DEoz#Wom2}N3{oeNzpYc@0B z5D+~jo|iZHD)kR9P>)~7GA;XuaNqgmKLI?ZBXwW!(%G|l8d#_2^&jxYxe=6suT%`R z$v!5skL{dA??NZLQ?5m?EiU?sT#8ExGkl0E!p4}Ga^F>sa@)kgHJ>q&9oHxHjGeR% zGqZ*c%VhCuh^_OKXo#bR78;I)Eu%~ZDosyJ>Q;_9C+s|nrSA<b_(}e7D+120u!&GL zSOF>v;J_mQ6)x~xZOK(dtBw8a=gmq`*vek(sI}=bg3eOYy>dhPBXNZ3N~DjqrN<rI zRL5MDvQ%X#9*KTLG-Zyl)_fVRIql7df!lPkC5u<|ttA*@`Tp5&m!!IxiK<T(n7Jtu T9d>n>co*G_Mp%|7(Jg-gEBmk` delta 615 zcmYjNOK1~O6rJ;uOkQRt$uvpZd>oRBS_Ru+t%!syg0vv0rTC{*Y)G(?m_#$FQUr;h zZq!<D!3u?@8&?X-ECh8W7R2gO3ocxUA|e!BsR+h535f4-&wcN}J@?*MAAU3BJ>>N& zk~p8I9vn|T^zL(Q*qby@SCW-NrLRz`niIuh-@xQx?fmxgM6#MUYZbFxF4BUl9}&7B zr%0A-h>P1(Y!n=$_lk$c-M7$B-`r=gjk0_mgY=tEV<$~{j;UKkvnm(F8NKt&Ax&jv zznZdD)>dCAuhq<d?}mB>d#G2-fLR6Y6HuTL-&LHWRo^(KX@@_HI?el^VTQ)^NnE#{ z>sg>dy#c~qdJ>oo&e?8JK@vi87xX4$ln>@{k5+=CxNjMu!@wglJHKMZI?+`J*62g` zD&AU;!wT@7mLr=LO_cApjf(UmawKZH8|spjlXA|>EFzgW<<7Yl)C1BMnM%<J`{JN$ z(KNjDGJ249#d`3I#$ub`vo6KThy);f^wvNOA?R>|Nr9%5kzx$v4viY?5T%lF5r(y9 zEJ8>(;%Ox4ReT7Gw4{VPIz_c^+qD0Zb4n$W>P?}ZowaGkswGB%+qB$M8Tcra5aVcp zg%O6vH0Vwy35eG0k5krdxOIO!)5-NmMHrbTQ$z4E-44cESrgT=7(2u?2X`xB8M0X5 RAAZUj?~ol_<uT5A_g}|ok0$^C diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-38.pyc index 2aef246d896db06b50d8a6d4a42c02b62ff2d1d0..5de0a9014f3c53df980a86d230212225d8a1f893 100644 GIT binary patch delta 940 zcmYjPO-~b16n*#22h*V)OCh2Gv=n2&4+;ViNJROH7zGK0fD&j5GeT*ZHgARo%2bGe ziMqn~2U^@2H-?QNai@ui|A4r3<HD6IjREf~#yH76@4WlY+<WG}DV}?O-k1mkbb^oX z=pgnqv}@FY_x5s}hOOR0pIKi7Ah(GbF&nmt*<kf=Ne>51I!>A{?C;T!(3g%brkAZK zTU%LKN<<wtA2s84!b;7jnQJ-Ct82Mv*0QtFRAMfgS#uZDc3X32)JeG3)l7Uo8DFsY z3;73J=NpO%-TbSvWAvaI)`F0eR;Oq7nR*R2RKTs_k^*>8ggl)j_JB-Wn$+1Ckh}yW zchQwhD99do(vl*=q}61Ho+ZfDBHe-~FiARyiR#DF6nQ{wIz>FXROXRb8Lk@p;Q9(a z!LWnu$xFH^B`JG}*^P2fE`m5pO6&j|$)cRyC`9ZvqQ8W?b0D}Q6bf1?l@dz9u#IM` zCK0O}z>LAZ2rQf`qLl@*1$bh(LCjT@cm=W$`z>(Rrll7{Cc)9GBe|N<ICHG9#aNn! z<8C;z-crx<k?!z%YyO*tvpbX@B~n(d;*On-rxIp(V(eacA%Rzs3;vfveM`Qnl7G@# zl|yOSS>QjlI$d93sTDhe9e9<`X`jY&PCEht3I+rbWe5@Zm>!>2HBiA1I%aiTF(*O_ z@_k<yJm=qiL$iw>6sRc`B#(&6iXRG@kDcUktbg~LC7n{z`A&4ED(<rg_|0V_Ib|Bn z&aiqkl2dL8=f5D#H}!h_Z}#*?=;xpHNNrZQJyUY4Q59-2f*2w6sdJ@#?ov0Nv0;QJ zVEuyE{DWF#hgvMgtPG3Ap7GuC&hjB~dSAdO-!-c1SO@YE3`dMv1KF?DXqBaG(;(OU zui(c18~+Xj4uiwJV|NF~V&j9Oy}ZX5R69kLF1~HF!6JWW+`NM0B$Uu&nbIR!sse-h VF$^59dMryaXt?*&D(aVX=?`Z<=)eE~ delta 758 zcmXw0%}*0S6rVS{U8e2!iy)vPmWsv(2w$QSV=QW;q)4=cQ1OFQcZHUATW7b#)CCfd z3pX>KObl&2c;TSw*`qgaCLZ_)j9xu>tZ&x1oA;YHzxOrso6o14{o%z>C_wQ0vGMWo zpXlpwAMj5@dD?x87z0M)6)_U#^<8E8hCvrd@=WWHeu2SzqfWUxS}jyZ3YP8UOQn&C zwF|Wula>6aZ9288Q>m0hOZ^QO#Rs1O(?Zww{8w=ZA46yzXcMsg9ld(kAq{Y$37d3@ zSSgh_bUnc5fov*3>Ip|NprN|pDn*|(gZ7X;dYm+27j|HYOc4V!x0D>YPb``vE-h*< zS<!Iq;BOq(VA8|xs;d_Ld<QY$q2J!#mm7N@M<}wHOvKU-OEZXEoggwgKa|)AHL?9F z*#(T~P8hj}=SR?s@~;vt>eWRJf-<S|^`Tj7BVQ^Qac(}Z6}VY8EoV4h&2!s~o19m~ zFQ%XP$)pIe|EY`Fx%g^f!?cnyG2$OT$p@umXAzEAjhDRQBh7xgW|qai-yY6k#2!W< zKp_lKL=`&QwB4;T&_KsuZ6nvFl!@`cG}Og<;C3eGLW3GgLvcxwHBo%P8>2i`k5@h3 z|Bp9(QvN33owWJ7@4?Hl%}0Cy2iAS5IBrBNIDpSP89Wau@i3U^Ez2Wyc}HSYgFdt< zTBmp$d=i>Qp3fpAfv3b+q)VLA8ElDj`sH9+#xfG-L_zQCm98!2VW8^l7>n^K+$3*` zclvv{(wYhFL1;O8XC|9TXIB=|chllqI1QIXe`FG#iEQMWj&cy%RsoHQgGf(@g3>6u F@)x-{x&8nE diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-38.pyc index 1f0bac0e4450ad577c01920522467c3d568cf03b..b252aad949b6b6977f931ff2edf7d172c96c2e47 100644 GIT binary patch delta 1160 zcmX|9ZA@Eb6u#%}ZN0svmkV8imD@tt++=K2##aelI#6J9Y>SzTD8U6v1MT?owtUq^ z7KQ@C81q@88(A<}bU)N3*u_j@R6>k~ESd3##%+o5hjEFRVMxqA5PWYjyU9K8Ip;Ya z&wJi;^Ag>-M9OiyT^9IfU7tTO+%c!Tz^XgF?cJRruRhq@8wq=(deGb2+!YRW1iSTE zC|Wo$829#ty865w;TCVtV645ntGLkTjfP{PJw46Alg(|R#3{B!lz}>Nj@<BAU2vF} zXdAq;3lGeTv@5CoWSOTToPX+P@*yl;r$EAERf%di_z6+st}HU=i=0|CNsv-VB!ziQ zaW@uhTVS{U;B0(?nxqYdv45H6e^gO|wpIgWTnGf!kqIab)P`l{4~k$$Ey5$S6E5{M z^>XWLI*rD(Pw5P-=_53Tsq}uDgvIeXO=G~(PZzM_XruShu;nJrB%XF2Bf5scj2trI zV#XI~hmBUxa3L{~$+Bck1T#lXbPs>JX6Y|XWRI~G0k_@T5h-zDS<Avnt&&!8RhzN@ zW8`kqj29qR+ltppw<Tk)xJ%hXBW;SU35a+;PrYTt=5F>$(M%}MSs=p0oZ(b~IAY<5 zKoTkD#5=kEG}{Pwt{T3$7rzxdaIfgY9eqZi$8g$2Vtl3+vaGWW(aau;8=@?+EMfw~ z+}_V<1g*t+G>*~YN;;3l;!(PeLnZz88%BvFV;0X#7G8H-@quQ+9W4!a%B?tCVwcUw z1ig~C(ceX3NtU^tt6w5ex=7!^R5s@ZxAR3^;>T?z96iy~9gXRsj!<(nq+fu$)NPJ% z=ohS(U9&%U(vad>vf)Dc<*g$e*C)AnsW#uN7a7*GhB%9U-(L2Z@Uia=a$sjg4Nai4 zB9Gp~bVWg`Y!vhJK>k)unkn&Pg+}giZfEl=MHQ|H#-@?XrOHxBA5YjSUm?pb4(r2+ z_>a<M%=<M<!KUM`KTCa^C+VYx7&F8<i2IJ_OmlUIQB&oLK(fh2uH?U)b~Ak%YqC2r zyKk1rk3b;6mun~xr3$PDZqX4e?*E<|Fj?iJxA1LMKD~_lRXV+zXsJF$)P!H3`<-GK zsM(3-=O^e*t~Js*?620aQe)-&d%r3h&e|q^@o4RLoNr}akftzO*Ux4d{&tk%$N>*s zLFa)-_OA?zB4;QHOhD{lXXZzSCpieFkYtv~BJp8Z5^D!T#9y!F(2~t(gyixhiBMke yCKry^@1aqgsSm3cxmz~|sv8r~uR^WQgyZmbr%xRcOlpxN^K(d0Ws_u+(*FaIG&*kp delta 1114 zcmX|Ae@t6d6z+HXc)Y&Sw?YSHEd^wlNstr@D>UoEnB&JB3`J*R%zkAf0YX<SAWkuu z4F?$p*gn*S{WO~R$DE4KEuu4OX5zv~mKdWkS)z%VGts})#03NOUfg^q@7#0Gcg{WM ze($`GXR$a7YnR7kI^=WbxexXnPRv=4iqiJ*K%y_)*WFjqeW-t6e{XL^q^oA|`Re5U zaDV5(VBbJ8*=x^=1;EcvZ4QNuy8^7rSU@S;%mDNBYbal}{?b1|gzsm5j~K^{kFdp# zySzY?1mA_QmrPCgJ7n>GOSOP3Xt11F$Xd~LW_x}K?p0Wh!kk9h5@K2C8gwaQS>o%s z-r9#=j#`J2<cf6%DPHncF<;N+!`_$ilH7fcaVD}aVS>S&QB3nf&Jbpp?|T-fc-%K6 z&NyhaL>XIKi3{vmyNI{!+T16AE1bwHg5brx`Rtvli-)8#geFXn;jst(V@~|R<-mFT z&9lLAEb+I{gWOS&z%u6xP74S4RA@#x!QVrZLI;NnulT?F{~V`C3rmCPFw>gGhN3Uw zrnC6S8WXaTF2fu!U}^SDaXfp?v~p_FmjxsJLYP-0A>OSzU3x_M3skUMgOJqeLSGhX zO&3dAT5}u13ybrS4{?;e)g_XLsp?HQ%Nx~W?k`lTP^p3sL~~{10X`OW@wJ+b_=-1b z_TU7ILw-HgB}1;WdE+%K(jA?{Nq!a$>XhEp^nVdO(!R}qqVGv=c(L}=bw?FAA=Q&j zWf`d|wX0O>RgTm}M5dr!_acfIjy2*q?-rKeb)Jfq`+cgVZ8FeM<m|mqj{Qxn0HJZ| z-yr+FHz#sRV9E=7MHW)ywtLgl(4!Lm)4`s2yM9KM8zEYK+!xpMT8X62@m4(F`-(!2 zDK)0lB(=@$;VEfG)ZxX_aKLm15LkT`t0gO%c5l_yV5X)RaEI)v&F6s*hU@F`29x#u zXy?!MH*t{mmg_jg;f6Yl@^V8N68y0tg+9Au>oCyIn~&U<x9)1(z+2lU<REr6K7&bC zZY|(XjV_#%!9iv;?Z%rt(DXHImNy^3+nj11!ewT*?7}>Ew=8+SRo$wI(1b|y;PyoD zs`9M<D8hn~VL&$|LAoWh75mrioxl&=xnrTM?fx|lVdfex!zsmYm{O!AV0tC((lSGA yXsy68CR@96Psutd^#M|fsMI@3dHHyu?_}Hh+?aR7;qulPF1e04d@|W>1pft@0Ui7R diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-38.pyc index 3013c2bf5b14a9e93e7f65e95859ee6c35e6cd7f..807db05e732142efe1d95f71ed09597a6b5d93dc 100644 GIT binary patch literal 1469 zcmbVMO^+Kj7`8o=nPfIeOIuJ6Jq%DN(XuluapAC9A%T$Kuos{}pc>7Ny@|8)h3(01 zLiR%W1^j~KxEFo^KY^d%D-u#~J@<fk-`VtIffG*r#P<96_4}Ex27`dW=>7Fu^0Y(9 zAGmpSII#H$rv4m&6Haqd&@nC8m=(_0p?Jn}ckFV9yLqSZ#$Mr%eM*G8?()utj(gnW z{?B9_@GkGc?+#~QkWugi^pTNcZ=}b%${QmRS=5y>w#(&QYFU+bSSwkY<fJJx1N);V z6t6Hl{H&a(x#SOpYI**4vGl&%OQJ`+8S<VFT)QwohN*7?7_z3EuE>V1*@l2A?C2TY z150ivSz1=5%s}^2BuY%gxpj1NY&&^%Ce(;pw@eFhNz?%JJe$VTst~bSG|f!LT4ga$ zODXaUybwA%Uo7LfDCco5kK=k_rd9bt^kJ-}5qou-ou(6^V=YWmo2trnoB)|uD!!7* zauPR2<~phu_O)w<p$$Xyh5-<!ZUA0$8P74Rt;<hgvFsbNB9G|>`I?k>U1I2Ipzc$G zpB3@Qw-APJ$b?)#SZ0jVQ%8NeqHBk<wTmYkx}m^?6Vq9Hm}%Zw`&W4ddG{004IHOs zky(#-PkZW@R)Y(?9_Al-y)6%Qkr~tjuzqb>LHkayeTU3;TG{WdY^Rm&ypZ)<*`KYf z-^%(|G7fL8zz#_1VEI!J!uWD3bqL?NP>WE@LguLoO%-knCQ1@*RFb?O9ycbOraG)j z5kkgIE<!F(PJ|L=CUmRoOqywErXoB`7okLY$#bFGBPDW?YPc#Ug(ywbUQk$iOZUh9 zi#M14d*4U<quu+KSQ`B+S=eM6=NkYk@@RNLAz}0}eFzEqfpJLBB|W;NP>n`iGRvZU zOV8UXyaFr-+dG(uQk>W7@B!+=qIU@+%Lmu02SR~O6CLCg6uLf)UfeqRKX$2G@Qk{R z@Hzr^#!H*jUD)ozd}&QLsw-_EC`&)$VvY-U7jQICKHl{JY)8~pHnm<_*U%K!JE>HW z8q1VWSlHH`RkF1HHtg1^m9Q@AwGQaSeg)s)pTggIYddwSjQ)pp_RfDr27S?Q0T7ST zJ{_`vxlTZDx$gqr!`1W2)H}c$^=**ApOk5oND_t3r!b)k6QJ%Pyp4d4wJusetBP9Y mLiO+n+qYHpigj%i+oX06ii$V6I7Dq4oxj7n?4}bq-Ok?}ENfx_ delta 218 zcmdnXeVLgrl$V!_0SKO#ZHQaSIFV0=(P*N!yhJL?0@f7fg^W>bDJ&_hEeuiYDNMl( znrsuRj3=JW(gbPw<)vSeTcBT%S)iMlS6q^qlcQ^tVNzOQoS&#)oLW*^P?DdYGr5k@ zs*ne$x|j)M3sVt@t;unVD?UE0w4}5sH9o!wBvZr;B3OXLEvBN>TkOgCxdoXysYPrc jVUV68kd;UTH%KXmO>TZlX-=vgNMkWbtq2nbGZ!-ep++<b diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-38.pyc index 94b724baa24dd9cde37d2a8a6f77ffc0d0ca4ecc..b0c97008108b06a3fba2204b82a2c7ea884c2f20 100644 GIT binary patch delta 2819 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 EZ#hU`)Bpeg delta 1988 zcmbtVTWpk75dP=<m;LwJ-R-vYvfW<TUbgMF4TToDS3wEZRji6!q+9tLXuI8A&cD<O zErb+;(MTi{MIJD1d@w#}6nybTA545AA-*W7(S&GXAVvc*@$%4h=HCL9SGPIenKS2` zbLPy<KmF?98$*HT{eF)^zh9<4IT%lV8mLy|gWZM6e0P2<pB&5Dg^^4qx#q~)W7EC4 zk#2jma4cWQ<uW*?c0m=st9}b{%xOPDC#LlGp$G5kY3RnHyB4#?N$ACo-PLHg`eBWu z+v_?BeU9!9>DD>A?dC~%gmg9dgV_h`Nf*T)_bhB8-7~O})|X(bV{^sR4_h1?-HR}Q zm%P*7cJkd05|{#`z9gh^mv7i>g@%+wSh`7%^Lhn_{5I^uv;L!y!ax0&VK=@V$iQ<b z%JT3c+GRViA=spciGBcYgeK{f$HTkm)(hcIu<(m;o0>}aFkRm3Wscm&Fn|kfRS~{o zCk?xXz!auts^*o*41mPhifS0bixuzrZWZY#pJb~+9H?aV{>m-zES~n1>+488clAo; z_bSZb`I-}kRZh-FuI{P52yh*LkM_e(Y^^)zJ;3(+7*hCo-D|yHlW4CeP=pUO2&e*T zAPNFZFqeeJb9i~?weOBujz?mr;TGPGB~O`T_ZXk>8^K{^7G{)jWgIM+P-T1u=7lBZ z)sk)j7624Sr_O7ZX6a`XXGh<z%+a2+%hraaOt@vnVH(7A-DesPF<qw|>RS%gT)xO< zxvP~G$C(c2Gl%0@=9mw0+z#hwhvS`BEq2g%|62FGYuQDMT$&+gDZ2iYUjn`RAMHfX zY@^(X*P1tBPlKoKASoANT1IFtK?O@`f<F}8(=cHi<+bF@8La(F!J7>g5vh}W+|^}` zPSJ_SwGKkO-n?N2y`Jeh-D+zjXo^r09=Vo8>1WuBfyQpw&j)vKQh%jk#|RYAR3Ajt z7$J|U<)J~esA)Le*o4<syYWuE&HbT}y<|Z3aUocxZzj=$TbtJo50do%Q@kR6u9Oo# zndjR$dYe}~R8Nz36}GnYwG>E77%N}N1{)ZTF$5T<_|27DNDOdvoOUFZ-;5u$#7_y@ z;+Q$*8YiJZ<u?bjRID>FVaNu`KFO9?prWl-h7^lNLQTn6i0foVPLq@nvYw`WfvHhx zkL9w%c0rD14?mo1{=#e75rYIpn4p<(+>f_IF}&X5Z{xeiVO->c&aBQ+J;_>PCbUKE zWonJ3*OuY=raFBa=^L@Ob>nIuN%u@2n5gnq(w8hkPSOTw-HfldHc`h3W2~*eYm6Cv z44W9ZHsqrWoL|XdlmBf>(d3t;w3`S_p@9cHOPX%3rp6Q#;Gr(z@zKyr@*#oWG?!yp z;&KOvS8^+rI~blINQgyMj!rFtlp$v+U*N3+_+6q|&yd)T(4K${cC`N;E^U=){2j?s ze@m0N8&e(Y+qicvRu5-#hek5P_meQ1AC)78oU~<%_7fn(To0=zX)(xY;6|lT4yd^< z$w|D?aTjc2tfD6UQ)jk{ODvU8We?5LX_1^a`4S%zN|Sho4{<&@A&U5BvL5!~N6BtD z!i<esV(ei?CkcunsF7-5fUzWsT2b>?0fmh|Kobm}1v%k1g;+9mnZ>%Uce<V;EBQ3T z5Cb=J>1ANIC5K3!W8mkI$<3~oLH>6Up}OKH`7}X|!1*g`x<<`Au%sELFK7f~!A4pu X<c0o#W9VkcjA{+R3A5g#n%;i_0gb6E diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/_compat.py b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/_compat.py index 210bb80..25da473 100644 --- a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/_compat.py +++ b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/_compat.py @@ -12,9 +12,9 @@ PY3 = sys.version_info[0] == 3 # flake8: noqa if PY3: - string_types = str, + string_types = (str,) else: - string_types = basestring, + string_types = (basestring,) def with_metaclass(meta, *bases): @@ -27,4 +27,5 @@ def with_metaclass(meta, *bases): class metaclass(meta): def __new__(cls, name, this_bases, d): return meta(name, bases, d) - return type.__new__(metaclass, 'temporary_class', (), {}) + + return type.__new__(metaclass, "temporary_class", (), {}) diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/_structures.py b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/_structures.py index ccc2786..68dcca6 100644 --- a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/_structures.py +++ b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/_structures.py @@ -5,7 +5,6 @@ from __future__ import absolute_import, division, print_function class Infinity(object): - def __repr__(self): return "Infinity" @@ -33,11 +32,11 @@ class Infinity(object): def __neg__(self): return NegativeInfinity + Infinity = Infinity() class NegativeInfinity(object): - def __repr__(self): return "-Infinity" @@ -65,4 +64,5 @@ class NegativeInfinity(object): def __neg__(self): return Infinity + NegativeInfinity = NegativeInfinity() diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/markers.py b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/markers.py index 031332a..4bdfdb2 100644 --- a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/markers.py +++ b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/markers.py @@ -17,8 +17,11 @@ from .specifiers import Specifier, InvalidSpecifier __all__ = [ - "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName", - "Marker", "default_environment", + "InvalidMarker", + "UndefinedComparison", + "UndefinedEnvironmentName", + "Marker", + "default_environment", ] @@ -42,7 +45,6 @@ class UndefinedEnvironmentName(ValueError): class Node(object): - def __init__(self, value): self.value = value @@ -57,62 +59,52 @@ class Node(object): class Variable(Node): - def serialize(self): return str(self) class Value(Node): - def serialize(self): return '"{0}"'.format(self) class Op(Node): - def serialize(self): return str(self) VARIABLE = ( - L("implementation_version") | - L("platform_python_implementation") | - L("implementation_name") | - L("python_full_version") | - L("platform_release") | - L("platform_version") | - L("platform_machine") | - L("platform_system") | - L("python_version") | - L("sys_platform") | - L("os_name") | - L("os.name") | # PEP-345 - L("sys.platform") | # PEP-345 - L("platform.version") | # PEP-345 - L("platform.machine") | # PEP-345 - L("platform.python_implementation") | # PEP-345 - L("python_implementation") | # undocumented setuptools legacy - L("extra") + L("implementation_version") + | L("platform_python_implementation") + | L("implementation_name") + | L("python_full_version") + | L("platform_release") + | L("platform_version") + | L("platform_machine") + | L("platform_system") + | L("python_version") + | L("sys_platform") + | L("os_name") + | L("os.name") + | L("sys.platform") # PEP-345 + | L("platform.version") # PEP-345 + | L("platform.machine") # PEP-345 + | L("platform.python_implementation") # PEP-345 + | L("python_implementation") # PEP-345 + | L("extra") # undocumented setuptools legacy ) ALIASES = { - 'os.name': 'os_name', - 'sys.platform': 'sys_platform', - 'platform.version': 'platform_version', - 'platform.machine': 'platform_machine', - 'platform.python_implementation': 'platform_python_implementation', - 'python_implementation': 'platform_python_implementation' + "os.name": "os_name", + "sys.platform": "sys_platform", + "platform.version": "platform_version", + "platform.machine": "platform_machine", + "platform.python_implementation": "platform_python_implementation", + "python_implementation": "platform_python_implementation", } VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) VERSION_CMP = ( - L("===") | - L("==") | - L(">=") | - L("<=") | - L("!=") | - L("~=") | - L(">") | - L("<") + L("===") | L("==") | L(">=") | L("<=") | L("!=") | L("~=") | L(">") | L("<") ) MARKER_OP = VERSION_CMP | L("not in") | L("in") @@ -152,8 +144,11 @@ def _format_marker(marker, first=True): # where the single item is itself it's own list. In that case we want skip # the rest of this function so that we don't get extraneous () on the # outside. - if (isinstance(marker, list) and len(marker) == 1 and - isinstance(marker[0], (list, tuple))): + if ( + isinstance(marker, list) + and len(marker) == 1 + and isinstance(marker[0], (list, tuple)) + ): return _format_marker(marker[0]) if isinstance(marker, list): @@ -239,20 +234,20 @@ def _evaluate_markers(markers, environment): def format_full_version(info): - version = '{0.major}.{0.minor}.{0.micro}'.format(info) + version = "{0.major}.{0.minor}.{0.micro}".format(info) kind = info.releaselevel - if kind != 'final': + if kind != "final": version += kind[0] + str(info.serial) return version def default_environment(): - if hasattr(sys, 'implementation'): + if hasattr(sys, "implementation"): iver = format_full_version(sys.implementation.version) implementation_name = sys.implementation.name else: - iver = '0' - implementation_name = '' + iver = "0" + implementation_name = "" return { "implementation_name": implementation_name, @@ -264,19 +259,19 @@ def default_environment(): "platform_version": platform.version(), "python_full_version": platform.python_version(), "platform_python_implementation": platform.python_implementation(), - "python_version": platform.python_version()[:3], + "python_version": ".".join(platform.python_version_tuple()[:2]), "sys_platform": sys.platform, } class Marker(object): - def __init__(self, marker): try: self._markers = _coerce_parse_result(MARKER.parseString(marker)) except ParseException as e: err_str = "Invalid marker: {0!r}, parse error at {1!r}".format( - marker, marker[e.loc:e.loc + 8]) + marker, marker[e.loc : e.loc + 8] + ) raise InvalidMarker(err_str) def __str__(self): diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/requirements.py b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/requirements.py index 5b49341..8a0c2cb 100644 --- a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/requirements.py +++ b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/requirements.py @@ -38,8 +38,8 @@ IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) NAME = IDENTIFIER("name") EXTRA = IDENTIFIER -URI = Regex(r'[^ ]+')("url") -URL = (AT + URI) +URI = Regex(r"[^ ]+")("url") +URL = AT + URI EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") @@ -48,28 +48,31 @@ VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY -VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), - joinString=",", adjacent=False)("_raw_spec") +VERSION_MANY = Combine( + VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), joinString=",", adjacent=False +)("_raw_spec") _VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) -_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '') +_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or "") VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") MARKER_EXPR.setParseAction( - lambda s, l, t: Marker(s[t._original_start:t._original_end]) + lambda s, l, t: Marker(s[t._original_start : t._original_end]) ) -MARKER_SEPERATOR = SEMICOLON -MARKER = MARKER_SEPERATOR + MARKER_EXPR +MARKER_SEPARATOR = SEMICOLON +MARKER = MARKER_SEPARATOR + MARKER_EXPR VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) URL_AND_MARKER = URL + Optional(MARKER) -NAMED_REQUIREMENT = \ - NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) +NAMED_REQUIREMENT = NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd +# setuptools.extern.pyparsing isn't thread safe during initialization, so we do it eagerly, see +# issue #104 +REQUIREMENT.parseString("x[]") class Requirement(object): @@ -90,15 +93,21 @@ class Requirement(object): req = REQUIREMENT.parseString(requirement_string) except ParseException as e: raise InvalidRequirement( - "Invalid requirement, parse error at \"{0!r}\"".format( - requirement_string[e.loc:e.loc + 8])) + 'Parse error at "{0!r}": {1}'.format( + requirement_string[e.loc : e.loc + 8], e.msg + ) + ) self.name = req.name if req.url: parsed_url = urlparse.urlparse(req.url) - if not (parsed_url.scheme and parsed_url.netloc) or ( - not parsed_url.scheme and not parsed_url.netloc): - raise InvalidRequirement("Invalid URL given") + if parsed_url.scheme == "file": + if urlparse.urlunparse(parsed_url) != req.url: + raise InvalidRequirement("Invalid URL given") + elif not (parsed_url.scheme and parsed_url.netloc) or ( + not parsed_url.scheme and not parsed_url.netloc + ): + raise InvalidRequirement("Invalid URL: {0}".format(req.url)) self.url = req.url else: self.url = None @@ -117,6 +126,8 @@ class Requirement(object): if self.url: parts.append("@ {0}".format(self.url)) + if self.marker: + parts.append(" ") if self.marker: parts.append("; {0}".format(self.marker)) diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/specifiers.py b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/specifiers.py index 7f5a76c..743576a 100644 --- a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/specifiers.py +++ b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/specifiers.py @@ -19,7 +19,6 @@ class InvalidSpecifier(ValueError): class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): - @abc.abstractmethod def __str__(self): """ @@ -84,10 +83,7 @@ class _IndividualSpecifier(BaseSpecifier): if not match: raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec)) - self._spec = ( - match.group("operator").strip(), - match.group("version").strip(), - ) + self._spec = (match.group("operator").strip(), match.group("version").strip()) # Store whether or not this Specifier should accept prereleases self._prereleases = prereleases @@ -99,11 +95,7 @@ class _IndividualSpecifier(BaseSpecifier): else "" ) - return "<{0}({1!r}{2})>".format( - self.__class__.__name__, - str(self), - pre, - ) + return "<{0}({1!r}{2})>".format(self.__class__.__name__, str(self), pre) def __str__(self): return "{0}{1}".format(*self._spec) @@ -194,11 +186,12 @@ class _IndividualSpecifier(BaseSpecifier): # If our version is a prerelease, and we were not set to allow # prereleases, then we'll store it for later incase nothing # else matches this specifier. - if (parsed_version.is_prerelease and not - (prereleases or self.prereleases)): + if parsed_version.is_prerelease and not ( + prereleases or self.prereleases + ): found_prereleases.append(version) # Either this is not a prerelease, or we should have been - # accepting prereleases from the begining. + # accepting prereleases from the beginning. else: yielded = True yield version @@ -213,8 +206,7 @@ class _IndividualSpecifier(BaseSpecifier): class LegacySpecifier(_IndividualSpecifier): - _regex_str = ( - r""" + _regex_str = r""" (?P<operator>(==|!=|<=|>=|<|>)) \s* (?P<version> @@ -225,10 +217,8 @@ class LegacySpecifier(_IndividualSpecifier): # them, and a comma since it's a version separator. ) """ - ) - _regex = re.compile( - r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) _operators = { "==": "equal", @@ -269,13 +259,13 @@ def _require_version_compare(fn): if not isinstance(prospective, Version): return False return fn(self, prospective, spec) + return wrapped class Specifier(_IndividualSpecifier): - _regex_str = ( - r""" + _regex_str = r""" (?P<operator>(~=|==|!=|<=|>=|<|>|===)) (?P<version> (?: @@ -367,10 +357,8 @@ class Specifier(_IndividualSpecifier): ) ) """ - ) - _regex = re.compile( - r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + _regex = re.compile(r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) _operators = { "~=": "compatible", @@ -397,8 +385,7 @@ class Specifier(_IndividualSpecifier): prefix = ".".join( list( itertools.takewhile( - lambda x: (not x.startswith("post") and not - x.startswith("dev")), + lambda x: (not x.startswith("post") and not x.startswith("dev")), _version_split(spec), ) )[:-1] @@ -407,8 +394,9 @@ class Specifier(_IndividualSpecifier): # Add the prefix notation to the end of our string prefix += ".*" - return (self._get_operator(">=")(prospective, spec) and - self._get_operator("==")(prospective, prefix)) + return self._get_operator(">=")(prospective, spec) and self._get_operator("==")( + prospective, prefix + ) @_require_version_compare def _compare_equal(self, prospective, spec): @@ -428,7 +416,7 @@ class Specifier(_IndividualSpecifier): # Shorten the prospective version to be the same length as the spec # so that we can determine if the specifier is a prefix of the # prospective version or not. - prospective = prospective[:len(spec)] + prospective = prospective[: len(spec)] # Pad out our two sides with zeros so that they both equal the same # length. @@ -503,7 +491,7 @@ class Specifier(_IndividualSpecifier): return False # Ensure that we do not allow a local version of the version mentioned - # in the specifier, which is techincally greater than, to match. + # in the specifier, which is technically greater than, to match. if prospective.local is not None: if Version(prospective.base_version) == Version(spec.base_version): return False @@ -567,27 +555,17 @@ def _pad_version(left, right): right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right))) # Get the rest of our versions - left_split.append(left[len(left_split[0]):]) - right_split.append(right[len(right_split[0]):]) + left_split.append(left[len(left_split[0]) :]) + right_split.append(right[len(right_split[0]) :]) # Insert our padding - left_split.insert( - 1, - ["0"] * max(0, len(right_split[0]) - len(left_split[0])), - ) - right_split.insert( - 1, - ["0"] * max(0, len(left_split[0]) - len(right_split[0])), - ) + left_split.insert(1, ["0"] * max(0, len(right_split[0]) - len(left_split[0]))) + right_split.insert(1, ["0"] * max(0, len(left_split[0]) - len(right_split[0]))) - return ( - list(itertools.chain(*left_split)), - list(itertools.chain(*right_split)), - ) + return (list(itertools.chain(*left_split)), list(itertools.chain(*right_split))) class SpecifierSet(BaseSpecifier): - def __init__(self, specifiers="", prereleases=None): # Split on , to break each indidivual specifier into it's own item, and # strip each item to remove leading/trailing whitespace. @@ -721,10 +699,7 @@ class SpecifierSet(BaseSpecifier): # given version is contained within all of them. # Note: This use of all() here means that an empty set of specifiers # will always return True, this is an explicit design decision. - return all( - s.contains(item, prereleases=prereleases) - for s in self._specs - ) + return all(s.contains(item, prereleases=prereleases) for s in self._specs) def filter(self, iterable, prereleases=None): # Determine if we're forcing a prerelease or not, if we're not forcing diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/utils.py b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/utils.py index 942387c..8841878 100644 --- a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/utils.py +++ b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/utils.py @@ -5,6 +5,8 @@ from __future__ import absolute_import, division, print_function import re +from .version import InvalidVersion, Version + _canonicalize_regex = re.compile(r"[-_.]+") @@ -12,3 +14,44 @@ _canonicalize_regex = re.compile(r"[-_.]+") def canonicalize_name(name): # This is taken from PEP 503. return _canonicalize_regex.sub("-", name).lower() + + +def canonicalize_version(version): + """ + This is very similar to Version.__str__, but has one subtle differences + with the way it handles the release segment. + """ + + try: + version = Version(version) + except InvalidVersion: + # Legacy versions cannot be normalized + return version + + parts = [] + + # Epoch + if version.epoch != 0: + parts.append("{0}!".format(version.epoch)) + + # Release segment + # NB: This strips trailing '.0's to normalize + parts.append(re.sub(r"(\.0)+$", "", ".".join(str(x) for x in version.release))) + + # Pre-release + if version.pre is not None: + parts.append("".join(str(x) for x in version.pre)) + + # Post-release + if version.post is not None: + parts.append(".post{0}".format(version.post)) + + # Development release + if version.dev is not None: + parts.append(".dev{0}".format(version.dev)) + + # Local version segment + if version.local is not None: + parts.append("+{0}".format(version.local)) + + return "".join(parts) diff --git a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/version.py b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/version.py index 83b5ee8..95157a1 100644 --- a/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/version.py +++ b/venv/lib/python3.8/site-packages/setuptools/_vendor/packaging/version.py @@ -10,14 +10,11 @@ import re from ._structures import Infinity -__all__ = [ - "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN" -] +__all__ = ["parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN"] _Version = collections.namedtuple( - "_Version", - ["epoch", "release", "dev", "pre", "post", "local"], + "_Version", ["epoch", "release", "dev", "pre", "post", "local"] ) @@ -40,7 +37,6 @@ class InvalidVersion(ValueError): class _BaseVersion(object): - def __hash__(self): return hash(self._key) @@ -70,7 +66,6 @@ class _BaseVersion(object): class LegacyVersion(_BaseVersion): - def __init__(self, version): self._version = str(version) self._key = _legacy_cmpkey(self._version) @@ -89,6 +84,26 @@ class LegacyVersion(_BaseVersion): def base_version(self): return self._version + @property + def epoch(self): + return -1 + + @property + def release(self): + return None + + @property + def pre(self): + return None + + @property + def post(self): + return None + + @property + def dev(self): + return None + @property def local(self): return None @@ -101,13 +116,19 @@ class LegacyVersion(_BaseVersion): def is_postrelease(self): return False + @property + def is_devrelease(self): + return False -_legacy_version_component_re = re.compile( - r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, -) + +_legacy_version_component_re = re.compile(r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE) _legacy_version_replacement_map = { - "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", + "pre": "c", + "preview": "c", + "-": "final-", + "rc": "c", + "dev": "@", } @@ -154,6 +175,7 @@ def _legacy_cmpkey(version): return epoch, parts + # Deliberately not anchored to the start and end of the string, to make it # easier for 3rd party code to reuse VERSION_PATTERN = r""" @@ -190,10 +212,7 @@ VERSION_PATTERN = r""" class Version(_BaseVersion): - _regex = re.compile( - r"^\s*" + VERSION_PATTERN + r"\s*$", - re.VERBOSE | re.IGNORECASE, - ) + _regex = re.compile(r"^\s*" + VERSION_PATTERN + r"\s*$", re.VERBOSE | re.IGNORECASE) def __init__(self, version): # Validate the version and parse it into pieces @@ -205,18 +224,11 @@ class Version(_BaseVersion): self._version = _Version( epoch=int(match.group("epoch")) if match.group("epoch") else 0, release=tuple(int(i) for i in match.group("release").split(".")), - pre=_parse_letter_version( - match.group("pre_l"), - match.group("pre_n"), - ), + pre=_parse_letter_version(match.group("pre_l"), match.group("pre_n")), post=_parse_letter_version( - match.group("post_l"), - match.group("post_n1") or match.group("post_n2"), - ), - dev=_parse_letter_version( - match.group("dev_l"), - match.group("dev_n"), + match.group("post_l"), match.group("post_n1") or match.group("post_n2") ), + dev=_parse_letter_version(match.group("dev_l"), match.group("dev_n")), local=_parse_local_version(match.group("local")), ) @@ -237,32 +249,57 @@ class Version(_BaseVersion): parts = [] # Epoch - if self._version.epoch != 0: - parts.append("{0}!".format(self._version.epoch)) + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) # Release segment - parts.append(".".join(str(x) for x in self._version.release)) + parts.append(".".join(str(x) for x in self.release)) # Pre-release - if self._version.pre is not None: - parts.append("".join(str(x) for x in self._version.pre)) + if self.pre is not None: + parts.append("".join(str(x) for x in self.pre)) # Post-release - if self._version.post is not None: - parts.append(".post{0}".format(self._version.post[1])) + if self.post is not None: + parts.append(".post{0}".format(self.post)) # Development release - if self._version.dev is not None: - parts.append(".dev{0}".format(self._version.dev[1])) + if self.dev is not None: + parts.append(".dev{0}".format(self.dev)) # Local version segment - if self._version.local is not None: - parts.append( - "+{0}".format(".".join(str(x) for x in self._version.local)) - ) + if self.local is not None: + parts.append("+{0}".format(self.local)) return "".join(parts) + @property + def epoch(self): + return self._version.epoch + + @property + def release(self): + return self._version.release + + @property + def pre(self): + return self._version.pre + + @property + def post(self): + return self._version.post[1] if self._version.post else None + + @property + def dev(self): + return self._version.dev[1] if self._version.dev else None + + @property + def local(self): + if self._version.local: + return ".".join(str(x) for x in self._version.local) + else: + return None + @property def public(self): return str(self).split("+", 1)[0] @@ -272,27 +309,25 @@ class Version(_BaseVersion): parts = [] # Epoch - if self._version.epoch != 0: - parts.append("{0}!".format(self._version.epoch)) + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) # Release segment - parts.append(".".join(str(x) for x in self._version.release)) + parts.append(".".join(str(x) for x in self.release)) return "".join(parts) - @property - def local(self): - version_string = str(self) - if "+" in version_string: - return version_string.split("+", 1)[1] - @property def is_prerelease(self): - return bool(self._version.dev or self._version.pre) + return self.dev is not None or self.pre is not None @property def is_postrelease(self): - return bool(self._version.post) + return self.post is not None + + @property + def is_devrelease(self): + return self.dev is not None def _parse_letter_version(letter, number): @@ -326,7 +361,7 @@ def _parse_letter_version(letter, number): return letter, int(number) -_local_version_seperators = re.compile(r"[\._-]") +_local_version_separators = re.compile(r"[\._-]") def _parse_local_version(local): @@ -336,7 +371,7 @@ def _parse_local_version(local): if local is not None: return tuple( part.lower() if not part.isdigit() else int(part) - for part in _local_version_seperators.split(local) + for part in _local_version_separators.split(local) ) @@ -347,12 +382,7 @@ def _cmpkey(epoch, release, pre, post, dev, local): # re-reverse it back into the correct order and make it a tuple and use # that for our sorting key. release = tuple( - reversed(list( - itertools.dropwhile( - lambda x: x == 0, - reversed(release), - ) - )) + reversed(list(itertools.dropwhile(lambda x: x == 0, reversed(release)))) ) # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0. @@ -385,9 +415,6 @@ def _cmpkey(epoch, release, pre, post, dev, local): # - Numeric segments sort numerically # - Shorter versions sort before longer versions when the prefixes # match exactly - local = tuple( - (i, "") if isinstance(i, int) else (-Infinity, i) - for i in local - ) + local = tuple((i, "") if isinstance(i, int) else (-Infinity, i) for i in local) return epoch, release, pre, post, dev, local diff --git a/venv/lib/python3.8/site-packages/setuptools/archive_util.py b/venv/lib/python3.8/site-packages/setuptools/archive_util.py index 8143604..0ce190b 100644 --- a/venv/lib/python3.8/site-packages/setuptools/archive_util.py +++ b/venv/lib/python3.8/site-packages/setuptools/archive_util.py @@ -25,7 +25,8 @@ def default_filter(src, dst): return dst -def unpack_archive(filename, extract_dir, progress_filter=default_filter, +def unpack_archive( + filename, extract_dir, progress_filter=default_filter, drivers=None): """Unpack `filename` to `extract_dir`, or raise ``UnrecognizedFormat`` @@ -133,10 +134,10 @@ def unpack_tarfile(filename, extract_dir, progress_filter=default_filter): """ try: tarobj = tarfile.open(filename) - except tarfile.TarError: + except tarfile.TarError as e: raise UnrecognizedFormat( "%s is not a compressed or uncompressed tar file" % (filename,) - ) + ) from e with contextlib.closing(tarobj): # don't do any chowning! tarobj.chown = lambda *args: None @@ -148,7 +149,8 @@ def unpack_tarfile(filename, extract_dir, progress_filter=default_filter): # resolve any links and to extract the link targets as normal # files - while member is not None and (member.islnk() or member.issym()): + while member is not None and ( + member.islnk() or member.issym()): linkpath = member.linkname if member.issym(): base = posixpath.dirname(member.name) diff --git a/venv/lib/python3.8/site-packages/setuptools/build_meta.py b/venv/lib/python3.8/site-packages/setuptools/build_meta.py index 10c4b52..4626681 100644 --- a/venv/lib/python3.8/site-packages/setuptools/build_meta.py +++ b/venv/lib/python3.8/site-packages/setuptools/build_meta.py @@ -38,7 +38,6 @@ import distutils from setuptools.py31compat import TemporaryDirectory from pkg_resources import parse_requirements -from pkg_resources.py31compat import makedirs __all__ = ['get_requires_for_build_sdist', 'get_requires_for_build_wheel', @@ -48,6 +47,7 @@ __all__ = ['get_requires_for_build_sdist', '__legacy__', 'SetupRequirementsError'] + class SetupRequirementsError(BaseException): def __init__(self, specifiers): self.specifiers = specifiers @@ -143,7 +143,8 @@ class _BuildMetaBackend(object): def get_requires_for_build_wheel(self, config_settings=None): config_settings = self._fix_config(config_settings) - return self._get_build_requires(config_settings, requirements=['wheel']) + return self._get_build_requires( + config_settings, requirements=['wheel']) def get_requires_for_build_sdist(self, config_settings=None): config_settings = self._fix_config(config_settings) @@ -160,8 +161,10 @@ class _BuildMetaBackend(object): dist_infos = [f for f in os.listdir(dist_info_directory) if f.endswith('.dist-info')] - if (len(dist_infos) == 0 and - len(_get_immediate_subdirectories(dist_info_directory)) == 1): + if ( + len(dist_infos) == 0 and + len(_get_immediate_subdirectories(dist_info_directory)) == 1 + ): dist_info_directory = os.path.join( dist_info_directory, os.listdir(dist_info_directory)[0]) @@ -186,14 +189,15 @@ class _BuildMetaBackend(object): result_directory = os.path.abspath(result_directory) # Build in a temporary directory, then copy to the target. - makedirs(result_directory, exist_ok=True) + os.makedirs(result_directory, exist_ok=True) with TemporaryDirectory(dir=result_directory) as tmp_dist_dir: sys.argv = (sys.argv[:1] + setup_command + ['--dist-dir', tmp_dist_dir] + config_settings["--global-option"]) self.run_setup() - result_basename = _file_with_extension(tmp_dist_dir, result_extension) + result_basename = _file_with_extension( + tmp_dist_dir, result_extension) result_path = os.path.join(result_directory, result_basename) if os.path.exists(result_path): # os.rename will fail overwriting on non-Unix. @@ -202,7 +206,6 @@ class _BuildMetaBackend(object): return result_basename - def build_wheel(self, wheel_directory, config_settings=None, metadata_directory=None): return self._build_with_temp_dir(['bdist_wheel'], '.whl', @@ -217,9 +220,12 @@ class _BuildMetaBackend(object): class _BuildMetaLegacyBackend(_BuildMetaBackend): """Compatibility backend for setuptools - This is a version of setuptools.build_meta that endeavors to maintain backwards - compatibility with pre-PEP 517 modes of invocation. It exists as a temporary - bridge between the old packaging mechanism and the new packaging mechanism, + This is a version of setuptools.build_meta that endeavors + to maintain backwards + compatibility with pre-PEP 517 modes of invocation. It + exists as a temporary + bridge between the old packaging mechanism and the new + packaging mechanism, and will eventually be removed. """ def run_setup(self, setup_script='setup.py'): @@ -232,6 +238,12 @@ class _BuildMetaLegacyBackend(_BuildMetaBackend): if script_dir not in sys.path: sys.path.insert(0, script_dir) + # Some setup.py scripts (e.g. in pygame and numpy) use sys.argv[0] to + # get the directory of the source code. They expect it to refer to the + # setup.py script. + sys_argv_0 = sys.argv[0] + sys.argv[0] = setup_script + try: super(_BuildMetaLegacyBackend, self).run_setup(setup_script=setup_script) @@ -242,6 +254,8 @@ class _BuildMetaLegacyBackend(_BuildMetaBackend): # the original path so that the path manipulation does not persist # within the hook after run_setup is called. sys.path[:] = sys_path + sys.argv[0] = sys_argv_0 + # The primary backend _BACKEND = _BuildMetaBackend() diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__init__.py b/venv/lib/python3.8/site-packages/setuptools/command/__init__.py index fe619e2..743f558 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/__init__.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/__init__.py @@ -2,8 +2,7 @@ __all__ = [ 'alias', 'bdist_egg', 'bdist_rpm', 'build_ext', 'build_py', 'develop', 'easy_install', 'egg_info', 'install', 'install_lib', 'rotate', 'saveopts', 'sdist', 'setopt', 'test', 'install_egg_info', 'install_scripts', - 'register', 'bdist_wininst', 'upload_docs', 'upload', 'build_clib', - 'dist_info', + 'bdist_wininst', 'upload_docs', 'build_clib', 'dist_info', ] from distutils.command.bdist import bdist diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/__init__.cpython-38.pyc index 83a282daa693f4648c59d98e3ef1e8b1800f9dd6..9563da55ef1c6f987c23257d673bdaa56282e951 100644 GIT binary patch delta 250 zcmaFH`ifOMl$V!_0SGw%?TWWxVqka-;vfT2AjbiSi_0cz>-wdOMlqy_rikS*<}yVw zF@o6QIm}VaKw2V)C6_gd6(}Z|%9O>H&0dt3A_Zizr%2i`fJ7E>q)0AgWMqhDie^p` z4`$Gmp15ku<P1ic$vuqujKY)uF#7t418ph-5x)}kGxBp&^@}P?OS3Zdi;I%=Qxfws zQ*)B@i%L?9^(rc>^vhE7%Jg$Glk^KJOEU8FjP)$^i!)17bqf-cvlG)(CzmtnGg?eu X&ZNWthlQPok%NhciHnhok%tKY9~wQ{ delta 246 zcmaFG`ixaOl$V!_0SKO#ZHNnEVqka-;vfTYAjbiSi>oGT>jtHWrii7BM=_*`r%2>5 z<}yVwF@o5VIm}VaKw2t?C6_gd6(}a1%9O>H&0bWLA_HWxr%2l{fJ7E>q)0DhWMqhD zie^rc3}(=jow#fZCr43gdS-D+YSH9KMp<^Y(t@1)#FWXUj0KFMlb<pA>PZ6aF9H$2 zob^j`3-k*z3v@H{ic1o6a&(O{OiC+^^Aq)pQ%gz<O7in_Cf76RGuljE&!i*Fz{JS( Tn}vgik%NhciHnhok%tKY>vTD) diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/alias.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/alias.cpython-38.pyc index 224594a602418bb56f71421aeced7a9e0b7579b6..250badba1e5208b934fd65e0aa59809e3993acea 100644 GIT binary patch delta 93 zcmca3^h<~*l$V!_0SGw%?TX*XQ^)8Or=O9Zo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu vTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mp1OG*<2rT#$7UfJ delta 63 zcmew*bVrCMl$V!_0SKO#ZHU{*Q^%;{pkI<(pkI(#pqrUjT#}fRqid95Qd(i0pQvA) RT2fk2lAoWm`3&Pab^wMr73BZ` diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-38.pyc index 4a381dea09f15bd9461b3342cb0ba09e1016cce4..c04da07d45b6f6c72241f5084d410c7f9127cfdf 100644 GIT binary patch delta 4287 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 RFdS@+)ufs<$#32@@;`3w{QUp` delta 4081 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 diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-38.pyc index 84b19b9d9ced95deec1e41de86ab85f7e9317590..307653a248d0d90d3230fb2d48234eb77e07519c 100644 GIT binary patch delta 93 zcmeyvJByDel$V!_0SGw%?TX*XQ^Vwxq@R(Wo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu vTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mp1OGrQveG9t-l~~ delta 63 zcmbQm_lK7!l$V!_0SKO#ZHU{*Q^Ta<qF<6*pkI(#pqrUjT#}fRqid95Qd(i0pQvA) RT2fk2lAoWm`4m$C3jlM+6+Hj| diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-38.pyc index 6287ecebfd384f1a6ecc30c05c15f9dfcdc24bee..da599c7515304b5371439ae4e63646ec7d525ccd 100644 GIT binary patch delta 638 zcmZuu%Wl&^6rDSsBu?5yp=`StSRlM0u7rwMR9#h+RVCC`MP3j&nQ1b?k7#C`kf>4@ z@B=72B&7Be*s@^5U-$<QKfnSB#2qI>EU@I`JID7NpL_kK@wM4GZ?{_nujcR1{SV&z z&hGdCPl5<YND7nyNonN4nqd*cH#DiG^{5Wym<Ug>cSJDhP3T)Mq5@7yQ2Xu-PXZ`+ zPo*uUHqR4tB&S*qW2^G)BG#G8MxS0C0@PL?Vefbw`+r`B<2;q2UKGVdg+>oU5oby! z!(3ZwdT$oXa3-@^n5aQGUD$D+J?=dXjk5C5G#<W=M{@N89@HA><*)A1v+F&qEV%&z zmflhvfnJfmx9nOrsom7C$SnZ5Ap1Ck<6q*47@nOhvw={?_U8&y8q1a8ViR5p9%q8j zRg&<5<XWcr3^|qYm|qsQ(2~!jHaKICpI;lvH%?<I6aH{sJvLcQfHGrcEP7|pf=21j z*IO|qbCsqTKHBOl)7M4j)>X1xtC9AQFFoV}&_34M?QRWiSKUFli?`{zBLN1K(qF8; z`bM8Wal5HH{!vx>O6sg#hhYdlw6>~`1&x*T?!Ra{sq4^P2OWg6W&Zx&D)0YXOaCCv RMUluuK#8d%?0`?Vy+5GlpLhTO delta 388 zcmYjLyGjF55S_XA=3&+itF@JgxJ6je7z-t(rV4@)C50h!m$+eH?A;X!5exkR-5=0D z&>yhz3vAO^ioamx+!fS;Ih+~hoHMU;FO~X{Y1V-1<KpS`irv+hnrk#kkmy5z3=jg= z=Lq{CndG-1xy#4whWDAoL$JlC7I&ZT+lV56!*$!B`K#lkLF~j{-0(t`4t>9|ao)@> zH>07W+%${RDDv|TTP>C8x|A!{yIvtCaS8*NSSgO#1E0bpA{@gOMeF?uy+x6{+uO56 z-xzpmkYr)#g`=5>5^t0+vY2t&*_c#_C;FEknAfaMU{R|o0bm&!T5Pg#COwtr?|i4F zzbUT%DGQH6uI&Z2(on^kQ3To|KM>2?+On7vQ?tM1U;V7Q8$>em-8O0y?Y79j0SN<2 Ab^rhX diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/build_clib.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/build_clib.cpython-38.pyc index e840552f63d0c3dc217f85ccf722775e0abdc6d0..c486684d9aae77b9f53ce6e54091958af913a9dd 100644 GIT binary patch delta 143 zcmeAaULwpJ%FD~e00f->cE#Io<Sl1r<lo%NoW#h)$gue(3ojER|K#s%-Ciphie!MQ zekJQ?<maa97gd&)W@YLZ7bWYbB<5wN<|OAAm82HyRa92#m!;;F>E~o7=@(R%WaQ@= t>sja*XO^Vu79=KTC#I)P-p+2pSTp$pdl)Ah2P4~mrvEJLn>{%k7y&(IEwlgt delta 116 zcmZ1?+$qc(%FD~e00hs=HpI1T<Sl1r6xiI#oW#gf%fI<03ojF+z~t|2-KJ6O`AJ!+ z$tA@r8H!|p%73})m*f`c7i1RbX66-_B<AGk8fBQ2Rv70e>KCV$lopia=jTj5!*0P? SHkp+pjG0x0WpfIL10w+c>Lb4Z diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/build_ext.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/build_ext.cpython-38.pyc index 8c3b6674663f2889a75055726ccf11b140e00417..d90845422b8a9d20684e6c0bc00cb4404097ff94 100644 GIT binary patch delta 2251 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 Kf!>{O5C03sjVRRs delta 2180 zcmZuyYfKzf6yCd!*=1Q4SlHza3oMTf%bUKTw54d$qzG+IEwzjbv%t{Vo$Z~WvShI) zHO92D!JKHd`U8G6rZq+_rkXS{)*l*w_{ZoEr!g8|wP|Bw`p?A2Id@yAO?NZjoO{lh zbI(1myEgL9e*cpN1zsEeZk~L9;zrL0{;T%L-cB=_?o6xcb~R;~aZPLQneCfj=+)z$ zM#7v=o4T%n<k-S&Ydakm8Eb@JoDlHzYw_fy65qKOt=%P)@RIAR;NwUbVh6j2<^H^F zZB9DNT<s_tTl>p>kx9Ks@;<nj*CKTi*#%$c&AK{}JOYE>B)balddr)xWNmZyEUU0B zIZVf#Q|~ifS%<<-+mVt^+m@VJC!c^j-gfpPROZ*auVfu_0e%Jc<nM2Zk=bnsmOHUv z%E@?|lUJ5w^hmGeo=KQ-)8xDjuIATC{iHhpH}VfxZzpmGLe#^BXLLF~OfUo^zF3G% z>i8JV2sY+pUgot+u<To6G4L0Zw~r#*l8jkRoizA9TwG!~OZiB10Rf_(LU>{AV8JyO z7@>6@!X-QR6Fmgs!ZLOawiXUHbrYip;jw5nr&C!)(`qWNsf!6&Pn)WqGWceAtFUUz z5fYY)l*wX$c}h>FRV~5!7BaGx<X(AtUen}MJed&Q@$K+OVd&IBQdswcAEM<h0ue&| z2+ia^$^{EWmRnJ|utV|UgT(UTsd=1dWE2^e6i=rUDTVJLQ7NBKnQAg2Kd2IQ=VH@0 zL?$TK;||SKEIS^Gf<7*xHrmR?Z6kP3qwLJuM@2Gg>_gIWP3wFr5e;!Cu6R8G@%c2t zC~OO)*(6*JoXi(F74ognR#NXeh6-=PSjj8nhmnf9Hez7;6ANjbo3fEfPU@PGi+unq zNB+M6lP0W+BRrJkBpUq;`b#gfF1T45E!v1Ml?jhQI2f$nMdT&|iXq>P5Ov<O31h)V z7uDMrYnfn}u?e^kYGmKRC!v8ts*Dj)8k~v|;-Mhal|_o_BqCtZTse)yp|TEk15THX zh#C>~%_m5U%H49rQyD%>%hdfZIVVcgsf^S&;3+@q5fO5r)5puZD#q7UH?p#Tyzk+| z@-O!a*D$%eNNc@favO_7uJ6u|lFEiPv8Rc=pWu2$h8>0-m0iWRaBWa(oi>S*v>CFM zL#z`%t*m9^@Iz${`w{-Ge7>d&RTiBc>5Ps?r-)h}YLO)N3Ll3HRc-7xd|ox|4WWqA zWyBy@eSm!ov(*i!XvC}(WbJeQRTi=-KBYkMn?9xRG*gO{VkLld3DTuX5UCJSWlFhH zF%wv2tBl#Qu9d=78@?UOjJGP4N|jcWEMAh3BW0a43^~;}&hnI+mz~J7tpt?XRW?_$ z<j%U4%Hz)E0meN!Rb)J%D%^5sovVxtlZj<!w3?2UQsOb2VmoMy*1^7-2<ryDW}Y>{ zuQlQPSXfP_7oD-NqOA?pMp$cWn10CY(Db+>D;aEEb*fbsT`kKoIoIPdT&sId5`EJL zgW=j?k*SALD9T1kEU1QQa5n~0berYWvE41#vs^V3mP?(M6^-vC=`*kr4zo>gJzNr? zUa`FTyqTUiX-wd-`z_q(rK<lEA7c_C^^qpK?;pFv&gd@*y#Kzpy5s!USq>-aj}6eR z!aE3PREe?5X*_UhZB7lysed@tF{cXU8G<E(-H_i<%|@ZMA%&H8zM-~Pc<0t9=Mqz< zVfpX5i9<*Xx^wiA=#)vK6ao!?Z#dvmk!*y)#ulc+Oyjxk6S%(RK!|!Q|8B!baGKP^ zoa_97exNw=CkV!%Int!i?)+7P*9acD9SP18yiV{2!3Bah3B*MuLjI^}L{9d=dyyg5 z4|gNCU33}tz|T$l@apPl?v9B|-~idFCJ^_9UC}J}Y}^pn<r!kP5vXvsxjDRuWbTgl i;Z5jcMTB;GB<8V~+Tq*gmOQ)1;mIpHWg7!mOUHlbt^YIt diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/build_py.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/build_py.cpython-38.pyc index f5a4723ff2124175bbe4a0a1e875697cdd5ce50d..6a89c40367e651003bbeb108dbcccfabebb18bcd 100644 GIT binary patch delta 1978 zcmZ8iO>7fa5Z<@mwb$|bCyo=_iIb2}B1}q5Ac(Zk783pu(2@dWRchAW4YuQ-FuP7j z>NE#ZAzG;_JXO6^g>XX%sZy#Qs;a8`bD+l}Rbnp{H>9e^R;omyGi!<~Y`xF(=FOX# zH-G+V^3J}{$zZTez>oj&*IED2)liB(ygGbt*;5W_Aww{va<~%FB1}M9F1J^rTC~!k zbyQ+nj0uYo<a*1Ul`gG|38#hXpd^^_nKt;63G_W67(PQ;5e(&$sCAtYs^VLM;Wye= z1TBGQ0Yk+z)%2ERv+I(i$ws>oG(sy(ONNZF5kawT!!sqMqg-JRCiG09RxvZMP_LJY z84L0mL$4Oia=r$(X^mW5Sj^0s)wxW$n9IyA*o9hk+sJsvD%$4eSv^0apEr3>+{9vh zT%2C+z$aTGg2F(-pFBhO??bc~*CZ~h55X30um+*n5LQ{qV~ZteLRb|kEK|ZQb}TJB zV$E{oe4$b^9LchE+woa;7I&tjOl1$9K5^*HeQD-+Z5_^=_AvNSZ4*?aoM1(tF|+ef zwDnxsOpsynPGFE&yDeT5S(3jhe<r7pHMI7d{4P5<fFukeIBIUeHnaI!Wwuy0p@;ZM z;s?-BwpO=i>$U~!iT#{W57et$_)XtOtecN2@jy4pH1G2%WwSht`@Q^q<@;nyshX=7 z%LYBHj>ZP~IsY5-R+Kx!zw$ryZXgZoIg512n~*%oziGS1HuK|w2^pfu;GYC`g>y() z5`tG0pDb?St7?ir3T#Y~0PI9?q*AR|b^J|Jm`@nxyVVri&d;j-;nzrvf(9=mX#7L< zAJ)gO1joEh1^kELF7I|a-_7OFQF$Md1%5hoD)li^4WT6L70#}_EiJJnamlkJH6+{v zzZ=?<_BFhh7!zz(5^pFC-zr=3HT=-k@Zl|gscpuKv``A%Q2B6pJQ@TyV9(r!NnQ{4 zM}V^D`1G7LtJ?+W<=4YKdnr+{4I$kI)Njyqkf{9x2M`=(8WUL6D<;Hg>%$r+jw4|b zr(p+$H8q4M3%D$@B8X9@un>#liZEquB(k4*k0KwfF1B~aDIHE&w=5IvESP28F3y=S z!Ed+k7;d>eN*Acs9mT8~)_l<}IBk|`8|JiLFWaz<2cyXlIjnijVm4nfU?(4orsZ*D zUFNxHMTK_K;g;8Wem^?MuCG0cjxkLAXzWRMt9pX@f|;MmKJ7>J@^I%nnATgJ{p=jS z+u18mqn?}m_s-=gX-rFCkm9E`+2~5JW^r9W?sxo7*Tr3~n9{0xn4k;22%3WN%R;SY zyQSw=mix@K=V=PK9#6<5|Kr+w@i<Gkx<tn}U9ISLz5p}>Zi(;;zmwR=e&N3+>ZeG= zeP<f^NIT+m72DdA(~VX)!yKO6$7PWQNfep#IIX}-xPgNN{RD>y4ig;VtI5Ggt0Dr# ze4XD*4#zGM>F(W%KaSg<*P`8Durb$J>A9zYhvaPnw@uuPxHrkAKlooglanpG$B>tn za9qur`Bp({D(Lf=BHK2hYBgWg>N)cN0dJ(HG@3<_CZIV1TM4M?-L?ekI-p_&suG}{ z2TCqnAaIjJk8xC*mBoC;#DQ%zqvLny2aT{4-_zUE9#RsDN9j`}#jC_c21#D&y~h^# zp1!S2<96Q$c@bs*<e&HTv&FS<`%bVIo)xzv7cJ~WCt?&WyKWcD)`$sE0}C$mv32Vv zY23hNa>P@y&Nm<13fdVw@ZrCK6+%K_DwCKhsy^{=NdY=b<K*w*pRU_ILf$ru&^2w* z_5*?f!4-lT0yp@vYXcVo)W1NE!x=t5F!bU^Bvmv)9sR$rsInLqP=tlVn5;;#WkG9; F{tNpwvH1W1 delta 1833 zcmZux+i%lm6!+&ij&r{?Nt0eeT97bRRaPosqvF<$%fk>*m5T*<ZtS#9<2ZbF5SLUH zDjR#4Ho>P!n}jCzxM@h0^0tRPOygzR!zQF@@*a3(lO}Edz{bvTpaDcH|8l<bo$uVw zdGOA|xx_*|9^v5c$(4;uoo#m#!{oO+6Ys4Fjf9m{l7!PaJ=jQDX(erCl#G>CvV^;y z0<PE?uyRU{aA&#Zn7|qNl?eTYaQJ_e(?hy+i_@ibUdf&3n*2HBh4l#VB8FHG8o6~r z3F=8bs>f~-rJ%?4#4S!4)C2RJocfbvCGvRd+>~pzrdnoe(rh}e)@V#lFVD2E?y|Kh z$8g&%*R~sMAHRcSS&gs7GZ2Nt14x8Q-7A5+JV~>#crQ2ryh`_L@di0o1d^5jyx8J3 z*HEjr)iN6f%_2XI{OFS5s&?CLwOxk}Av?SYF%$^Uc5{MR(#PXyP!4)Y6`$yutEn~6 z<xu25)5u1{lfiK~A7CfL-xvF4VvB9Fp{tgyx50doO+-!wcYxdxb~EzF=m=_fjd3~# z7bn^6=v}gnm12hlkGCDB#b(Jx_C@UU@Gg8e1K<gD+iZH_o|T5VNM#m_50gnI$IHpR zD2Bn%X@CWGHvTWkvxUTr*i*nhNz96qc>gB*CGl=>Kaf>6o;)-BAy6Hz&b`fD>|795 z$tu4ZSQR<~oa^k<<e>_w^Y=rY(3fO2)CtpkCj`<`J-i|U&DA6KqwHyNZzk5u(Wbj} zmK{%(*SwIn=(IF<ndZQblB?RyD+YDdY1iJR>UPyN94HEwk4^x{5sIx#d!8b70O25j zCt)d?nq_#Rt5GPB7jkG7nVtaEt<fnIeYvzlbQG8_d`=#K<1<7e36g;?)fLl6$ets> z?fEufHmi-cZm2D-x}q%^e*G!d%}Z*IgI-gkp}8gmu#c^0_N4m3%BW?Q{g^3j_rr+# zVJN&+QzURw)lKU7K`EkPs#Qy;Gc1;sgFE5fP4-sSihM;*^n4#;-Rv0oy!&f*hCoY1 zb5BcI)b6)(yt-^uSDt%Fb8Kt=(i|qsi*9;tQYB<IO;>GQ^8&4vC92@P1ete@CM5gi z3{eek@3DvZwYdvG$pTg3=Y{FXpe|EunAZ)}Zn>u2eC-g?20Z(g-7Z``@9UBJD(F7c z=-1y*2DNRM_H#FjW&{1Y!#Kjkz2YUR_^x|yut3NK)+*-7Zg#u4o&3Z$itRIK(0?HF zbT`l*Uu(+53oL4SPmezsm*M6Se2xep@H~<JlO_5F9Oxm00>WX0IfS>_jnY`E--uCU z9%m0q69W#C{@GW2430l^|0->enP(|{IXD_Xc^knWQ$Ms#m!7bnhv!E6c8`LbEO>&` zGOEw!fbAS9yfESD?eFZ&$ovAXL0Un;g+y`N`1{0P0u*Q5?|+JIMlT{@wf$1{ih{0t zG1$beS+xvz+1BYHw!seuvD*r4XmltYmj<PPG%5*_C>3}@)9mQzBjU25@-*?-iSo8! z8)W}xSIcG6?tWH2O`fluf3}Q}b(W}X8OQxa*U?tMa+Y4L?L1r%cB)bcBPEj)a*<uG z9F)<AUKjcKY~t|)get=O2sMPm>~ZC?h+fcnaK13;Nwd8zyq^Hm*$NONF_K{)jTOa# JHST;Q^FJ$snY#c0 diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/develop.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/develop.cpython-38.pyc index 30b347dbd08a8a325057f255e51207967f44a895..7a584088fe57a4b0b338de9d72660cbda76196bd 100644 GIT binary patch delta 332 zcmaE9^u~xcl$V!_0SGw%?TX*FkvEjtDM3FYKQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+Fv28*?x_rvoDcLkU9` zWAWriT)XQ_1hNE+ZqzU=5CX9lGBPrxFq8<y3j#%i7cww1l!z=4P2s9x$Pxo$@rBHc z3_x090%Ng8i6lrgg}a%lU#6C&hGl^ikk6IEBMwp_EzSTkE1bcUA&?=6Ap$72Kqdtw z!wtl;JPaU{QW%0KtMH_8%N4N!eR_*IAkt{^RG!+&%DiV7Ehc~9)!r=2SIo$`aPvfd zOGd`In@<a@XJlMIxmsuw<H5~(!t#ua`kVbk3YZwLPTnup&v;|9zjy=V?a3F!3mA`W Lc9c+OWHbc;iymS? delta 370 zcmaE3^wNkol$V!_0SKO#ZHW7^kvEiC#Yw*;w?Mxjvp_d9uec;JCr8&P!=$vrI6qOp zIJKm-pd>#(XY&%~V0KOqMh1owhAhUSN!+{ZYZw*?EM#D0C=tvODtZ9q34>S*85tQ; zfMW4NKoJqJyyyb46s{VEEO8)~Sjf!C0Hh@+Fcuq>NP$FCxSN^!WolV!SQbbF`CKVH z;vf|=;tU|O!Wm2%0vUoBB7kBGWK%#g+(0bHGuenIk6XTo4d|6y%mI<clUMW93P$lm zy%1lVS&|xGP&rwH_Y9-e<gdKiOdO1x75Iu785eDy!f(mQIB)Ygf%S}x8z$EYZDKsM z*-%)Xk<nmtphy7|?=_&A#Y~_;Vyu#%{6R=;@)NOK-kV6GN?_3v@i^W)NTRA>(XZlu OjK?>-NT@S1ngIZ{Z)TkU diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/dist_info.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/dist_info.cpython-38.pyc index 3f029417c2927d6ae546069737751664e1f5c19d..fc0334269b82e7a00a47cea7b4ea603501262859 100644 GIT binary patch delta 100 zcmcc0^_hz&l$V!_0SGw%?TX*XbDhyCNk1b$H&wr=va~cSQ@^+<SwAH)FEceKIlrhR zwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!RiJ#{lXlOPl0t<91wHjDth CwjuZc delta 70 zcmey&b(M=Jl$V!_0SKO#ZHU{*bDdGeMZYAsK))cfKsPh5xFj(rN7pFBq_n~~KT*Fp YwWPG5BtJiAvnrDy6Jyk7a~2y$03<RNVgLXD diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/easy_install.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/easy_install.cpython-38.pyc index e48628c721529b216b0a9d42facc0c7b722f817a..10fd6fce2bad5fe9c37b578dd1dc3ca49d7eb8b6 100644 GIT binary patch delta 16096 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 UneAD2d#1&1vpXCG2r%XTKf~K*Gynhq delta 16244 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 Q?cdhnuP*QZHlJnxFOnur0RR91 diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/egg_info.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/egg_info.cpython-38.pyc index f475cb7aa16e90fb5ef7cd43880269041e6ab412..a0fcb04e79f42e55694d54e7c63b967a1aaf0040 100644 GIT binary patch delta 1257 zcmYLIYfKzf6rOK(cDW4fu*<H67FsqEuq}_VP_%DSXlbeCQD|*#jARQ_SSZW(?$QF; zKBUHwMr+d(O)92htD@Lg=~bhxKS+PrkdWA<niykZV$#MR8kIhLM8JF3AI{`_bI*6b zbMDDGcSa^a6Y%cwdQD9}>GRjxzMb@rrqzV)uD)K!=7atH-4Q#^+wG2UG~yg;@8bz4 zUOq55WFK*&N9;q919ogM(bX5NEMH^CBMGN07H;necRDnaR*9mktP)7l>hx)xr1|ul z7@;rCmoOk&Gp2N0q@eXYF4JpP93KfY>oo8Qz3N+QrO9GcMYYo6yXkx1)BX*HmdNNa z`59=(3}{2kXtRG&Y0?<h_i9yIha`_1`?P1YsJ>52YTa2KS`Xu&%9XF%f6Se9$KIoU ze-(bC5B&MYS#X1<{du-0>5;;8={F}m-Akn$W6R#sdh`^db-R+Dwt|EqdDkf<JtB~O z21uiefydmuSr$jrfs#!(RFyRnG&h3@Q`ceX=7R3hk-flNK6s!*`ihwgx=k<ybrU{h zB8W^;9(<_d9u?*EA}%N=094R;Zi_tT@7&+<i1>N&yFi|xyyZZN_#(enN9DPKJ2)rq z79b6E;-}(F9j}N7%d>zB<X#!Y8<bc%iHoARM8;gErqZ`DF7B6_z@%6x%LcAdw*4GF zqr>)xxFJH19|yjoH&>m)O)9MT8n@}sid*=OrYq0mN72680q%(Dsvm$~>HQ}sP%Cz? zsRK+JT{{4u2(H@+1Sq`zIts+n4bRFtX=vj+D5TJ)tFY<zrWsU<vFb5ko!Gp&7igd> zHJ6YkT5DyRz2fyPaiBw3b%nrDs@OJ}lOB%6oM=Z|J0I3%ccp0>hKlKrZA<^(qWtZ) z&VQl9R)7v}4+c&sDN9K+btYTPXX)kbQ<$a3`a^g?*XzrcjVO&TrSZr?WXgf5G5Em$ zktBu6mQZL%W6^!-@L2`xCG5B2PNF~7#+}3c5$?qKu-f^HXh)5oR6>vRHJQ!=pQpP! zW-v<PsTc8(*6pm$Ij<C%DTM)#&gP8;!^2&4c4w#elG>9dqq&=mhHn<j%dL$oHuX!& z!mR)D8Z_H*5BuqEW3kNZZF-^bic;mKVwoP4w~WD1H%h*_@@wkc5+6661m>t}*PchG zlzfqryA9}?zF_D|s(N5xC3pZ7W&!$qS7?h*)-Y7P#ffpJJ)CelLI<3#@R3L#4;>Bj zXe8PhIw;p$J3H&62m4Ax2L@x|cwEu({+NuB>%J&8wXDihiEgQLrD+UY`72PjVj~aI zXiKkWPSQL}SglPcPjy=jfzK;&Nhx<LP#xixf`9^*gFlfP`i0$Fi(IVLT9SQ2tMHxB Yw)&cxmjxJO=`4eJn8^&2F+cPD3-ZlQP5=M^ delta 1146 zcmYLIZA=_x5Z-6GJC+6R1CF*73R|U?qi|;dwY2nz98$gtDN+<uA;)pxad&&i?p>*P z(rT?Xrfu3xVye{y(#j9;qxd#4#+bB;(KI2AsWlOQXeAg;O*BGUW0QjKLX7)nCi707 zdES}X8Jfn)X=ESF&XxuK{d)Lv@4{^Mh4d1iClQT%;-Pp&NYxYmNTj0jh3e#ys+ixS z2NTJ7A{L9#o%AY{up+4nc!@eQuHz^b%3tFRT9i*=l#OIw6){Pb)>kk?SFAcdW~H__ zfh)x9HC79MPvYX^qSw=Xd$+CJBqTD!vNjIEIOKP1D0&q=f+{{Mq=aGHfDo3nDQ?+^ z9WR?wruccf=y(jbY2HyNYD@HwqrhWMnK>-uEHrP*JiLX2F;O%rgvB+FFr1b$_Z25h z+@E$FDKqosoB=F!Gj}_!<nFLsGqUlL$C+PXg#{wyRdH1|%aGs{W!RAgCuBC{yeDFb zdN)R)vAK=8Ko#BI)X9me^8bR9ZQDErY-V!>r9c_GTj&!}Nj1g4;2bMfkdCL=*6mp$ z&M>#j2E0e!G8Gr-!?IaSvc4TWXogOfU&0itsE~onY?nI+_>5XTz4(--Js;s3>v?n> zxIy3VJdUsEP~|P$q@7jYV4lS4xA8N3w>k(cGV$@BfIn#AiD}fc)4Ljh47ycw1U9yR zcN>sH@9g;;MXbB_5KolY-uLkk^>{ylo3iTWP|4=&CV(0?_GA=jqu=T;!op7ZI88VE zwm}C1Y+vKUz+npSo2`**BmQXrfZuye6oh5oNnvbT->4Q!1pBn$NHU}aqd_&HyK5t{ zfIp&pxv`F?o+eM`a~b}4Jg5%z1vEO{RFXT+NpxdE1m1KBGPGs-vgs<8=|pn`_h_lP z0w+jm$;SiQ-4eFk<wy>hX(_^e8fkOVk1cM;S%btFHGxxDp{>%E);XM~JFTzdZ;q<N zTQu92XE8w#0%>%^vxyelTCyjMFfKeyv(TRX-{qS*;F958TNFMB)^$QNx!RZU18wPe zgcCM&yoL|xddF7S+3y|4fE9`yI9Tw75okB)%vrn`qns?5PzEiJ77kP&&Ee!@Bff}V z*OkGTri}VEHKYzH{{C1pp$r7$S}@>Ggkq|$gj6LsG}NpP#td_97rXc_>TabymQX@N zYD^0bDE%+;s6l@+k|<Y_Y9tg6Dh>a$JhM*kZg-iqR-P0EI!g<T9OnKjTY_fXU1)Ue z)i%&nXVkL7ftrKmKivVB@o%*UhFUe0(LBv!D5Fc7-B5Xk%As>z&qJg?yYg)5Ql?~) MWXU8;l0&ln3vlUA$N&HU diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/install.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/install.cpython-38.pyc index 1d4479ef7c8b6fff873bdeed270fa7b646f4e172..54e45d945c73937214cedc8f950921aca691c3eb 100644 GIT binary patch delta 161 zcmbO&e@UJ<l$V!_0SGw%?TSy_$lJ{1l%SuHpPQ;*R9RY@m8oA`l&qhUn3tKFlbl~v zl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2(-keHmEn4Y?M3)5B(#-7Pp+|^=P z0x29RoV|>U3@HpHJn_6K48aVVT$8_Z+ljhqGDZm$XXKa1r=%7Xr6wnqWaj5>Hsz6L MWaQZ#%In4i0NY_RbN~PV delta 105 zcmca4KU<zRl$V!_0SKO#ZHV*U$lJ`M;-p`aTcBT%S)iMlS6q^qlcQ^tVNzOQoS&#) zoLW*^P?DdYv-uL!Ru0CF$sOF)LJI^IGB7fvFqH7b^QJHaGiY*5mgKS9oWmo}$jGs| Ihu4h>0OheCo&W#< diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-38.pyc index e374a0915a07f1ef41a58c2ea85d6efe59f578c0..7cee205762c331f1019181e14662db3413ffd0b0 100644 GIT binary patch delta 99 zcmaDZ)GEvq%FD~e00f->cExYxxx?s`sh^Rbo2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu zTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mp1PTbNrIg*YO*S)699nX BAwU2C delta 85 zcmZn_elEll%FD~e00hs=HpFe@xx=X9tzVK`pkI(#pqrUjT#}fRqid95Qd(i0pQvA) jT2fk2lAoWmS&K=6o%a@}CqzYRQ4#y(jU3{W(>Ub;o_!oi diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/install_lib.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/install_lib.cpython-38.pyc index a10466b66cf44f64133fc70ebc94ff97b73bc3ba..0dbb56e38b5c6d33c16eb23465a8540ad91a175d 100644 GIT binary patch delta 155 zcmZ3Wa72MOl$V!_0SGw%?TT04$a{j(DMddcKQ~pssIs&)D^tI?C|N%xF)uSUCpo{U zB(+$tqOwZAEH$r8KPNLuzo4=tBR|hr&qBXAvm{lwATc>RF+FwjPsS7u2`P}V>}*VI zjBHF?j4VK!iGk}s3)AL&t}Bd;8Jk^rSQ#0^CwuX}WUQQQ!dJ^!I(ZY{9Y*oV{rnRF D&dV;G delta 119 zcmX@2ut0$~l$V!_0SKO#ZHN=w$a{iO#ZA8?w?Mxjvp_d9uec;JCr8&P!=$vrI6qOp zIJKm-pd>#(XR|m{3WtygNFzHN6B{EN6Bi>3lNjUX$y`?$8Phjs@USv6hE2}neaToc VIfAd2v1IZ!zB`O!lQ;8E1OWY`A|e0) diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/install_scripts.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/install_scripts.cpython-38.pyc index 1f4f89e181feda2dc816fd85f955191ef21b9c2a..8b9dc7fbcebbbc94ef42a51956878e78f52da7d9 100644 GIT binary patch delta 376 zcmaDVxJ`&Rl$V!_0SGw%?TWv?k@o<jQ-*#<er~FMQDtdqR;GS&QL=tYVqRuyPI7)x zNouiPMP-$KS!!OHeokhRenDkPMt+{Lo`rsKW=X1UL1J=tVtVT2kBoWT96&>zfw)+V zadH+@Q+<_G4Z{NN6xM}|wQMCqHEbztDeTS6wd~;xc@iuPCBoTUMVlBIKrn^9mOYXo zk12wohA~T|mZOHf=tK%fEh~^G3goeth-HaqGZo#aVNGWQigGNFSjYer=g5)-u@*?x zfb8G|ic8lp*KjV7S;(-E$winUR-l%vh9OI~hN}-~$ppqihRJcv(TsAFcQK#hxy9|7 zTLAQ+Yf(}D<Ytx-##@tbu=F$9P0nCd<z!;yViaKHW8~UAfz^wVO#|qwBF)JU*g9a$ wJa!dUMWCqJ<mv1VjOvqbu-h^!PTt5NK3SJTlu>Q6Glv(O4oH{m<jEXC08CYAi2wiq delta 303 zcmdlc^i+^Hl$V!_0SKO#ZHQ~%$a{cM#Y?{=w?Mxjvp_d9uec;JCr8&P!=$vrI6qOp zIJKm-pd>#(XEHxi9ycpcn==p>e`A>3!PHb=!?1umg>@lgEnA6D4O<FZ3VSniEqe`P zmT)ac4SUh56pmU}AWsCyV=WQQ63b>P+Ev4v&IlCcSRlTT0VvLqB>`eBkgNfj!wD3Z zs$s6-Tp+!WVIh+XLo8n{R}Dj!Obu5b10zG>qZEc<22D=CB1WJqZcSdv?8hiO`3Li< z$>&*u8KWjEv-UGuOy10@%FM;cv-u&b7bBY*P+^h!WJC527;`_n3adO&)Ohj>b_Yh) e$(kItjPjGyIdmA6Cr{z<V$%ZYkeU31BM1P4-cyYL diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/py36compat.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/py36compat.cpython-38.pyc index f13b42c13f96940aa82c8f24c0157eec7b72f815..c2cf493f5fb1efa65259b7d5595bb6f45632bb9f 100644 GIT binary patch delta 94 zcmZouS)#%l%FD~e00f->cEvYs<n3d1O4iTF&rQ`Ysw^$d%G56|O4d(F%*#y8NzN}S wNiEi^sI1a2OU*0O&&f>EFQ_cZ$j>v@v(PWjEJ@WZNKDR7Oi$gspVgfQ0LbSc;Q#;t delta 64 zcmZ3Y(x$>2%FD~e00hs=HpEqJ<n3csan&!$EzmE>EYQu&D=taQ$<Z~+Fe$At&QH`Y SPAw@dD9O*y*?gDPod*Df78Ruc diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/register.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/register.cpython-38.pyc index 5af686d44ca0975bed5bbc56f3afa7f2d32529f7..01e33effc05a0b6878c8eabc67c476ae39064ec2 100644 GIT binary patch literal 845 zcmYjP&5qMB5VoD9KTG$(asY9PI8g!dfeTt8w9;xpT*|7zB@(i-v1wBrJ8L_IR^`I( zgTRqj;5j(u%86It0F1M3w<FDDew>-_8~g44{vHD9|NX&!VuXJAU{^v2jzFz99C0jB ziBpWdPb4V=f-ow>G-@+}?3CTKi_r_jLmpis9*JlcUIb~#$!j$1{Dv-Qh?_v_$q2r; z#-h}7!H;!WW{RH}qfPG5><WS42-MyIBT$MtN(sklzzGj75%dnBchvNZm=x9tvwZMe zn^G9Lh-)i&>~y>-#Z{Jn$R@(ZTE(Y})0asOw723%dCJG2_8u6HKjRhp3S?LKHgb4I zz7dREu)-Jk3jl$^!D#vJ%~V{E$gjx6)6B+aLMW)TBp-S-vHMskusW_QsWToI3LwMx z{?xh39#UE@sv^;5LMz&y9WJ{k<MFHUVLS|*UZ#|;RW6K&+C*)|1mF)z6IvnPH$iD9 z-;wD<?oURix)jtb>UvgCYjVmnRS21D<AhB<EtYgH)SSxV4CcD2R*#b>)D})W+ANA% z;p)n1EiGL$qnm9e)uIVZt^6CZJurxne<V5}%fa>tlt=z@7*km(7;E+zD>bjB_Xmuf z*O^>bx{Pt1GiGi;r<TBu@iUCSn=YvJP7jBq%?x`@pTo`9u8_7}OnP@4Cu`8j22s;p tXWD<8P@7_s-n?d+2>%LgyVRZeexJsJXnIet@IUh}$9BLB@BtYF{{h2N-yHw| literal 759 zcmZ8fO>fjN5Vaj=H{EU#;=rNekRvP64T5s1PzCCt;<AS#R1_qvD0b7VoY=J;N>{zn zAJQJV@q2vbfcOhYNQ|?))e1|Vyz$3-Zzle*vok_4etr4z`7uH0XGk^&h2#xPyAOdQ zjwNbvj&Z<5k|rVuqlV@&M#qRpoZcW#MLeh9qMUN_9!=uka1%|ikEE(*Wk@y$h%N=5 z01zn09OXnrb2^Xnm}5?EP(I)h5K*5PQPtK7Q{oMZfI|^SFzs^)i`{E<8*y?6HXZQX z4z5war|1=e9Vo)#Ik_VkeS|WAIhrj#oxVMpy_+2$q$ewlx~<aMrd((v%EAf$EbXjF z-DTZERB5NBDtKDAU<kfX&z;luAj|ZXuBXaWna=vN*~BNJs#x8gsmahMMcb;bErkh{ zdm428w&_|{s-`Jg?x`|$WumYf!8&w~S|QKABeM-_e~vQO=uFpoFGv?s?!7qQ@4miN zMP`NTv{OpjO}OIC*3FyhE3*Ym2~7I{0>Xrh@Iyl3OaCs$_Xk0J7A!N?7L8!cj~Htd z?_|JZ#xA--E_X~ITY4Tc##PB!uhCoH2;=p!7=R6rE5QlrFHQ!2i^JdTTrF+ioP75_ jpRS6SuD$u;YNfxsln?FsPs=B-mxd3+E9nKt_)+u^p=!AE diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/rotate.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/rotate.cpython-38.pyc index d638fb0c7d5aeb20e36c4702ad31ec065802cf6c..86c967c255c7353d985e14b4e681027de773bf83 100644 GIT binary patch delta 437 zcmca3+%Li#%FD~e00f->cEvYr<V|4;(qz2FQk<HTwvwTUA1LuFUOyv0H&wr=va~cS zQ@^+<SwAH)FEceKIlrhRwOFsBvP!=!HLpxRCo@UEpt2+*KhIdtLcch(BvrQ{F*!Ri zJ$3R@rc6F2pjjZBoPoG_#$*|03u_$~h7y)+uA&4+hFV5OhAO@i#uVme#u~;Zrf>#R zh7_P^9b*JTBtsrk1VagH4MP?~30oF>GgDE=<a*|B>LBN7G8KVLzQtNxQj}Ss$#jcJ z&)^ng0odsfLSXV7mVIJCb$lRojHxJ6*{lZ40*o@7=dq?Rnu5(^zQvSZe2b+Zu_WUb zM|x^WZb@ctDp0pDSa%w-ZlFk!=wx&DSGpjhixfdB*nt{LQj79#v8H9_q!!;|EGbe0 lNrKFVxyO%Vmb@T{FApNj;WEf-*f|#pAoyUGz~mjADgbbWYGVKZ delta 358 zcmeAdxg*RQ%FD~e00hs=HpG=|<V|5RS;=^dr8qSwZ6!mI08rwWqkc(lfqp?|fo^7A zaY<rMj;>LLNoj>~exiPHYDsB9Nq&CL<ikvve2hTV96;<0#Kj$xt(YyeWmp(WShBf_ z0vH)Uu!J#%xtXzvF_IyVDT1MdwT2;!p@c1qy_u<~V)9z%Z|WcmHJOT-fYdG4;*z4w z0!^k{OnL^l7z@CTfe?a|PqFM1EaC&ILJ^(EYQW6L$hY|-YYL+&*eK>(O!>vPSPBwL zGH!9Cr<UZFWag#<Ef4`&z?g=t8)TT+<Sh1AjQo>BITX1;`eD{Ja?Fw!0`cWRggIOW TS&bFvLIDIH%o3dZno|V;V1rWv diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/saveopts.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/saveopts.cpython-38.pyc index 5359098093e36c1db0de0fdf614b6a7683568ae4..1eba315a138734fa30bba72c1f4160fc00f9cf46 100644 GIT binary patch delta 93 zcmey%Hk+L%l$V!_0SGw%?TX*XW5wi@sGpIao2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu vTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mp1L`UNth7;l${@- delta 63 zcmbQu{+Ep>l$V!_0SKO#ZHU{*W5uN6tY4B_pkI(#pqrUjT#}fRqid95Qd(i0pQvA) RT2fk2lAoWmxr0fV5ddT76l?$h diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/sdist.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/sdist.cpython-38.pyc index ea51339aaa7f9c12fd0ddc404b75ad6c21f634f8..5f8dff54629ebeaab3bbddcf289b2458baba8c48 100644 GIT binary patch delta 3377 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 I8?j9C|05t0K>z>% delta 2290 zcmZuzTW=dh6y8~{?X_b&PMSD3J27d~vQ3jlNn1(?QKVidDvDZY3*BB;ThBP&WPR!E zrcElRsnnnX5)aWlAOwiyv4savkdXSq18?vQ5)1DLi64L}BsgcBTccXqZ_m!T%$zgl zoAEENe|9`|Ihl+r@cZ-5H#h&tuBNhNWp(iU2vMj;!)~ISG?O4JRCQBkiZz>Q+C-yN zUm<488w!ol_=-Z~EV=q58zDi+a~4*A``buDz-LoO{c`PS&8ZDJ70<U_cWAV9Y<^*^ zY9IBOKVS2!RaYd`*GRKCr{>gu6)~eeJxjARx1yMtM@o^<UfQ>!n;kSyUxKkt+E4ex zyNe#61Mu#q2k9Yr_t2NA0q^W1MN`b&JBo35<6-CoArbLZt2E(axP;WkSU5@|X&i`% zsmNQTLwp>$o9%>wKr1>f3p8r`cEh^iBJxo;X^?3{3$!YCW_VhB8XamM*bdq-!_PtS zdvu9t;;L@654}KtM0}!ub>J{+<P!Q(dXZuOMlt4+Wf^$~QeYlLr>j?Ncb>fqAD#-J z6aFeHG}o!jO&ejpAHH}FVI0R}XBG;q<~!9&5QVbazRwL+x|llVW8Jac-T9*9aexbo zxY+b{-}Y*QBxg3Yd{(Zxw$J!$XgDgeiDOx;ML?`T^>6KoWVVTPu1!2hOcu|A5llRc zZUp5}L)Jk43t>ws4L6l2b5s`4W$T9n5qLuIcsBv+%B-?R))j7w!Blp9R+)`>W}VDN zPb)VLUe}h?50xc#DFkMrHBB~_N<%ApJ#<=mNY)8aZjVw8+9oWnrSi+q&4ne#x%S~) z-2gK%+l|&G;w!UcP5nTrlXZ1fy$$X%cSuXtz86e+9{{A)2CqQJ_Nv%r_L#s%@Pb7h z-l&$`*Z73%cz&T;uB9g*fxRb_B<g?nhDE-)yK8vDtrl$8n*?FgaB|wv`2q1Dm5JcO zc#rrzl@lZBe$&vn?9VrG_%zNQ+nU{L%y}L)a^g12rqrUWXwSR8XVn({QngYCwTC^b zsBsb}>99^(Ng7rodYf}%yj2u}(1oj`JPZ~==kpPeKo(Bt1z~T##&{6Bv{++jIInV! z<qWjDHm}IWhg!retKiz6XIVSd;FrMcBXMxw&*R(03?gg+68AWE{#IohomXslN~T~= zJP#nmVB7a5Qh;{=7zw`9$}MGkj#-?!%=Vb&bH?^;S`aPS9#Vy01K%JrUqN;Su|l=B zD0Ac8VxqlkM9#0@!YHtvLAa5&Mw#dDUDFK+^o4l8{l}JFDLEc`h$|U`42TDrw%uoy z_%hQ+o`@eZb;36$I*t)S#qG|i<szn3LcspVeHaTOlohI!1+AAW4hpB`XQSj;FW3p6 zJGCGV=P>uZyN+MtJs2X3a0&qWR<;aAmuCsvlfWkb%eq~0ijd!T;$+v^W$aRXFvKn@ zQef2*sRKbMFl}AEu1fxes5YnbQ6E@H!^k^iogbc!tVQdgb>dBfMyC;w)rJlj8(WK` zuJLU|?=7AxvBI2}cZzw}i5FM}YA=ge>F%0x{JdX{=Qn?cJmwaMQHhi}gf4!G<>A1a zXZb?4;@faB<!u~rXuf9qCGl<dMKRJd9%=$&-R~J#-qjb_36194uG}Wi;9{sjV<OS` z0>Yj%J6XUbTdpHl`xBNb1E7Qxp|q+4zce*LBET+9)zo|YJPNBFmOhy+C!?32z{sy4 zoD}!7r`k;v4TM32BMANC*X%GkF2cF|@+c0B0hnoMW(#_KZqX{)73wlRiMqEDkZF=H z92=CE5$+%?0R+iSau%5DZV^-__a2%^uHh+x_op`jpc5^ms%l7mriqQ*K)0Ss#PqnH zgeN2KJcDpNO^sIZPj2j-yagpKB`4&HXF$y#0+=n^{}Q}mwg6X7MRvRyuPu(9z?0JU h<pIQ_Vxc$N-i(erm6uXVJnrp}C)9+ht6C@?{U7sw4WR%4 diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/setopt.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/setopt.cpython-38.pyc index 6f4cc50637064ae922ecfd4e861ae4bf10c413cd..ac36b1169968b1b640d0aa50d53002ed72a763c1 100644 GIT binary patch delta 93 zcmdn1d|R0(l$V!_0SGw%?TX*XW6JClub+{ho2p+_Sz4Nvsb5@_te=vYmzkQAoL^Lu vTC7)5S*2f=npdWulbNJnP+5|ZpJ%LRp<kR?lB!#fn4F!Mp1L`eIf4%Wr!XKP delta 63 zcmcbuyjPhgl$V!_0SKO#ZHU{*W6G@Js9%y>pkI(#pqrUjT#}fRqid95Qd(i0pQvA) RT2fk2lAoWmxtTeF4*+p~6zu>2 diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/test.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/test.cpython-38.pyc index f0491bd563c9c08d9f286cd2ee51a6e552a03f90..5377fd05079ca2b539d1adcb60b1c013cbfb7096 100644 GIT binary patch delta 756 zcmYL`PiPZC6vpSxZeo%qsin3}|5(R=U<I>MsTB{U7PNY>hid6bWxG2`H%)fJ>};Bp zv=ysRdMP-FhziL?!CPHHXc4@5Q1IYIdk`<4^)6axTf{kh@7u?3zPB^;YV_S$dMcGl zAhqIuHg7#VzLEZn$8H$2tV9i7^ZkNjc-%5<({*UkVq8!!Tdge^73x-uqBCQZYhsqU zXR_xE&k^)g*|g@&JPi`s%P5?dZ{kN&<b+MjoLZ)!_CWA0{xs4*2?z;PfFxoE1g@ik zW`m7av_)LUyc#@e{R;40R@=s5FnHT`3HFbMe~1&HBaHBlt_A7##~3z(7af}bpCs-2 z0Pp2sW^DPs;_9e@Y!FbuO$_0erY7i3SX46_5#^)Ghg0|QkzH1+<4)8BKsLIzw_E?$ z5it>OB<x5N>ac<rRZ^p+t~Fu($Zm47iPqD*F4aVUrselcW;r^sur+;Qa^lLw_<3@j zdctw@q~e%F%sL*iSgB;XHc|Hfy^ydo?-Yw<h7wLotU?vx5|iY7;d4qVlzR?yvt-Is zjuaW23sZB9D<)4}${mZS#}R~%x`Nk8nK`ad5o!iiqCCs(0o->LPE3_bU5oi#y_Zb{ zBfdvfsb=L)W~ej09Wz~*`L0E|t}b<3504~=x(~^l-MRKJs^#@5L7)TH^<R2Se(W9r zFG%-P0G8yv-XW;Vt=_AVI|}+KQ+=XkRk;D+7gdpm(;bl|Wm<w~eMyL{DcdSv9}If# zD#yb;+p#idWy(d3hag{*KcX4=r2ph_7OSDj42DE1))nhjRl~r~Drn#s&xh>oP%ek^ OAe8w~R)gRD!|)d@2ijBs delta 490 zcmXw!PiqrF7{=$B&8FMUpIU7-rirOG2U`dcYpf@ginbIiR+0831UGFH((E#s#0ndW zL?}J=Fbbjw*@IrKPA~NXC=}_zQ>jqFOHY0VI}>qWp7%HNJiPDBx5@3B@rSXPP1HJS zZauo4{S@D)*&BJj;^n=vmn+xmyjZQ~E-znctd6_Ie7(dQ9(UcUyl8w5V?_My9gz|H zote4^LO7|wJ;|w0Dux4xwv86`DQn8FeTTpY@xFfw<ML1c9az`&Ogcd2ty6C)w&btD zFTfA+=FE5OilxNl+6(3Tq@#8P0a|d->GoBuYlvM^uIZ@$r%3=1hdj`E(=q<v@G$S` zSWYN_k2Y-?%I)=y0Gk(}lXgHh<6Vjb1Z18R$Q-#(7XDGRi@NEkIV=92Eg&jpk{SEJ zD%NUlqxQHY%E`sZzItVSK>r2eck()zJU`R~eDOL}z%#Lzx@$gH=8+gqbF7P3>5S>C zGnG5(D9jCoVX=EoCfkabP99hubG;JdPniy~4H4@}h>w}Ei5x`;(FBDZv-+$dRSgPu ZRfR^gY)NO=v`lMxspW~5b$McV0>|t1eKY_7 diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/upload.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/upload.cpython-38.pyc index c998f7af103a36764e5ed9402877ead3783c793f..626925fe7687146f907bb5870a9161725e54f563 100644 GIT binary patch literal 818 zcmYjPy^ho{5cW^9f9w?p1(XpLksvN;&<UZFP6whnP75@luyV24&Emwtb{2NEG~7K1 zl)M5D!2_hF;uR=>advOnkvy64O#FS{*sl)`MhI;9=R5y_5&G$qeG4EthGmby2_&#W zB~CH+F;S$XY0$+~g=H`8Ve|}%K!jIFgff`ZOPW&Adx_%yFZdtDxTQ)@;nQnsr85E1 zt%)r4LW&bzmRTiEjnO9e&HF|mIfiBLfRiZ20;NP?IGhN2h0;I-01_Gs<yHJtn^GFJ zj2bIN<aD$Fi|Q<YmrbShTj$I3=SdEdcjhs?+!I*#E;xZd;WhdKLf7~<a(GU@5{w*O z<4gP*7yu$YTfKQTlh*+GMng2qY;+-I6`75;`<_YUJ`@%B9i5`GPG%yyH*>DGM~v0W zx=6H{vYK_h@v471nY@@BMRCv$vZ~Tel}qD^wqaK>o^VXsz)JPDrKO#ILuLqjzd4)f zQZln_nt8#j$(hKiLaJOFCvEa^xnc`hEto1U0N2fQ^)PwFY~kdC>oGAaT~j-)m1SFH zY%|HEUbfUUm47>S01grImxMR*YP4;D;#nNF1J0|gl$^IC&Py#C<>N8u@0(0*D}By| z&N(+X;GB;9p7RLZt@a_XUhMz}q}w@*`|VH^)-|qBb~Ba3U7l<icdc!pO)*Um{|ic_ fe`mIv-yWPFo$;9M;PHm;6aPeP58N1!$(a5FvlG+t literal 5207 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 diff --git a/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/upload_docs.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/command/__pycache__/upload_docs.cpython-38.pyc index a7074969a07a47b96638c8d186cec6372b6ab5b1..15da24db6c98604a3060dca01696e305736ae120 100644 GIT binary patch delta 412 zcmWlVu}|AT6o-B1^Vtcpfl|uMm;sE4kPz%hY?Ww-vVgfe2M1zDcNZYhSs*dPz>QRG zGIj)S3|%T#{(u`gvN5rBh<bV7@Y8$x^oHNn+WlJiH4N*Ho!aE-;O-%ufJ-bS&xka$ zqR)BJP9$T3Bt16t`Z8VFY`WaDzHvW)TQ`{Hq@b(`4G?y*J{P|nK5vD8G(Il6EaroL zzmvs+lb9xX#!gAWB@?R`gJFEe^0W9fJBoV)d0gbJ)y-JUWRk7)5^|EXS#=Ko)W3`z z>W;yZQ@YBf$R<*VdMPYD2|7?Yo#`Flz!FQOumU4*>|Ddrm$>7P0_BfE8Av?xRiL~v zENj$PP~V1oaM;qX;kIwQM35}g%h5*TecDB{&LbO|Mmzd3+5-FfEuxDN2rS3~Cm2Pb zVF`3P`xA%?&;5pAzk2=vLET`=rloLNy(}QmNbM_wx=begQ2+h7yI^W5Pug9UOJNWx W@|=@uYmopz^^Z^A!Ij=#dj1dS=6;a? delta 411 zcmYjMJxClu6yBMgnLQ78PraDy(qD0$<Ps1pg#$Z5PtYPV?9S>Qw?E9xNsw6;wH1pg zExhXtSSZ`uSy)=w3|NQMsggo6c6nd%zW4EckN2*YPL}+E@7En$KM(G{UEcd|;J6{i zoacK~GA2S=FhhjoNhlBTSjL^@w#%{g8+U!XX9&x}JYsEVfUtwjaq+|9^VaaU-<4_6 zEs~;>WJ1!>sPlRM%lLaQr(MD1xR7~1693aMPg9yzH}I~$*>Xx(xshu-QYb<(EU|Qk zKsiHbb$kI!B3(rkn4qb121`%kA(?o}n}V_?@r0<F!c$nzL`1<!EwZ}4^*6BS+1oS- zR`hD{H87ZpFiCz}&1u*5dC>O^iJ1LKKLsnmXxxYvYv3Ko0=^LxfLV(`A2qH4uRhH^ zKwzrZ1qeL8Yq#*Y`qe~WcHeS?QYI;<`p<{8=FUva>0Zh*DGUnpEaR*iEQWx@@2S3i QZngBw#}ja>w_1<?0R0zzRsaA1 diff --git a/venv/lib/python3.8/site-packages/setuptools/command/bdist_egg.py b/venv/lib/python3.8/site-packages/setuptools/command/bdist_egg.py index 9f8df91..7af3165 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/bdist_egg.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/bdist_egg.py @@ -11,13 +11,14 @@ import os import re import textwrap import marshal +import warnings from setuptools.extern import six from pkg_resources import get_build_platform, Distribution, ensure_directory from pkg_resources import EntryPoint from setuptools.extension import Library -from setuptools import Command +from setuptools import Command, SetuptoolsDeprecationWarning try: # Python 2.7 or >=3.2 @@ -54,10 +55,11 @@ def write_stub(resource, pyfile): _stub_template = textwrap.dedent(""" def __bootstrap__(): global __bootstrap__, __loader__, __file__ - import sys, pkg_resources, imp + import sys, pkg_resources + from importlib.machinery import ExtensionFileLoader __file__ = pkg_resources.resource_filename(__name__, %r) __loader__ = None; del __bootstrap__, __loader__ - imp.load_dynamic(__name__,__file__) + ExtensionFileLoader(__name__,__file__).load_module() __bootstrap__() """).lstrip() with open(pyfile, 'w') as f: @@ -278,13 +280,19 @@ class bdist_egg(Command): if ep is None: return 'w' # not an eggsecutable, do it the usual way. + warnings.warn( + "Eggsecutables are deprecated and will be removed in a future " + "version.", + SetuptoolsDeprecationWarning + ) + if not ep.attrs or ep.extras: raise DistutilsSetupError( "eggsecutable entry point (%r) cannot have 'extras' " "or refer to a module" % (ep,) ) - pyver = sys.version[:3] + pyver = '{}.{}'.format(*sys.version_info) pkg = ep.module_name full = '.'.join(ep.attrs) base = ep.attrs[0] diff --git a/venv/lib/python3.8/site-packages/setuptools/command/bdist_wininst.py b/venv/lib/python3.8/site-packages/setuptools/command/bdist_wininst.py index 073de97..ff4b634 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/bdist_wininst.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/bdist_wininst.py @@ -1,4 +1,7 @@ import distutils.command.bdist_wininst as orig +import warnings + +from setuptools import SetuptoolsDeprecationWarning class bdist_wininst(orig.bdist_wininst): @@ -14,6 +17,12 @@ class bdist_wininst(orig.bdist_wininst): return cmd def run(self): + warnings.warn( + "bdist_wininst is deprecated and will be removed in a future " + "version. Use bdist_wheel (wheel packages) instead.", + SetuptoolsDeprecationWarning + ) + self._is_running = True try: orig.bdist_wininst.run(self) diff --git a/venv/lib/python3.8/site-packages/setuptools/command/build_clib.py b/venv/lib/python3.8/site-packages/setuptools/command/build_clib.py index 09caff6..67ce244 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/build_clib.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/build_clib.py @@ -25,9 +25,9 @@ class build_clib(orig.build_clib): sources = build_info.get('sources') if sources is None or not isinstance(sources, (list, tuple)): raise DistutilsSetupError( - "in 'libraries' option (library '%s'), " - "'sources' must be present and must be " - "a list of source filenames" % lib_name) + "in 'libraries' option (library '%s'), " + "'sources' must be present and must be " + "a list of source filenames" % lib_name) sources = list(sources) log.info("building '%s' library", lib_name) @@ -38,9 +38,9 @@ class build_clib(orig.build_clib): obj_deps = build_info.get('obj_deps', dict()) if not isinstance(obj_deps, dict): raise DistutilsSetupError( - "in 'libraries' option (library '%s'), " - "'obj_deps' must be a dictionary of " - "type 'source: list'" % lib_name) + "in 'libraries' option (library '%s'), " + "'obj_deps' must be a dictionary of " + "type 'source: list'" % lib_name) dependencies = [] # Get the global dependencies that are specified by the '' key. @@ -48,9 +48,9 @@ class build_clib(orig.build_clib): global_deps = obj_deps.get('', list()) if not isinstance(global_deps, (list, tuple)): raise DistutilsSetupError( - "in 'libraries' option (library '%s'), " - "'obj_deps' must be a dictionary of " - "type 'source: list'" % lib_name) + "in 'libraries' option (library '%s'), " + "'obj_deps' must be a dictionary of " + "type 'source: list'" % lib_name) # Build the list to be used by newer_pairwise_group # each source will be auto-added to its dependencies. @@ -60,39 +60,42 @@ class build_clib(orig.build_clib): extra_deps = obj_deps.get(source, list()) if not isinstance(extra_deps, (list, tuple)): raise DistutilsSetupError( - "in 'libraries' option (library '%s'), " - "'obj_deps' must be a dictionary of " - "type 'source: list'" % lib_name) + "in 'libraries' option (library '%s'), " + "'obj_deps' must be a dictionary of " + "type 'source: list'" % lib_name) src_deps.extend(extra_deps) dependencies.append(src_deps) expected_objects = self.compiler.object_filenames( - sources, - output_dir=self.build_temp - ) + sources, + output_dir=self.build_temp, + ) - if newer_pairwise_group(dependencies, expected_objects) != ([], []): + if ( + newer_pairwise_group(dependencies, expected_objects) + != ([], []) + ): # First, compile the source code to object files in the library # directory. (This should probably change to putting object # files in a temporary build directory.) macros = build_info.get('macros') include_dirs = build_info.get('include_dirs') cflags = build_info.get('cflags') - objects = self.compiler.compile( - sources, - output_dir=self.build_temp, - macros=macros, - include_dirs=include_dirs, - extra_postargs=cflags, - debug=self.debug - ) + self.compiler.compile( + sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=include_dirs, + extra_postargs=cflags, + debug=self.debug + ) # Now "link" the object files together into a static library. # (On Unix at least, this isn't really linking -- it just # builds an archive. Whatever.) self.compiler.create_static_lib( - expected_objects, - lib_name, - output_dir=self.build_clib, - debug=self.debug - ) + expected_objects, + lib_name, + output_dir=self.build_clib, + debug=self.debug + ) diff --git a/venv/lib/python3.8/site-packages/setuptools/command/build_ext.py b/venv/lib/python3.8/site-packages/setuptools/command/build_ext.py index daa8e4f..0eb29ad 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/build_ext.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/build_ext.py @@ -14,7 +14,8 @@ from setuptools.extern import six if six.PY2: import imp - EXTENSION_SUFFIXES = [s for s, _, tp in imp.get_suffixes() if tp == imp.C_EXTENSION] + EXTENSION_SUFFIXES = [ + s for s, _, tp in imp.get_suffixes() if tp == imp.C_EXTENSION] else: from importlib.machinery import EXTENSION_SUFFIXES @@ -29,7 +30,7 @@ except ImportError: # make sure _config_vars is initialized get_config_var("LDSHARED") -from distutils.sysconfig import _config_vars as _CONFIG_VARS +from distutils.sysconfig import _config_vars as _CONFIG_VARS # noqa def _customize_compiler_for_shlib(compiler): @@ -65,7 +66,9 @@ elif os.name != 'nt': except ImportError: pass -if_dl = lambda s: s if have_rtld else '' + +def if_dl(s): + return s if have_rtld else '' def get_abi3_suffix(): @@ -113,7 +116,7 @@ class build_ext(_build_ext): if fullname in self.ext_map: ext = self.ext_map[fullname] use_abi3 = ( - six.PY3 + not six.PY2 and getattr(ext, 'py_limited_api') and get_abi3_suffix() ) @@ -251,7 +254,8 @@ class build_ext(_build_ext): '\n'.join([ "def __bootstrap__():", " global __bootstrap__, __file__, __loader__", - " import sys, os, pkg_resources, imp" + if_dl(", dl"), + " import sys, os, pkg_resources" + if_dl(", dl"), + " from importlib.machinery import ExtensionFileLoader", " __file__ = pkg_resources.resource_filename" "(__name__,%r)" % os.path.basename(ext._file_name), @@ -263,7 +267,8 @@ class build_ext(_build_ext): " try:", " os.chdir(os.path.dirname(__file__))", if_dl(" sys.setdlopenflags(dl.RTLD_NOW)"), - " imp.load_dynamic(__name__,__file__)", + " ExtensionFileLoader(__name__,", + " __file__).load_module()", " finally:", if_dl(" sys.setdlopenflags(old_flags)"), " os.chdir(old_dir)", diff --git a/venv/lib/python3.8/site-packages/setuptools/command/build_py.py b/venv/lib/python3.8/site-packages/setuptools/command/build_py.py index b0314fd..9d0288a 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/build_py.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/build_py.py @@ -7,6 +7,7 @@ import textwrap import io import distutils.errors import itertools +import stat from setuptools.extern import six from setuptools.extern.six.moves import map, filter, filterfalse @@ -20,6 +21,10 @@ except ImportError: "do nothing" +def make_writable(target): + os.chmod(target, os.stat(target).st_mode | stat.S_IWRITE) + + class build_py(orig.build_py, Mixin2to3): """Enhanced 'build_py' command that includes data files with packages @@ -121,6 +126,7 @@ class build_py(orig.build_py, Mixin2to3): self.mkpath(os.path.dirname(target)) srcfile = os.path.join(src_dir, filename) outf, copied = self.copy_file(srcfile, target) + make_writable(target) srcfile = os.path.abspath(srcfile) if (copied and srcfile in self.distribution.convert_2to3_doctests): diff --git a/venv/lib/python3.8/site-packages/setuptools/command/develop.py b/venv/lib/python3.8/site-packages/setuptools/command/develop.py index 009e4f9..e7e03cd 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/develop.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/develop.py @@ -108,7 +108,7 @@ class develop(namespaces.DevelopInstaller, easy_install): return path_to_setup def install_for_development(self): - if six.PY3 and getattr(self.distribution, 'use_2to3', False): + if not six.PY2 and getattr(self.distribution, 'use_2to3', False): # If we run 2to3 we can not do this inplace: # Ensure metadata is up-to-date @@ -139,7 +139,6 @@ class develop(namespaces.DevelopInstaller, easy_install): self.reinitialize_command('build_ext', inplace=1) self.run_command('build_ext') - self.install_site_py() # ensure that target dir is site-safe if setuptools.bootstrap_install_from: self.easy_install(setuptools.bootstrap_install_from) setuptools.bootstrap_install_from = None diff --git a/venv/lib/python3.8/site-packages/setuptools/command/easy_install.py b/venv/lib/python3.8/site-packages/setuptools/command/easy_install.py index 06c9827..bcbd4f5 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/easy_install.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/easy_install.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python """ Easy Install ------------ @@ -64,7 +63,7 @@ from pkg_resources import ( Distribution, PathMetadata, EggMetadata, WorkingSet, DistributionNotFound, VersionConflict, DEVELOP_DIST, ) -import pkg_resources.py31compat +import pkg_resources __metaclass__ = type @@ -121,7 +120,8 @@ else: return False -_one_liner = lambda text: textwrap.dedent(text).strip().replace('\n', '; ') +def _one_liner(text): + return textwrap.dedent(text).strip().replace('\n', '; ') class easy_install(Command): @@ -156,19 +156,16 @@ class easy_install(Command): "allow building eggs from local checkouts"), ('version', None, "print version information and exit"), ('no-find-links', None, - "Don't load find-links defined in packages being installed") + "Don't load find-links defined in packages being installed"), + ('user', None, "install in user site-package '%s'" % site.USER_SITE) ] boolean_options = [ 'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy', 'editable', - 'no-deps', 'local-snapshots-ok', 'version' + 'no-deps', 'local-snapshots-ok', 'version', + 'user' ] - if site.ENABLE_USER_SITE: - help_msg = "install in user site-package '%s'" % site.USER_SITE - user_options.append(('user', None, help_msg)) - boolean_options.append('user') - negative_opt = {'always-unzip': 'zip-ok'} create_index = PackageIndex @@ -208,7 +205,6 @@ class easy_install(Command): self.pth_file = self.always_copy_from = None self.site_dirs = None self.installed_projects = {} - self.sitepy_installed = False # Always read easy_install options, even if we are subclassed, or have # an independent instance created. This ensures that defaults will # always come from the standard configuration file(s)' "easy_install" @@ -241,7 +237,7 @@ class easy_install(Command): """ Render the Setuptools version and installation details, then exit. """ - ver = sys.version[:3] + ver = '{}.{}'.format(*sys.version_info) dist = get_distribution('setuptools') tmpl = 'setuptools {dist.version} from {dist.location} (Python {ver})' print(tmpl.format(**locals())) @@ -272,6 +268,9 @@ class easy_install(Command): self.config_vars['userbase'] = self.install_userbase self.config_vars['usersite'] = self.install_usersite + elif self.user: + log.warn("WARNING: The user site-packages directory is disabled.") + self._fix_install_dir_for_user_site() self.expand_basedirs() @@ -356,8 +355,10 @@ class easy_install(Command): self.optimize = int(self.optimize) if not (0 <= self.optimize <= 2): raise ValueError - except ValueError: - raise DistutilsOptionError("--optimize must be 0, 1, or 2") + except ValueError as e: + raise DistutilsOptionError( + "--optimize must be 0, 1, or 2" + ) from e if self.editable and not self.build_directory: raise DistutilsArgError( @@ -410,7 +411,13 @@ class easy_install(Command): ] self._expand_attrs(dirs) - def run(self): + def run(self, show_deprecation=True): + if show_deprecation: + self.announce( + "WARNING: The easy_install command is deprecated " + "and will be removed in a future version.", + log.WARN, + ) if self.verbose != self.distribution.verbose: log.set_verbosity(self.verbose) try: @@ -453,6 +460,12 @@ class easy_install(Command): instdir = normalize_path(self.install_dir) pth_file = os.path.join(instdir, 'easy-install.pth') + if not os.path.exists(instdir): + try: + os.makedirs(instdir) + except (OSError, IOError): + self.cant_write_to_target() + # Is it a configured, PYTHONPATH, implicit, or explicit site dir? is_site_dir = instdir in self.all_site_dirs @@ -472,8 +485,9 @@ class easy_install(Command): self.cant_write_to_target() if not is_site_dir and not self.multi_version: - # Can't install non-multi to non-site dir - raise DistutilsError(self.no_default_version_msg()) + # Can't install non-multi to non-site dir with easy_install + pythonpath = os.environ.get('PYTHONPATH', '') + log.warn(self.__no_default_msg, self.install_dir, pythonpath) if is_site_dir: if self.pth_file is None: @@ -481,12 +495,8 @@ class easy_install(Command): else: self.pth_file = None - if instdir not in map(normalize_path, _pythonpath()): - # only PYTHONPATH dirs need a site.py, so pretend it's there - self.sitepy_installed = True - elif self.multi_version and not os.path.exists(pth_file): - self.sitepy_installed = True # don't need site.py in this case - self.pth_file = None # and don't create a .pth file + if self.multi_version and not os.path.exists(pth_file): + self.pth_file = None # don't create a .pth file self.install_dir = instdir __cant_write_msg = textwrap.dedent(""" @@ -501,13 +511,13 @@ class easy_install(Command): the distutils default setting) was: %s - """).lstrip() + """).lstrip() # noqa __not_exists_id = textwrap.dedent(""" This directory does not currently exist. Please create it and try again, or choose a different installation directory (using the -d or --install-dir option). - """).lstrip() + """).lstrip() # noqa __access_msg = textwrap.dedent(""" Perhaps your account does not have write access to this directory? If the @@ -523,7 +533,7 @@ class easy_install(Command): https://setuptools.readthedocs.io/en/latest/easy_install.html Please make the appropriate changes for your system and try again. - """).lstrip() + """).lstrip() # noqa def cant_write_to_target(self): msg = self.__cant_write_msg % (sys.exc_info()[1], self.install_dir,) @@ -551,7 +561,7 @@ class easy_install(Command): if ok_exists: os.unlink(ok_file) dirname = os.path.dirname(ok_file) - pkg_resources.py31compat.makedirs(dirname, exist_ok=True) + os.makedirs(dirname, exist_ok=True) f = open(pth_file, 'w') except (OSError, IOError): self.cant_write_to_target() @@ -643,9 +653,6 @@ class easy_install(Command): os.path.exists(tmpdir) and rmtree(rmtree_safe(tmpdir)) def easy_install(self, spec, deps=False): - if not self.editable: - self.install_site_py() - with self._tmpdir() as tmpdir: if not isinstance(spec, Requirement): if URL_SCHEME(spec): @@ -752,9 +759,9 @@ class easy_install(Command): [requirement], self.local_index, self.easy_install ) except DistributionNotFound as e: - raise DistutilsError(str(e)) + raise DistutilsError(str(e)) from e except VersionConflict as e: - raise DistutilsError(e.report()) + raise DistutilsError(e.report()) from e if self.always_copy or self.always_copy_from: # Force all the relevant distros to be copied or activated for dist in distros: @@ -1087,13 +1094,13 @@ class easy_install(Command): pkg_resources.require("%(name)s") # latest installed version pkg_resources.require("%(name)s==%(version)s") # this exact version pkg_resources.require("%(name)s>=%(version)s") # this version or higher - """).lstrip() + """).lstrip() # noqa __id_warning = textwrap.dedent(""" Note also that the installation directory must be on sys.path at runtime for this to work. (e.g. by being the application's script directory, by being on PYTHONPATH, or by being added to sys.path by your code.) - """) + """) # noqa def installation_report(self, req, dist, what="Installed"): """Helpful installation message for display to package users""" @@ -1118,7 +1125,7 @@ class easy_install(Command): %(python)s setup.py develop See the setuptools documentation for the "develop" command for more info. - """).lstrip() + """).lstrip() # noqa def report_editable(self, spec, setup_script): dirname = os.path.dirname(setup_script) @@ -1143,7 +1150,9 @@ class easy_install(Command): try: run_setup(setup_script, args) except SystemExit as v: - raise DistutilsError("Setup script exited with %s" % (v.args[0],)) + raise DistutilsError( + "Setup script exited with %s" % (v.args[0],) + ) from v def build_and_install(self, setup_script, setup_base): args = ['bdist_egg', '--dist-dir'] @@ -1180,8 +1189,7 @@ class easy_install(Command): # to the setup.cfg file. ei_opts = self.distribution.get_option_dict('easy_install').copy() fetch_directives = ( - 'find_links', 'site_dirs', 'index_url', 'optimize', - 'site_dirs', 'allow_hosts', + 'find_links', 'site_dirs', 'index_url', 'optimize', 'allow_hosts', ) fetch_options = {} for key, val in ei_opts.items(): @@ -1302,43 +1310,8 @@ class easy_install(Command): https://setuptools.readthedocs.io/en/latest/easy_install.html#custom-installation-locations - Please make the appropriate changes for your system and try again.""").lstrip() - - def no_default_version_msg(self): - template = self.__no_default_msg - return template % (self.install_dir, os.environ.get('PYTHONPATH', '')) - - def install_site_py(self): - """Make sure there's a site.py in the target dir, if needed""" - - if self.sitepy_installed: - return # already did it, or don't need to - - sitepy = os.path.join(self.install_dir, "site.py") - source = resource_string("setuptools", "site-patch.py") - source = source.decode('utf-8') - current = "" - - if os.path.exists(sitepy): - log.debug("Checking existing site.py in %s", self.install_dir) - with io.open(sitepy) as strm: - current = strm.read() - - if not current.startswith('def __boot():'): - raise DistutilsError( - "%s is not a setuptools-generated site.py; please" - " remove it." % sitepy - ) - - if current != source: - log.info("Creating %s", sitepy) - if not self.dry_run: - ensure_directory(sitepy) - with io.open(sitepy, 'w', encoding='utf-8') as strm: - strm.write(source) - self.byte_compile([sitepy]) - - self.sitepy_installed = True + Please make the appropriate changes for your system and try again. + """).strip() def create_home_path(self): """Create directories under ~.""" @@ -1412,7 +1385,7 @@ def get_site_dirs(): os.path.join( prefix, "lib", - "python" + sys.version[:3], + "python{}.{}".format(*sys.version_info), "site-packages", ), os.path.join(prefix, "lib", "site-python"), @@ -1433,7 +1406,7 @@ def get_site_dirs(): home, 'Library', 'Python', - sys.version[:3], + '{}.{}'.format(*sys.version_info), 'site-packages', ) sitedirs.append(home_sp) @@ -1562,7 +1535,7 @@ def get_exe_prefixes(exe_filename): continue if parts[0].upper() in ('PURELIB', 'PLATLIB'): contents = z.read(name) - if six.PY3: + if not six.PY2: contents = contents.decode() for pth in yield_lines(contents): pth = pth.strip().replace('\\', '/') @@ -2063,17 +2036,38 @@ class ScriptWriter: template = textwrap.dedent(r""" # EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r - __requires__ = %(spec)r import re import sys - from pkg_resources import load_entry_point + + # for compatibility with easy_install; see #2198 + __requires__ = %(spec)r + + try: + from importlib.metadata import distribution + except ImportError: + try: + from importlib_metadata import distribution + except ImportError: + from pkg_resources import load_entry_point + + + def importlib_load_entry_point(spec, group, name): + dist_name, _, _ = spec.partition('==') + matches = ( + entry_point + for entry_point in distribution(dist_name).entry_points + if entry_point.group == group and entry_point.name == name + ) + return next(matches).load() + + + globals().setdefault('load_entry_point', importlib_load_entry_point) + if __name__ == '__main__': sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) - sys.exit( - load_entry_point(%(spec)r, %(group)r, %(name)r)() - ) - """).lstrip() + sys.exit(load_entry_point(%(spec)r, %(group)r, %(name)r)()) + """).lstrip() command_spec_class = CommandSpec @@ -2088,7 +2082,8 @@ class ScriptWriter: @classmethod def get_script_header(cls, script_text, executable=None, wininst=False): # for backward compatibility - warnings.warn("Use get_header", EasyInstallDeprecationWarning, stacklevel=2) + warnings.warn( + "Use get_header", EasyInstallDeprecationWarning, stacklevel=2) if wininst: executable = "python.exe" return cls.get_header(script_text, executable) @@ -2337,6 +2332,8 @@ def _patch_usage(): finally: distutils.core.gen_usage = saved + class EasyInstallDeprecationWarning(SetuptoolsDeprecationWarning): - """Class for warning about deprecations in EasyInstall in SetupTools. Not ignored by default, unlike DeprecationWarning.""" - + """ + Warning for EasyInstall deprecations, bypassing suppression. + """ diff --git a/venv/lib/python3.8/site-packages/setuptools/command/egg_info.py b/venv/lib/python3.8/site-packages/setuptools/command/egg_info.py index 5d8f451..0855207 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/egg_info.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/egg_info.py @@ -33,6 +33,7 @@ from setuptools.glob import glob from setuptools.extern import packaging from setuptools import SetuptoolsDeprecationWarning + def translate_pattern(glob): """ Translate a file path glob like '*.txt' in to a regular expression. @@ -113,7 +114,7 @@ def translate_pattern(glob): pat += sep pat += r'\Z' - return re.compile(pat, flags=re.MULTILINE|re.DOTALL) + return re.compile(pat, flags=re.MULTILINE | re.DOTALL) class InfoCommon: @@ -207,11 +208,11 @@ class egg_info(InfoCommon, Command): list( parse_requirements(spec % (self.egg_name, self.egg_version)) ) - except ValueError: + except ValueError as e: raise distutils.errors.DistutilsOptionError( "Invalid distribution name or version syntax: %s-%s" % (self.egg_name, self.egg_version) - ) + ) from e if self.egg_base is None: dirs = self.distribution.package_dir @@ -266,7 +267,7 @@ class egg_info(InfoCommon, Command): to the file. """ log.info("writing %s to %s", what, filename) - if six.PY3: + if not six.PY2: data = data.encode("utf-8") if not self.dry_run: f = open(filename, 'wb') @@ -637,7 +638,9 @@ def warn_depends_obsolete(cmd, basename, filename): def _write_requirements(stream, reqs): lines = yield_lines(reqs or ()) - append_cr = lambda line: line + '\n' + + def append_cr(line): + return line + '\n' lines = map(append_cr, lines) stream.writelines(lines) @@ -703,7 +706,8 @@ def get_pkg_info_revision(): Get a -r### off of PKG-INFO Version in case this is an sdist of a subversion revision. """ - warnings.warn("get_pkg_info_revision is deprecated.", EggInfoDeprecationWarning) + warnings.warn( + "get_pkg_info_revision is deprecated.", EggInfoDeprecationWarning) if os.path.exists('PKG-INFO'): with io.open('PKG-INFO') as f: for line in f: @@ -714,4 +718,4 @@ def get_pkg_info_revision(): class EggInfoDeprecationWarning(SetuptoolsDeprecationWarning): - """Class for warning about deprecations in eggInfo in setupTools. Not ignored by default, unlike DeprecationWarning.""" + """Deprecated behavior warning for EggInfo, bypassing suppression.""" diff --git a/venv/lib/python3.8/site-packages/setuptools/command/install.py b/venv/lib/python3.8/site-packages/setuptools/command/install.py index 31a5ddb..72b9a3e 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/install.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/install.py @@ -114,7 +114,7 @@ class install(orig.install): args.insert(0, setuptools.bootstrap_install_from) cmd.args = args - cmd.run() + cmd.run(show_deprecation=False) setuptools.bootstrap_install_from = None diff --git a/venv/lib/python3.8/site-packages/setuptools/command/install_lib.py b/venv/lib/python3.8/site-packages/setuptools/command/install_lib.py index 07d6593..2e9d875 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/install_lib.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/install_lib.py @@ -77,7 +77,8 @@ class install_lib(orig.install_lib): if not hasattr(sys, 'implementation'): return - base = os.path.join('__pycache__', '__init__.' + sys.implementation.cache_tag) + base = os.path.join( + '__pycache__', '__init__.' + sys.implementation.cache_tag) yield base + '.pyc' yield base + '.pyo' yield base + '.opt-1.pyc' diff --git a/venv/lib/python3.8/site-packages/setuptools/command/install_scripts.py b/venv/lib/python3.8/site-packages/setuptools/command/install_scripts.py index 1623427..8c9a15e 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/install_scripts.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/install_scripts.py @@ -32,8 +32,11 @@ class install_scripts(orig.install_scripts): ) bs_cmd = self.get_finalized_command('build_scripts') exec_param = getattr(bs_cmd, 'executable', None) - bw_cmd = self.get_finalized_command("bdist_wininst") - is_wininst = getattr(bw_cmd, '_is_running', False) + try: + bw_cmd = self.get_finalized_command("bdist_wininst") + is_wininst = getattr(bw_cmd, '_is_running', False) + except ImportError: + is_wininst = False writer = ei.ScriptWriter if is_wininst: exec_param = "python.exe" diff --git a/venv/lib/python3.8/site-packages/setuptools/command/py36compat.py b/venv/lib/python3.8/site-packages/setuptools/command/py36compat.py index 61063e7..2886055 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/py36compat.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/py36compat.py @@ -132,5 +132,5 @@ class sdist_add_defaults: if hasattr(sdist.sdist, '_add_defaults_standards'): # disable the functionality already available upstream - class sdist_add_defaults: + class sdist_add_defaults: # noqa pass diff --git a/venv/lib/python3.8/site-packages/setuptools/command/register.py b/venv/lib/python3.8/site-packages/setuptools/command/register.py index 98bc015..b8266b9 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/register.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/register.py @@ -1,18 +1,18 @@ from distutils import log import distutils.command.register as orig +from setuptools.errors import RemovedCommandError + class register(orig.register): - __doc__ = orig.register.__doc__ + """Formerly used to register packages on PyPI.""" def run(self): - try: - # Make sure that we are using valid current name/version info - self.run_command('egg_info') - orig.register.run(self) - finally: - self.announce( - "WARNING: Registering is deprecated, use twine to " - "upload instead (https://pypi.org/p/twine/)", - log.WARN - ) + msg = ( + "The register command has been removed, use twine to upload " + + "instead (https://pypi.org/p/twine)" + ) + + self.announce("ERROR: " + msg, log.ERROR) + + raise RemovedCommandError(msg) diff --git a/venv/lib/python3.8/site-packages/setuptools/command/rotate.py b/venv/lib/python3.8/site-packages/setuptools/command/rotate.py index b89353f..e398834 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/rotate.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/rotate.py @@ -36,8 +36,8 @@ class rotate(Command): raise DistutilsOptionError("Must specify number of files to keep") try: self.keep = int(self.keep) - except ValueError: - raise DistutilsOptionError("--keep must be an integer") + except ValueError as e: + raise DistutilsOptionError("--keep must be an integer") from e if isinstance(self.match, six.string_types): self.match = [ convert_path(p.strip()) for p in self.match.split(',') diff --git a/venv/lib/python3.8/site-packages/setuptools/command/sdist.py b/venv/lib/python3.8/site-packages/setuptools/command/sdist.py index dc25398..8c3438e 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/sdist.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/sdist.py @@ -5,7 +5,7 @@ import sys import io import contextlib -from setuptools.extern import six +from setuptools.extern import six, ordered_set from .py36compat import sdist_add_defaults @@ -121,19 +121,40 @@ class sdist(sdist_add_defaults, orig.sdist): if has_leaky_handle: read_template = __read_template_hack + def _add_defaults_optional(self): + if six.PY2: + sdist_add_defaults._add_defaults_optional(self) + else: + super()._add_defaults_optional() + if os.path.isfile('pyproject.toml'): + self.filelist.append('pyproject.toml') + def _add_defaults_python(self): """getting python files""" if self.distribution.has_pure_modules(): build_py = self.get_finalized_command('build_py') self.filelist.extend(build_py.get_source_files()) - # This functionality is incompatible with include_package_data, and - # will in fact create an infinite recursion if include_package_data - # is True. Use of include_package_data will imply that - # distutils-style automatic handling of package_data is disabled - if not self.distribution.include_package_data: - for _, src_dir, _, filenames in build_py.data_files: - self.filelist.extend([os.path.join(src_dir, filename) - for filename in filenames]) + self._add_data_files(self._safe_data_files(build_py)) + + def _safe_data_files(self, build_py): + """ + Extracting data_files from build_py is known to cause + infinite recursion errors when `include_package_data` + is enabled, so suppress it in that case. + """ + if self.distribution.include_package_data: + return () + return build_py.data_files + + def _add_data_files(self, data_files): + """ + Add data files as found in build_py.data_files. + """ + self.filelist.extend( + os.path.join(src_dir, name) + for _, src_dir, _, filenames in data_files + for name in filenames + ) def _add_defaults_data_files(self): try: @@ -186,7 +207,7 @@ class sdist(sdist_add_defaults, orig.sdist): manifest = open(self.manifest, 'rb') for line in manifest: # The manifest must contain UTF-8. See #303. - if six.PY3: + if not six.PY2: try: line = line.decode('UTF-8') except UnicodeDecodeError: @@ -200,10 +221,12 @@ class sdist(sdist_add_defaults, orig.sdist): manifest.close() def check_license(self): - """Checks if license_file' is configured and adds it to - 'self.filelist' if the value contains a valid path. + """Checks if license_file' or 'license_files' is configured and adds any + valid paths to 'self.filelist'. """ + files = ordered_set.OrderedSet() + opts = self.distribution.get_option_dict('metadata') # ignore the source of the value @@ -211,11 +234,19 @@ class sdist(sdist_add_defaults, orig.sdist): if license_file is None: log.debug("'license_file' option was not specified") - return + else: + files.add(license_file) - if not os.path.exists(license_file): - log.warn("warning: Failed to find the configured license file '%s'", - license_file) - return + try: + files.update(self.distribution.metadata.license_files) + except TypeError: + log.warn("warning: 'license_files' option is malformed") - self.filelist.append(license_file) + for f in files: + if not os.path.exists(f): + log.warn( + "warning: Failed to find the configured license file '%s'", + f) + files.remove(f) + + self.filelist.extend(files) diff --git a/venv/lib/python3.8/site-packages/setuptools/command/test.py b/venv/lib/python3.8/site-packages/setuptools/command/test.py index 973e4eb..2d83967 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/test.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/test.py @@ -74,7 +74,7 @@ class NonDataProperty: class test(Command): """Command to run unit tests after in-place build""" - description = "run unit tests after in-place build" + description = "run unit tests after in-place build (deprecated)" user_options = [ ('test-module=', 'm', "Run 'test_suite' in specified module"), @@ -129,7 +129,8 @@ class test(Command): @contextlib.contextmanager def project_on_sys_path(self, include_dists=[]): - with_2to3 = six.PY3 and getattr(self.distribution, 'use_2to3', False) + with_2to3 = not six.PY2 and getattr( + self.distribution, 'use_2to3', False) if with_2to3: # If we run 2to3 we can not do this inplace: @@ -214,6 +215,14 @@ class test(Command): return itertools.chain(ir_d, tr_d, er_d) def run(self): + self.announce( + "WARNING: Testing via this command is deprecated and will be " + "removed in a future version. Users looking for a generic test " + "entry point independent of test runner are encouraged to use " + "tox.", + log.WARN, + ) + installed_dists = self.install_dists(self.distribution) cmd = ' '.join(self._argv) @@ -232,7 +241,7 @@ class test(Command): # Purge modules under test from sys.modules. The test loader will # re-import them from the build location. Required when 2to3 is used # with namespace packages. - if six.PY3 and getattr(self.distribution, 'use_2to3', False): + if not six.PY2 and getattr(self.distribution, 'use_2to3', False): module = self.test_suite.split('.')[0] if module in _namespace_packages: del_modules = [] diff --git a/venv/lib/python3.8/site-packages/setuptools/command/upload.py b/venv/lib/python3.8/site-packages/setuptools/command/upload.py index 6db8888..ec7f81e 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/upload.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/upload.py @@ -1,196 +1,17 @@ -import io -import os -import hashlib -import getpass - -from base64 import standard_b64encode - from distutils import log from distutils.command import upload as orig -from distutils.spawn import spawn -from distutils.errors import DistutilsError - -from setuptools.extern.six.moves.urllib.request import urlopen, Request -from setuptools.extern.six.moves.urllib.error import HTTPError -from setuptools.extern.six.moves.urllib.parse import urlparse +from setuptools.errors import RemovedCommandError class upload(orig.upload): - """ - Override default upload behavior to obtain password - in a variety of different ways. - """ + """Formerly used to upload packages to PyPI.""" + def run(self): - try: - orig.upload.run(self) - finally: - self.announce( - "WARNING: Uploading via this command is deprecated, use twine " - "to upload instead (https://pypi.org/p/twine/)", - log.WARN - ) - - def finalize_options(self): - orig.upload.finalize_options(self) - self.username = ( - self.username or - getpass.getuser() - ) - # Attempt to obtain password. Short circuit evaluation at the first - # sign of success. - self.password = ( - self.password or - self._load_password_from_keyring() or - self._prompt_for_password() + msg = ( + "The upload command has been removed, use twine to upload " + + "instead (https://pypi.org/p/twine)" ) - def upload_file(self, command, pyversion, filename): - # Makes sure the repository URL is compliant - schema, netloc, url, params, query, fragments = \ - urlparse(self.repository) - if params or query or fragments: - raise AssertionError("Incompatible url %s" % self.repository) - - if schema not in ('http', 'https'): - raise AssertionError("unsupported schema " + schema) - - # Sign if requested - if self.sign: - gpg_args = ["gpg", "--detach-sign", "-a", filename] - if self.identity: - gpg_args[2:2] = ["--local-user", self.identity] - spawn(gpg_args, - dry_run=self.dry_run) - - # Fill in the data - send all the meta-data in case we need to - # register a new release - with open(filename, 'rb') as f: - content = f.read() - - meta = self.distribution.metadata - - data = { - # action - ':action': 'file_upload', - 'protocol_version': '1', - - # identify release - 'name': meta.get_name(), - 'version': meta.get_version(), - - # file content - 'content': (os.path.basename(filename), content), - 'filetype': command, - 'pyversion': pyversion, - 'md5_digest': hashlib.md5(content).hexdigest(), - - # additional meta-data - 'metadata_version': str(meta.get_metadata_version()), - 'summary': meta.get_description(), - 'home_page': meta.get_url(), - 'author': meta.get_contact(), - 'author_email': meta.get_contact_email(), - 'license': meta.get_licence(), - 'description': meta.get_long_description(), - 'keywords': meta.get_keywords(), - 'platform': meta.get_platforms(), - 'classifiers': meta.get_classifiers(), - 'download_url': meta.get_download_url(), - # PEP 314 - 'provides': meta.get_provides(), - 'requires': meta.get_requires(), - 'obsoletes': meta.get_obsoletes(), - } - - data['comment'] = '' - - if self.sign: - data['gpg_signature'] = (os.path.basename(filename) + ".asc", - open(filename+".asc", "rb").read()) - - # set up the authentication - user_pass = (self.username + ":" + self.password).encode('ascii') - # The exact encoding of the authentication string is debated. - # Anyway PyPI only accepts ascii for both username or password. - auth = "Basic " + standard_b64encode(user_pass).decode('ascii') - - # Build up the MIME payload for the POST data - boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' - sep_boundary = b'\r\n--' + boundary.encode('ascii') - end_boundary = sep_boundary + b'--\r\n' - body = io.BytesIO() - for key, value in data.items(): - title = '\r\nContent-Disposition: form-data; name="%s"' % key - # handle multiple entries for the same name - if not isinstance(value, list): - value = [value] - for value in value: - if type(value) is tuple: - title += '; filename="%s"' % value[0] - value = value[1] - else: - value = str(value).encode('utf-8') - body.write(sep_boundary) - body.write(title.encode('utf-8')) - body.write(b"\r\n\r\n") - body.write(value) - body.write(end_boundary) - body = body.getvalue() - - msg = "Submitting %s to %s" % (filename, self.repository) - self.announce(msg, log.INFO) - - # build the Request - headers = { - 'Content-type': 'multipart/form-data; boundary=%s' % boundary, - 'Content-length': str(len(body)), - 'Authorization': auth, - } - - request = Request(self.repository, data=body, - headers=headers) - # send the data - try: - result = urlopen(request) - status = result.getcode() - reason = result.msg - except HTTPError as e: - status = e.code - reason = e.msg - except OSError as e: - self.announce(str(e), log.ERROR) - raise - - if status == 200: - self.announce('Server response (%s): %s' % (status, reason), - log.INFO) - if self.show_response: - text = getattr(self, '_read_pypi_response', - lambda x: None)(result) - if text is not None: - msg = '\n'.join(('-' * 75, text, '-' * 75)) - self.announce(msg, log.INFO) - else: - msg = 'Upload failed (%s): %s' % (status, reason) - self.announce(msg, log.ERROR) - raise DistutilsError(msg) - - def _load_password_from_keyring(self): - """ - Attempt to load password from keyring. Suppress Exceptions. - """ - try: - keyring = __import__('keyring') - return keyring.get_password(self.repository, self.username) - except Exception: - pass - - def _prompt_for_password(self): - """ - Prompt for a password on the tty. Suppress Exceptions. - """ - try: - return getpass.getpass() - except (Exception, KeyboardInterrupt): - pass + self.announce("ERROR: " + msg, log.ERROR) + raise RemovedCommandError(msg) diff --git a/venv/lib/python3.8/site-packages/setuptools/command/upload_docs.py b/venv/lib/python3.8/site-packages/setuptools/command/upload_docs.py index 07aa564..0351da7 100644 --- a/venv/lib/python3.8/site-packages/setuptools/command/upload_docs.py +++ b/venv/lib/python3.8/site-packages/setuptools/command/upload_docs.py @@ -24,7 +24,7 @@ from .upload import upload def _encode(s): - errors = 'surrogateescape' if six.PY3 else 'strict' + errors = 'strict' if six.PY2 else 'surrogateescape' return s.encode('utf-8', errors) @@ -127,8 +127,8 @@ class upload_docs(upload): """ Build up the MIME payload for the POST data """ - boundary = b'--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' - sep_boundary = b'\n--' + boundary + boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' + sep_boundary = b'\n--' + boundary.encode('ascii') end_boundary = sep_boundary + b'--' end_items = end_boundary, b"\n", builder = functools.partial( @@ -138,7 +138,7 @@ class upload_docs(upload): part_groups = map(builder, data.items()) parts = itertools.chain.from_iterable(part_groups) body_items = itertools.chain(parts, end_items) - content_type = 'multipart/form-data; boundary=%s' % boundary.decode('ascii') + content_type = 'multipart/form-data; boundary=%s' % boundary return b''.join(body_items), content_type def upload_file(self, filename): @@ -153,7 +153,7 @@ class upload_docs(upload): # set up the authentication credentials = _encode(self.username + ':' + self.password) credentials = standard_b64encode(credentials) - if six.PY3: + if not six.PY2: credentials = credentials.decode('ascii') auth = "Basic " + credentials diff --git a/venv/lib/python3.8/site-packages/setuptools/config.py b/venv/lib/python3.8/site-packages/setuptools/config.py index b662604..a8f8b6b 100644 --- a/venv/lib/python3.8/site-packages/setuptools/config.py +++ b/venv/lib/python3.8/site-packages/setuptools/config.py @@ -1,23 +1,65 @@ from __future__ import absolute_import, unicode_literals +import ast import io import os import sys import warnings import functools +import importlib from collections import defaultdict from functools import partial from functools import wraps -from importlib import import_module +import contextlib from distutils.errors import DistutilsOptionError, DistutilsFileError from setuptools.extern.packaging.version import LegacyVersion, parse +from setuptools.extern.packaging.specifiers import SpecifierSet from setuptools.extern.six import string_types, PY3 __metaclass__ = type +class StaticModule: + """ + Attempt to load the module by the name + """ + def __init__(self, name): + spec = importlib.util.find_spec(name) + with open(spec.origin) as strm: + src = strm.read() + module = ast.parse(src) + vars(self).update(locals()) + del self.self + + def __getattr__(self, attr): + try: + return next( + ast.literal_eval(statement.value) + for statement in self.module.body + if isinstance(statement, ast.Assign) + for target in statement.targets + if isinstance(target, ast.Name) and target.id == attr + ) + except Exception as e: + raise AttributeError( + "{self.name} has no attribute {attr}".format(**locals()) + ) from e + + +@contextlib.contextmanager +def patch_path(path): + """ + Add path to front of sys.path for the duration of the context. + """ + try: + sys.path.insert(0, path) + yield + finally: + sys.path.remove(path) + + def read_configuration( filepath, find_others=False, ignore_option_errors=False): """Read given configuration file and returns options from it as a dict. @@ -343,15 +385,16 @@ class ConfigHandler: elif '' in package_dir: # A custom parent directory was specified for all root modules parent_path = os.path.join(os.getcwd(), package_dir['']) - sys.path.insert(0, parent_path) - try: - module = import_module(module_name) - value = getattr(module, attr_name) - finally: - sys.path = sys.path[1:] + with patch_path(parent_path): + try: + # attempt to load value statically + return getattr(StaticModule(module_name), attr_name) + except Exception: + # fallback to simple import + module = importlib.import_module(module_name) - return value + return getattr(module, attr_name) @classmethod def _get_parser_compound(cls, *parse_methods): @@ -482,6 +525,7 @@ class ConfigMetadataHandler(ConfigHandler): 'obsoletes': parse_list, 'classifiers': self._get_parser_compound(parse_file, parse_list), 'license': exclude_files_parser('license'), + 'license_files': parse_list, 'description': parse_file, 'long_description': parse_file, 'version': self._parse_version, @@ -554,6 +598,7 @@ class ConfigOptionsHandler(ConfigHandler): 'packages': self._parse_packages, 'entry_points': self._parse_file, 'py_modules': parse_list, + 'python_requires': SpecifierSet, } def _parse_packages(self, value): diff --git a/venv/lib/python3.8/site-packages/setuptools/dep_util.py b/venv/lib/python3.8/site-packages/setuptools/dep_util.py index 2931c13..521eb71 100644 --- a/venv/lib/python3.8/site-packages/setuptools/dep_util.py +++ b/venv/lib/python3.8/site-packages/setuptools/dep_util.py @@ -1,5 +1,6 @@ from distutils.dep_util import newer_group + # yes, this is was almost entirely copy-pasted from # 'newer_pairwise()', this is just another convenience # function. @@ -10,7 +11,8 @@ def newer_pairwise_group(sources_groups, targets): of 'newer_group()'. """ if len(sources_groups) != len(targets): - raise ValueError("'sources_group' and 'targets' must be the same length") + raise ValueError( + "'sources_group' and 'targets' must be the same length") # build a pair of lists (sources_groups, targets) where source is newer n_sources = [] diff --git a/venv/lib/python3.8/site-packages/setuptools/depends.py b/venv/lib/python3.8/site-packages/setuptools/depends.py index 45e7052..a37675c 100644 --- a/venv/lib/python3.8/site-packages/setuptools/depends.py +++ b/venv/lib/python3.8/site-packages/setuptools/depends.py @@ -1,11 +1,13 @@ import sys -import imp import marshal +import contextlib from distutils.version import StrictVersion -from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN from .py33compat import Bytecode +from .py27compat import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE +from . import py27compat + __all__ = [ 'Require', 'find_module', 'get_module_constant', 'extract_constant' @@ -15,7 +17,8 @@ __all__ = [ class Require: """A prerequisite to building or installing a distribution""" - def __init__(self, name, requested_version, module, homepage='', + def __init__( + self, name, requested_version, module, homepage='', attribute=None, format=None): if format is None and requested_version is not None: @@ -79,23 +82,15 @@ class Require: return self.version_ok(version) -def find_module(module, paths=None): - """Just like 'imp.find_module()', but with package support""" +def maybe_close(f): + @contextlib.contextmanager + def empty(): + yield + return + if not f: + return empty() - parts = module.split('.') - - while parts: - part = parts.pop(0) - f, path, (suffix, mode, kind) = info = imp.find_module(part, paths) - - if kind == PKG_DIRECTORY: - parts = parts or ['__init__'] - paths = [path] - - elif parts: - raise ImportError("Can't find %r in %s" % (parts, module)) - - return info + return contextlib.closing(f) def get_module_constant(module, symbol, default=-1, paths=None): @@ -106,28 +101,23 @@ def get_module_constant(module, symbol, default=-1, paths=None): constant. Otherwise, return 'default'.""" try: - f, path, (suffix, mode, kind) = find_module(module, paths) + f, path, (suffix, mode, kind) = info = find_module(module, paths) except ImportError: # Module doesn't exist return None - try: + with maybe_close(f): if kind == PY_COMPILED: f.read(8) # skip magic & date code = marshal.load(f) elif kind == PY_FROZEN: - code = imp.get_frozen_object(module) + code = py27compat.get_frozen_object(module, paths) elif kind == PY_SOURCE: code = compile(f.read(), path, 'exec') else: # Not something we can parse; we'll have to import it. :( - if module not in sys.modules: - imp.load_module(module, f, path, (suffix, mode, kind)) - return getattr(sys.modules[module], symbol, None) - - finally: - if f: - f.close() + imported = py27compat.get_module(module, paths, info) + return getattr(imported, symbol, None) return extract_constant(code, symbol, default) diff --git a/venv/lib/python3.8/site-packages/setuptools/dist.py b/venv/lib/python3.8/site-packages/setuptools/dist.py index f0f030b..e813b11 100644 --- a/venv/lib/python3.8/site-packages/setuptools/dist.py +++ b/venv/lib/python3.8/site-packages/setuptools/dist.py @@ -19,19 +19,18 @@ import itertools from collections import defaultdict from email import message_from_file -from distutils.errors import ( - DistutilsOptionError, DistutilsPlatformError, DistutilsSetupError, -) +from distutils.errors import DistutilsOptionError, DistutilsSetupError from distutils.util import rfc822_escape from distutils.version import StrictVersion from setuptools.extern import six from setuptools.extern import packaging +from setuptools.extern import ordered_set from setuptools.extern.six.moves import map, filter, filterfalse from . import SetuptoolsDeprecationWarning -from setuptools.depends import Require +import setuptools from setuptools import windows_support from setuptools.monkey import get_unpatched from setuptools.config import parse_configuration @@ -161,7 +160,7 @@ def write_pkg_file(self, file): if self.download_url: write_field('Download-URL', self.download_url) for project_url in self.project_urls.items(): - write_field('Project-URL', '%s, %s' % project_url) + write_field('Project-URL', '%s, %s' % project_url) long_desc = rfc822_escape(self.get_long_description()) write_field('Description', long_desc) @@ -205,11 +204,11 @@ def check_importable(dist, attr, value): try: ep = pkg_resources.EntryPoint.parse('x=' + value) assert not ep.extras - except (TypeError, ValueError, AttributeError, AssertionError): + except (TypeError, ValueError, AttributeError, AssertionError) as e: raise DistutilsSetupError( "%r must be importable 'module:attrs' string (got %r)" % (attr, value) - ) + ) from e def assert_string_list(dist, attr, value): @@ -220,10 +219,10 @@ def assert_string_list(dist, attr, value): assert isinstance(value, (list, tuple)) # verify that elements of value are strings assert ''.join(value) != value - except (TypeError, ValueError, AttributeError, AssertionError): + except (TypeError, ValueError, AttributeError, AssertionError) as e: raise DistutilsSetupError( "%r must be a list of strings (got %r)" % (attr, value) - ) + ) from e def check_nsp(dist, attr, value): @@ -248,12 +247,12 @@ def check_extras(dist, attr, value): """Verify that extras_require mapping is valid""" try: list(itertools.starmap(_check_extra, value.items())) - except (TypeError, ValueError, AttributeError): + except (TypeError, ValueError, AttributeError) as e: raise DistutilsSetupError( "'extras_require' must be a dictionary whose values are " "strings or lists of strings containing valid project/version " "requirement specifiers." - ) + ) from e def _check_extra(extra, reqs): @@ -281,7 +280,9 @@ def check_requirements(dist, attr, value): "{attr!r} must be a string or list of strings " "containing valid project/version requirement specifiers; {error}" ) - raise DistutilsSetupError(tmpl.format(attr=attr, error=error)) + raise DistutilsSetupError( + tmpl.format(attr=attr, error=error) + ) from error def check_specifier(dist, attr, value): @@ -293,7 +294,9 @@ def check_specifier(dist, attr, value): "{attr!r} must be a string " "containing valid version specifiers; {error}" ) - raise DistutilsSetupError(tmpl.format(attr=attr, error=error)) + raise DistutilsSetupError( + tmpl.format(attr=attr, error=error) + ) from error def check_entry_points(dist, attr, value): @@ -301,7 +304,7 @@ def check_entry_points(dist, attr, value): try: pkg_resources.EntryPoint.parse_map(value) except ValueError as e: - raise DistutilsSetupError(e) + raise DistutilsSetupError(e) from e def check_test_suite(dist, attr, value): @@ -337,7 +340,7 @@ _Distribution = get_unpatched(distutils.core.Distribution) class Distribution(_Distribution): - """Distribution with support for features, tests, and package data + """Distribution with support for tests and package data This is an enhanced version of 'distutils.dist.Distribution' that effectively adds the following new optional keyword arguments to 'setup()': @@ -364,21 +367,6 @@ class Distribution(_Distribution): EasyInstall and requests one of your extras, the corresponding additional requirements will be installed if needed. - 'features' **deprecated** -- a dictionary mapping option names to - 'setuptools.Feature' - objects. Features are a portion of the distribution that can be - included or excluded based on user options, inter-feature dependencies, - and availability on the current system. Excluded features are omitted - from all setup commands, including source and binary distributions, so - you can create multiple distributions from the same source tree. - Feature names should be valid Python identifiers, except that they may - contain the '-' (minus) sign. Features can be included or excluded - via the command line options '--with-X' and '--without-X', where 'X' is - the name of the feature. Whether a feature is included by default, and - whether you are allowed to control this from the command line, is - determined by the Feature object. See the 'Feature' class for more - information. - 'test_suite' -- the name of a test suite to run for the 'test' command. If the user runs 'python setup.py test', the package will be installed, and the named test suite will be run. The format is the same as @@ -400,14 +388,14 @@ class Distribution(_Distribution): for manipulating the distribution's contents. For example, the 'include()' and 'exclude()' methods can be thought of as in-place add and subtract commands that add or remove packages, modules, extensions, and so on from - the distribution. They are used by the feature subsystem to configure the - distribution for the included and excluded features. + the distribution. """ _DISTUTILS_UNSUPPORTED_METADATA = { 'long_description_content_type': None, 'project_urls': dict, - 'provides_extras': set, + 'provides_extras': ordered_set.OrderedSet, + 'license_files': ordered_set.OrderedSet, } _patched_dist = None @@ -430,10 +418,6 @@ class Distribution(_Distribution): if not have_package_data: self.package_data = {} attrs = attrs or {} - if 'features' in attrs or 'require_features' in attrs: - Feature.warn_deprecated() - self.require_features = [] - self.features = {} self.dist_files = [] # Filter-out setuptools' specific options. self.src_root = attrs.pop("src_root", None) @@ -459,30 +443,40 @@ class Distribution(_Distribution): value = default() if default else None setattr(self.metadata, option, value) - if isinstance(self.metadata.version, numbers.Number): - # Some people apparently take "version number" too literally :) - self.metadata.version = str(self.metadata.version) + self.metadata.version = self._normalize_version( + self._validate_version(self.metadata.version)) + self._finalize_requires() - if self.metadata.version is not None: + @staticmethod + def _normalize_version(version): + if isinstance(version, setuptools.sic) or version is None: + return version + + normalized = str(packaging.version.Version(version)) + if version != normalized: + tmpl = "Normalizing '{version}' to '{normalized}'" + warnings.warn(tmpl.format(**locals())) + return normalized + return version + + @staticmethod + def _validate_version(version): + if isinstance(version, numbers.Number): + # Some people apparently take "version number" too literally :) + version = str(version) + + if version is not None: try: - ver = packaging.version.Version(self.metadata.version) - normalized_version = str(ver) - if self.metadata.version != normalized_version: - warnings.warn( - "Normalizing '%s' to '%s'" % ( - self.metadata.version, - normalized_version, - ) - ) - self.metadata.version = normalized_version + packaging.version.Version(version) except (packaging.version.InvalidVersion, TypeError): warnings.warn( "The version specified (%r) is an invalid version, this " "may not work as expected with newer versions of " "setuptools, pip, and PyPI. Please see PEP 440 for more " - "details." % self.metadata.version + "details." % version ) - self._finalize_requires() + return setuptools.sic(version) + return version def _finalize_requires(self): """ @@ -569,7 +563,7 @@ class Distribution(_Distribution): from setuptools.extern.six.moves.configparser import ConfigParser # Ignore install directory options if we have a venv - if six.PY3 and sys.prefix != sys.base_prefix: + if not six.PY2 and sys.prefix != sys.base_prefix: ignore_options = [ 'install-base', 'install-platbase', 'install-lib', 'install-platlib', 'install-purelib', 'install-headers', @@ -591,7 +585,7 @@ class Distribution(_Distribution): with io.open(filename, encoding='utf-8') as reader: if DEBUG: self.announce(" reading {filename}".format(**locals())) - (parser.read_file if six.PY3 else parser.readfp)(reader) + (parser.readfp if six.PY2 else parser.read_file)(reader) for section in parser.sections(): options = parser.options(section) opt_dict = self.get_option_dict(section) @@ -619,8 +613,8 @@ class Distribution(_Distribution): setattr(self, opt, strtobool(val)) else: setattr(self, opt, val) - except ValueError as msg: - raise DistutilsOptionError(msg) + except ValueError as e: + raise DistutilsOptionError(e) from e @staticmethod def _try_str(val): @@ -634,7 +628,7 @@ class Distribution(_Distribution): Ref #1653 """ - if six.PY3: + if not six.PY2: return val try: return val.encode() @@ -686,8 +680,8 @@ class Distribution(_Distribution): raise DistutilsOptionError( "error in %s: command '%s' has no such option '%s'" % (source, command_name, option)) - except ValueError as msg: - raise DistutilsOptionError(msg) + except ValueError as e: + raise DistutilsOptionError(e) from e def parse_config_files(self, filenames=None, ignore_option_errors=False): """Parses configuration files from various levels @@ -700,17 +694,6 @@ class Distribution(_Distribution): ignore_option_errors=ignore_option_errors) self._finalize_requires() - def parse_command_line(self): - """Process features after parsing command line options""" - result = _Distribution.parse_command_line(self) - if self.features: - self._finalize_features() - return result - - def _feature_attrname(self, name): - """Convert feature name to corresponding option attribute name""" - return 'with_' + name.replace('-', '_') - def fetch_build_eggs(self, requires): """Resolve pre-setup requirements""" resolved_dists = pkg_resources.working_set.resolve( @@ -723,15 +706,28 @@ class Distribution(_Distribution): return resolved_dists def finalize_options(self): - _Distribution.finalize_options(self) - if self.features: - self._set_global_opts_from_features() + """ + Allow plugins to apply arbitrary operations to the + distribution. Each hook may optionally define a 'order' + to influence the order of execution. Smaller numbers + go first and the default is 0. + """ + group = 'setuptools.finalize_distribution_options' + def by_order(hook): + return getattr(hook, 'order', 0) + eps = map(lambda e: e.load(), pkg_resources.iter_entry_points(group)) + for ep in sorted(eps, key=by_order): + ep(self) + + def _finalize_setup_keywords(self): for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'): value = getattr(self, ep.name, None) if value is not None: ep.require(installer=self.fetch_build_egg) ep.load()(self, ep.name, value) + + def _finalize_2to3_doctests(self): if getattr(self, 'convert_2to3_doctests', None): # XXX may convert to set here when we can rely on set being builtin self.convert_2to3_doctests = [ @@ -758,76 +754,8 @@ class Distribution(_Distribution): def fetch_build_egg(self, req): """Fetch an egg needed for building""" - from setuptools.command.easy_install import easy_install - dist = self.__class__({'script_args': ['easy_install']}) - opts = dist.get_option_dict('easy_install') - opts.clear() - opts.update( - (k, v) - for k, v in self.get_option_dict('easy_install').items() - if k in ( - # don't use any other settings - 'find_links', 'site_dirs', 'index_url', - 'optimize', 'site_dirs', 'allow_hosts', - )) - if self.dependency_links: - links = self.dependency_links[:] - if 'find_links' in opts: - links = opts['find_links'][1] + links - opts['find_links'] = ('setup', links) - install_dir = self.get_egg_cache_dir() - cmd = easy_install( - dist, args=["x"], install_dir=install_dir, - exclude_scripts=True, - always_copy=False, build_directory=None, editable=False, - upgrade=False, multi_version=True, no_report=True, user=False - ) - cmd.ensure_finalized() - return cmd.easy_install(req) - - def _set_global_opts_from_features(self): - """Add --with-X/--without-X options based on optional features""" - - go = [] - no = self.negative_opt.copy() - - for name, feature in self.features.items(): - self._set_feature(name, None) - feature.validate(self) - - if feature.optional: - descr = feature.description - incdef = ' (default)' - excdef = '' - if not feature.include_by_default(): - excdef, incdef = incdef, excdef - - new = ( - ('with-' + name, None, 'include ' + descr + incdef), - ('without-' + name, None, 'exclude ' + descr + excdef), - ) - go.extend(new) - no['without-' + name] = 'with-' + name - - self.global_options = self.feature_options = go + self.global_options - self.negative_opt = self.feature_negopt = no - - def _finalize_features(self): - """Add/remove features and resolve dependencies between them""" - - # First, flag all the enabled items (and thus their dependencies) - for name, feature in self.features.items(): - enabled = self.feature_is_included(name) - if enabled or (enabled is None and feature.include_by_default()): - feature.include_in(self) - self._set_feature(name, 1) - - # Then disable the rest, so that off-by-default features don't - # get flagged as errors when they're required by an enabled feature - for name, feature in self.features.items(): - if not self.feature_is_included(name): - feature.exclude_from(self) - self._set_feature(name, 0) + from setuptools.installer import fetch_build_egg + return fetch_build_egg(self, req) def get_command_class(self, command): """Pluggable version of get_command_class()""" @@ -858,25 +786,6 @@ class Distribution(_Distribution): self.cmdclass[ep.name] = cmdclass return _Distribution.get_command_list(self) - def _set_feature(self, name, status): - """Set feature's inclusion status""" - setattr(self, self._feature_attrname(name), status) - - def feature_is_included(self, name): - """Return 1 if feature is included, 0 if excluded, 'None' if unknown""" - return getattr(self, self._feature_attrname(name)) - - def include_feature(self, name): - """Request inclusion of feature named 'name'""" - - if self.feature_is_included(name) == 0: - descr = self.features[name].description - raise DistutilsOptionError( - descr + " is required, but was excluded or is not available" - ) - self.features[name].include_in(self) - self._set_feature(name, 1) - def include(self, **attrs): """Add items to distribution that are named in keyword arguments @@ -938,10 +847,10 @@ class Distribution(_Distribution): ) try: old = getattr(self, name) - except AttributeError: + except AttributeError as e: raise DistutilsSetupError( "%s: No such distribution setting" % name - ) + ) from e if old is not None and not isinstance(old, sequence): raise DistutilsSetupError( name + ": this setting cannot be changed via include/exclude" @@ -958,10 +867,10 @@ class Distribution(_Distribution): ) try: old = getattr(self, name) - except AttributeError: + except AttributeError as e: raise DistutilsSetupError( "%s: No such distribution setting" % name - ) + ) from e if old is None: setattr(self, name, value) elif not isinstance(old, sequence): @@ -1121,160 +1030,6 @@ class Distribution(_Distribution): sys.stdout.detach(), encoding, errors, newline, line_buffering) -class Feature: - """ - **deprecated** -- The `Feature` facility was never completely implemented - or supported, `has reported issues - <https://github.com/pypa/setuptools/issues/58>`_ and will be removed in - a future version. - - A subset of the distribution that can be excluded if unneeded/wanted - - Features are created using these keyword arguments: - - 'description' -- a short, human readable description of the feature, to - be used in error messages, and option help messages. - - 'standard' -- if true, the feature is included by default if it is - available on the current system. Otherwise, the feature is only - included if requested via a command line '--with-X' option, or if - another included feature requires it. The default setting is 'False'. - - 'available' -- if true, the feature is available for installation on the - current system. The default setting is 'True'. - - 'optional' -- if true, the feature's inclusion can be controlled from the - command line, using the '--with-X' or '--without-X' options. If - false, the feature's inclusion status is determined automatically, - based on 'availabile', 'standard', and whether any other feature - requires it. The default setting is 'True'. - - 'require_features' -- a string or sequence of strings naming features - that should also be included if this feature is included. Defaults to - empty list. May also contain 'Require' objects that should be - added/removed from the distribution. - - 'remove' -- a string or list of strings naming packages to be removed - from the distribution if this feature is *not* included. If the - feature *is* included, this argument is ignored. This argument exists - to support removing features that "crosscut" a distribution, such as - defining a 'tests' feature that removes all the 'tests' subpackages - provided by other features. The default for this argument is an empty - list. (Note: the named package(s) or modules must exist in the base - distribution when the 'setup()' function is initially called.) - - other keywords -- any other keyword arguments are saved, and passed to - the distribution's 'include()' and 'exclude()' methods when the - feature is included or excluded, respectively. So, for example, you - could pass 'packages=["a","b"]' to cause packages 'a' and 'b' to be - added or removed from the distribution as appropriate. - - A feature must include at least one 'requires', 'remove', or other - keyword argument. Otherwise, it can't affect the distribution in any way. - Note also that you can subclass 'Feature' to create your own specialized - feature types that modify the distribution in other ways when included or - excluded. See the docstrings for the various methods here for more detail. - Aside from the methods, the only feature attributes that distributions look - at are 'description' and 'optional'. - """ - - @staticmethod - def warn_deprecated(): - msg = ( - "Features are deprecated and will be removed in a future " - "version. See https://github.com/pypa/setuptools/issues/65." - ) - warnings.warn(msg, DistDeprecationWarning, stacklevel=3) - - def __init__( - self, description, standard=False, available=True, - optional=True, require_features=(), remove=(), **extras): - self.warn_deprecated() - - self.description = description - self.standard = standard - self.available = available - self.optional = optional - if isinstance(require_features, (str, Require)): - require_features = require_features, - - self.require_features = [ - r for r in require_features if isinstance(r, str) - ] - er = [r for r in require_features if not isinstance(r, str)] - if er: - extras['require_features'] = er - - if isinstance(remove, str): - remove = remove, - self.remove = remove - self.extras = extras - - if not remove and not require_features and not extras: - raise DistutilsSetupError( - "Feature %s: must define 'require_features', 'remove', or " - "at least one of 'packages', 'py_modules', etc." - ) - - def include_by_default(self): - """Should this feature be included by default?""" - return self.available and self.standard - - def include_in(self, dist): - """Ensure feature and its requirements are included in distribution - - You may override this in a subclass to perform additional operations on - the distribution. Note that this method may be called more than once - per feature, and so should be idempotent. - - """ - - if not self.available: - raise DistutilsPlatformError( - self.description + " is required, " - "but is not available on this platform" - ) - - dist.include(**self.extras) - - for f in self.require_features: - dist.include_feature(f) - - def exclude_from(self, dist): - """Ensure feature is excluded from distribution - - You may override this in a subclass to perform additional operations on - the distribution. This method will be called at most once per - feature, and only after all included features have been asked to - include themselves. - """ - - dist.exclude(**self.extras) - - if self.remove: - for item in self.remove: - dist.exclude_package(item) - - def validate(self, dist): - """Verify that feature makes sense in context of distribution - - This method is called by the distribution just before it parses its - command line. It checks to ensure that the 'remove' attribute, if any, - contains only valid package/module names that are present in the base - distribution when 'setup()' is called. You may override it in a - subclass to perform any other required validation of the feature - against a target distribution. - """ - - for item in self.remove: - if not dist.has_contents_for(item): - raise DistutilsSetupError( - "%s wants to be able to remove %s, but the distribution" - " doesn't contain any packages or modules under %s" - % (self.description, item, item) - ) - - class DistDeprecationWarning(SetuptoolsDeprecationWarning): """Class for warning about deprecations in dist in setuptools. Not ignored by default, unlike DeprecationWarning.""" diff --git a/venv/lib/python3.8/site-packages/setuptools/extern/__init__.py b/venv/lib/python3.8/site-packages/setuptools/extern/__init__.py index cb2fa32..4e79aa1 100644 --- a/venv/lib/python3.8/site-packages/setuptools/extern/__init__.py +++ b/venv/lib/python3.8/site-packages/setuptools/extern/__init__.py @@ -43,13 +43,6 @@ class VendorImporter: __import__(extant) mod = sys.modules[extant] sys.modules[fullname] = mod - # mysterious hack: - # Remove the reference to the extant package/module - # on later Python versions to cause relative imports - # in the vendor package to resolve the same modules - # as those going through this importer. - if sys.version_info >= (3, ): - del sys.modules[extant] return mod except ImportError: pass @@ -69,5 +62,5 @@ class VendorImporter: sys.meta_path.append(self) -names = 'six', 'packaging', 'pyparsing', +names = 'six', 'packaging', 'pyparsing', 'ordered_set', VendorImporter(__name__, names, 'setuptools._vendor').install() diff --git a/venv/lib/python3.8/site-packages/setuptools/extern/__pycache__/__init__.cpython-38.pyc b/venv/lib/python3.8/site-packages/setuptools/extern/__pycache__/__init__.cpython-38.pyc index 1301a0d802f3b115cc444d2c5955f4b7e8a75ef3..ae5732033d6f911a249348549312dd8a49ab0568 100644 GIT binary patch delta 317 zcmaDY^je57l$V!_0SGw%?TQcJSjflZl%SuHpPQ;*R9RY@m8oA`l&qhUn3tKFlbl~v zl3J`+QCX#5mYP?lpOcxSUr<?+k)LO*XQ5x5S(2(-keHmEn4Y@Xi0LvDW6fkXRs~j% zTGlGP$=a+c7B%eQ3``7+48aU63?*#YTt!KYKprDQBtxN01Q3_7r7&f&r!kapG&A%u zHZwLcrZ5LHXtGS6$r?2I6YESy&dEJ&T9c2k<qFGzT+AZI$i>LS$N_|0j9imF*!MEZ zOlIRSX0)7a#Zkeg3{+C2HhBk!k%3qd6Og0Ha*Me*v*H#f#Fd$O=|E;>L1IxckQv3D rUzCzsl$sJ>oLVxOms4C^2BaUP?-pxbVs2`2kvhacYffEeTNXwD6tq+* delta 324 zcmaDY^je57l$V!_0SKO#ZHPO}xsZ=Z#Yw*;w?Mxjvp_d9uec;JCr8&P!=$vrI6qOp zIJKm-pd>#(XLA74WhTbH$ttW0tWmYBRSuIqSyjABShCnsn6g=mB7iK`8a7*o8uoAo zCI&`^U<MY3683Daq7p_RkC7pgp-?6Qh)dX0n6o(27)m&s8TuHT8JieWSb`ZeStl=L z4Pwz`e91id3+o(4uE`VGw0L>SQj3Z+^Yh{}^V0Gs?_$dnR{}YlMU0V)k%^H52)P)! z*ti%uCR?-bWt5%#liirnVX`hq1)C~RS&_!%)f`63vPDcljwbUh=HkqXTbu=n$=QkN znR)3zW@SMl(EPmg$-JE6GO{2oAf>lh^AdAYi;FbDW`GFh$$}ihlY==$nO#^I0pQ(H A#sB~S diff --git a/venv/lib/python3.8/site-packages/setuptools/glibc.py b/venv/lib/python3.8/site-packages/setuptools/glibc.py deleted file mode 100644 index a134591..0000000 --- a/venv/lib/python3.8/site-packages/setuptools/glibc.py +++ /dev/null @@ -1,86 +0,0 @@ -# This file originally from pip: -# https://github.com/pypa/pip/blob/8f4f15a5a95d7d5b511ceaee9ed261176c181970/src/pip/_internal/utils/glibc.py -from __future__ import absolute_import - -import ctypes -import re -import warnings - - -def glibc_version_string(): - "Returns glibc version string, or None if not using glibc." - - # 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. - process_namespace = ctypes.CDLL(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() - # py2 / py3 compatibility: - if not isinstance(version_str, str): - version_str = version_str.decode("ascii") - - return version_str - - -# Separated out from have_compatible_glibc for easier unit testing -def check_glibc_version(version_str, required_major, minimum_minor): - # Parse string and check against requested 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<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str) - if not m: - warnings.warn("Expected glibc version with 2 components major.minor," - " got: %s" % version_str, RuntimeWarning) - return False - return (int(m.group("major")) == required_major and - int(m.group("minor")) >= minimum_minor) - - -def have_compatible_glibc(required_major, minimum_minor): - version_str = glibc_version_string() - if version_str is None: - return False - return check_glibc_version(version_str, required_major, minimum_minor) - - -# platform.libc_ver regularly returns completely nonsensical glibc -# versions. E.g. on my computer, platform says: -# -# ~$ python2.7 -c 'import platform; print(platform.libc_ver())' -# ('glibc', '2.7') -# ~$ python3.5 -c 'import platform; print(platform.libc_ver())' -# ('glibc', '2.9') -# -# But the truth is: -# -# ~$ ldd --version -# ldd (Debian GLIBC 2.22-11) 2.22 -# -# This is unfortunate, because it means that the linehaul data on libc -# versions that was generated by pip 8.1.2 and earlier is useless and -# misleading. Solution: instead of using platform, use our code that actually -# works. -def libc_ver(): - """Try to determine the glibc version - - Returns a tuple of strings (lib, version) which default to empty strings - in case the lookup fails. - """ - glibc_version = glibc_version_string() - if glibc_version is None: - return ("", "") - else: - return ("glibc", glibc_version) diff --git a/venv/lib/python3.8/site-packages/setuptools/launch.py b/venv/lib/python3.8/site-packages/setuptools/launch.py index 308283e..0208fdf 100644 --- a/venv/lib/python3.8/site-packages/setuptools/launch.py +++ b/venv/lib/python3.8/site-packages/setuptools/launch.py @@ -25,7 +25,8 @@ def run(): sys.argv[:] = sys.argv[1:] open_ = getattr(tokenize, 'open', open) - script = open_(script_name).read() + with open_(script_name) as fid: + script = fid.read() norm_script = script.replace('\\r\\n', '\\n') code = compile(norm_script, script_name, 'exec') exec(code, namespace) diff --git a/venv/lib/python3.8/site-packages/setuptools/lib2to3_ex.py b/venv/lib/python3.8/site-packages/setuptools/lib2to3_ex.py index 4b1a73f..017f728 100644 --- a/venv/lib/python3.8/site-packages/setuptools/lib2to3_ex.py +++ b/venv/lib/python3.8/site-packages/setuptools/lib2to3_ex.py @@ -7,11 +7,13 @@ Customized Mixin2to3 support: This module raises an ImportError on Python 2. """ +import warnings from distutils.util import Mixin2to3 as _Mixin2to3 from distutils import log from lib2to3.refactor import RefactoringTool, get_fixers_from_package import setuptools +from ._deprecation_warning import SetuptoolsDeprecationWarning class DistutilsRefactoringTool(RefactoringTool): @@ -33,6 +35,13 @@ class Mixin2to3(_Mixin2to3): return if not files: return + + warnings.warn( + "2to3 support is deprecated. If the project still " + "requires Python 2 support, please migrate to " + "a single-codebase solution or employ an " + "independent conversion process.", + SetuptoolsDeprecationWarning) log.info("Fixing " + " ".join(files)) self.__build_fixer_names() self.__exclude_fixers() diff --git a/venv/lib/python3.8/site-packages/setuptools/msvc.py b/venv/lib/python3.8/site-packages/setuptools/msvc.py index b9c472f..72383eb 100644 --- a/venv/lib/python3.8/site-packages/setuptools/msvc.py +++ b/venv/lib/python3.8/site-packages/setuptools/msvc.py @@ -11,16 +11,22 @@ Microsoft Visual C++ 9.0: Microsoft Visual C++ 10.0: Microsoft Windows SDK 7.1 (x86, x64, ia64) -Microsoft Visual C++ 14.0: +Microsoft Visual C++ 14.X: Microsoft Visual C++ Build Tools 2015 (x86, x64, arm) - Microsoft Visual Studio 2017 (x86, x64, arm, arm64) Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64) + Microsoft Visual Studio Build Tools 2019 (x86, x64, arm, arm64) + +This may also support compilers shipped with compatible Visual Studio versions. """ -import os +import json +from io import open +from os import listdir, pathsep +from os.path import join, isfile, isdir, dirname import sys import platform import itertools +import subprocess import distutils.errors from setuptools.extern.packaging.version import LegacyVersion @@ -30,12 +36,9 @@ from .monkey import get_unpatched if platform.system() == 'Windows': from setuptools.extern.six.moves import winreg - safe_env = os.environ + from os import environ else: - """ - Mock winreg and environ so the module can be imported - on this platform. - """ + # Mock winreg and environ so the module can be imported on this platform. class winreg: HKEY_USERS = None @@ -43,7 +46,7 @@ else: HKEY_LOCAL_MACHINE = None HKEY_CLASSES_ROOT = None - safe_env = dict() + environ = dict() _msvc9_suppress_errors = ( # msvc9compiler isn't available on some platforms @@ -63,16 +66,14 @@ except _msvc9_suppress_errors: def msvc9_find_vcvarsall(version): """ Patched "distutils.msvc9compiler.find_vcvarsall" to use the standalone - compiler build for Python (VCForPython). Fall back to original behavior - when the standalone compiler is not available. + compiler build for Python + (VCForPython / Microsoft Visual C++ Compiler for Python 2.7). + + Fall back to original behavior when the standalone compiler is not + available. Redirect the path of "vcvarsall.bat". - Known supported compilers - ------------------------- - Microsoft Visual C++ 9.0: - Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64) - Parameters ---------- version: float @@ -80,24 +81,25 @@ def msvc9_find_vcvarsall(version): Return ------ - vcvarsall.bat path: str + str + vcvarsall.bat path """ - VC_BASE = r'Software\%sMicrosoft\DevDiv\VCForPython\%0.1f' - key = VC_BASE % ('', version) + vc_base = r'Software\%sMicrosoft\DevDiv\VCForPython\%0.1f' + key = vc_base % ('', version) try: # Per-user installs register the compiler path here productdir = Reg.get_value(key, "installdir") except KeyError: try: # All-user installs on a 64-bit system register here - key = VC_BASE % ('Wow6432Node\\', version) + key = vc_base % ('Wow6432Node\\', version) productdir = Reg.get_value(key, "installdir") except KeyError: productdir = None if productdir: - vcvarsall = os.path.os.path.join(productdir, "vcvarsall.bat") - if os.path.isfile(vcvarsall): + vcvarsall = join(productdir, "vcvarsall.bat") + if isfile(vcvarsall): return vcvarsall return get_unpatched(msvc9_find_vcvarsall)(version) @@ -106,20 +108,10 @@ def msvc9_find_vcvarsall(version): def msvc9_query_vcvarsall(ver, arch='x86', *args, **kwargs): """ Patched "distutils.msvc9compiler.query_vcvarsall" for support extra - compilers. + Microsoft Visual C++ 9.0 and 10.0 compilers. Set environment without use of "vcvarsall.bat". - Known supported compilers - ------------------------- - Microsoft Visual C++ 9.0: - Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64) - Microsoft Windows SDK 6.1 (x86, x64, ia64) - Microsoft Windows SDK 7.0 (x86, x64, ia64) - - Microsoft Visual C++ 10.0: - Microsoft Windows SDK 7.1 (x86, x64, ia64) - Parameters ---------- ver: float @@ -129,9 +121,10 @@ def msvc9_query_vcvarsall(ver, arch='x86', *args, **kwargs): Return ------ - environment: dict + dict + environment """ - # Try to get environement from vcvarsall.bat (Classical way) + # Try to get environment from vcvarsall.bat (Classical way) try: orig = get_unpatched(msvc9_query_vcvarsall) return orig(ver, arch, *args, **kwargs) @@ -150,20 +143,161 @@ def msvc9_query_vcvarsall(ver, arch='x86', *args, **kwargs): raise +def _msvc14_find_vc2015(): + """Python 3.8 "distutils/_msvccompiler.py" backport""" + try: + key = winreg.OpenKey( + winreg.HKEY_LOCAL_MACHINE, + r"Software\Microsoft\VisualStudio\SxS\VC7", + 0, + winreg.KEY_READ | winreg.KEY_WOW64_32KEY + ) + except OSError: + return None, None + + best_version = 0 + best_dir = None + with key: + for i in itertools.count(): + try: + v, vc_dir, vt = winreg.EnumValue(key, i) + except OSError: + break + if v and vt == winreg.REG_SZ and isdir(vc_dir): + try: + version = int(float(v)) + except (ValueError, TypeError): + continue + if version >= 14 and version > best_version: + best_version, best_dir = version, vc_dir + return best_version, best_dir + + +def _msvc14_find_vc2017(): + """Python 3.8 "distutils/_msvccompiler.py" backport + + Returns "15, path" based on the result of invoking vswhere.exe + If no install is found, returns "None, None" + + The version is returned to avoid unnecessarily changing the function + result. It may be ignored when the path is not None. + + If vswhere.exe is not available, by definition, VS 2017 is not + installed. + """ + root = environ.get("ProgramFiles(x86)") or environ.get("ProgramFiles") + if not root: + return None, None + + try: + path = subprocess.check_output([ + join(root, "Microsoft Visual Studio", "Installer", "vswhere.exe"), + "-latest", + "-prerelease", + "-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", + "-property", "installationPath", + "-products", "*", + ]).decode(encoding="mbcs", errors="strict").strip() + except (subprocess.CalledProcessError, OSError, UnicodeDecodeError): + return None, None + + path = join(path, "VC", "Auxiliary", "Build") + if isdir(path): + return 15, path + + return None, None + + +PLAT_SPEC_TO_RUNTIME = { + 'x86': 'x86', + 'x86_amd64': 'x64', + 'x86_arm': 'arm', + 'x86_arm64': 'arm64' +} + + +def _msvc14_find_vcvarsall(plat_spec): + """Python 3.8 "distutils/_msvccompiler.py" backport""" + _, best_dir = _msvc14_find_vc2017() + vcruntime = None + + if plat_spec in PLAT_SPEC_TO_RUNTIME: + vcruntime_plat = PLAT_SPEC_TO_RUNTIME[plat_spec] + else: + vcruntime_plat = 'x64' if 'amd64' in plat_spec else 'x86' + + if best_dir: + vcredist = join(best_dir, "..", "..", "redist", "MSVC", "**", + vcruntime_plat, "Microsoft.VC14*.CRT", + "vcruntime140.dll") + try: + import glob + vcruntime = glob.glob(vcredist, recursive=True)[-1] + except (ImportError, OSError, LookupError): + vcruntime = None + + if not best_dir: + best_version, best_dir = _msvc14_find_vc2015() + if best_version: + vcruntime = join(best_dir, 'redist', vcruntime_plat, + "Microsoft.VC140.CRT", "vcruntime140.dll") + + if not best_dir: + return None, None + + vcvarsall = join(best_dir, "vcvarsall.bat") + if not isfile(vcvarsall): + return None, None + + if not vcruntime or not isfile(vcruntime): + vcruntime = None + + return vcvarsall, vcruntime + + +def _msvc14_get_vc_env(plat_spec): + """Python 3.8 "distutils/_msvccompiler.py" backport""" + if "DISTUTILS_USE_SDK" in environ: + return { + key.lower(): value + for key, value in environ.items() + } + + vcvarsall, vcruntime = _msvc14_find_vcvarsall(plat_spec) + if not vcvarsall: + raise distutils.errors.DistutilsPlatformError( + "Unable to find vcvarsall.bat" + ) + + try: + out = subprocess.check_output( + 'cmd /u /c "{}" {} && set'.format(vcvarsall, plat_spec), + stderr=subprocess.STDOUT, + ).decode('utf-16le', errors='replace') + except subprocess.CalledProcessError as exc: + raise distutils.errors.DistutilsPlatformError( + "Error executing {}".format(exc.cmd) + ) from exc + + env = { + key.lower(): value + for key, _, value in + (line.partition('=') for line in out.splitlines()) + if key and value + } + + if vcruntime: + env['py_vcruntime_redist'] = vcruntime + return env + + def msvc14_get_vc_env(plat_spec): """ Patched "distutils._msvccompiler._get_vc_env" for support extra - compilers. + Microsoft Visual C++ 14.X compilers. Set environment without use of "vcvarsall.bat". - Known supported compilers - ------------------------- - Microsoft Visual C++ 14.0: - Microsoft Visual C++ Build Tools 2015 (x86, x64, arm) - Microsoft Visual Studio 2017 (x86, x64, arm, arm64) - Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64) - Parameters ---------- plat_spec: str @@ -171,18 +305,13 @@ def msvc14_get_vc_env(plat_spec): Return ------ - environment: dict + dict + environment """ - # Try to get environment from vcvarsall.bat (Classical way) - try: - return get_unpatched(msvc14_get_vc_env)(plat_spec) - except distutils.errors.DistutilsPlatformError: - # Pass error Vcvarsall.bat is missing - pass - # If error, try to set environment directly + # Always use backport from CPython 3.8 try: - return EnvironmentInfo(plat_spec, vc_min_ver=14.0).return_env() + return _msvc14_get_vc_env(plat_spec) except distutils.errors.DistutilsPlatformError as exc: _augment_exception(exc, 14.0) raise @@ -217,9 +346,9 @@ def _augment_exception(exc, version, arch=''): if version == 9.0: if arch.lower().find('ia64') > -1: # For VC++ 9.0, if IA64 support is needed, redirect user - # to Windows SDK 7.0 - message += ' Get it with "Microsoft Windows SDK 7.0": ' - message += msdownload % 3138 + # to Windows SDK 7.0. + # Note: No download link available from Microsoft. + message += ' Get it with "Microsoft Windows SDK 7.0"' else: # For VC++ 9.0 redirect user to Vc++ for Python 2.7 : # This redirection link is maintained by Microsoft. @@ -230,8 +359,8 @@ def _augment_exception(exc, version, arch=''): message += ' Get it with "Microsoft Windows SDK 7.1": ' message += msdownload % 8279 elif version >= 14.0: - # For VC++ 14.0 Redirect user to Visual C++ Build Tools - message += (' Get it with "Microsoft Visual C++ Build Tools": ' + # For VC++ 14.X Redirect user to latest Visual C++ Build Tools + message += (' Get it with "Build Tools for Visual Studio": ' r'https://visualstudio.microsoft.com/downloads/') exc.args = (message, ) @@ -239,26 +368,50 @@ def _augment_exception(exc, version, arch=''): class PlatformInfo: """ - Current and Target Architectures informations. + Current and Target Architectures information. Parameters ---------- arch: str Target architecture. """ - current_cpu = safe_env.get('processor_architecture', '').lower() + current_cpu = environ.get('processor_architecture', '').lower() def __init__(self, arch): self.arch = arch.lower().replace('x64', 'amd64') @property def target_cpu(self): + """ + Return Target CPU architecture. + + Return + ------ + str + Target CPU + """ return self.arch[self.arch.find('_') + 1:] def target_is_x86(self): + """ + Return True if target CPU is x86 32 bits.. + + Return + ------ + bool + CPU is x86 32 bits + """ return self.target_cpu == 'x86' def current_is_x86(self): + """ + Return True if current CPU is x86 32 bits.. + + Return + ------ + bool + CPU is x86 32 bits + """ return self.current_cpu == 'x86' def current_dir(self, hidex86=False, x64=False): @@ -274,8 +427,8 @@ class PlatformInfo: Return ------ - subfolder: str - '\target', or '' (see hidex86 parameter) + str + subfolder: '\target', or '' (see hidex86 parameter) """ return ( '' if (self.current_cpu == 'x86' and hidex86) else @@ -296,8 +449,8 @@ class PlatformInfo: Return ------ - subfolder: str - '\current', or '' (see hidex86 parameter) + str + subfolder: '\current', or '' (see hidex86 parameter) """ return ( '' if (self.target_cpu == 'x86' and hidex86) else @@ -312,13 +465,13 @@ class PlatformInfo: Parameters ---------- forcex86: bool - Use 'x86' as current architecture even if current acritecture is + Use 'x86' as current architecture even if current architecture is not x86. Return ------ - subfolder: str - '' if target architecture is current architecture, + str + subfolder: '' if target architecture is current architecture, '\current_target' if not. """ current = 'x86' if forcex86 else self.current_cpu @@ -330,7 +483,7 @@ class PlatformInfo: class RegistryInfo: """ - Microsoft Visual Studio related registry informations. + Microsoft Visual Studio related registry information. Parameters ---------- @@ -349,6 +502,11 @@ class RegistryInfo: def visualstudio(self): """ Microsoft Visual Studio root registry key. + + Return + ------ + str + Registry key """ return 'VisualStudio' @@ -356,27 +514,47 @@ class RegistryInfo: def sxs(self): """ Microsoft Visual Studio SxS registry key. + + Return + ------ + str + Registry key """ - return os.path.join(self.visualstudio, 'SxS') + return join(self.visualstudio, 'SxS') @property def vc(self): """ Microsoft Visual C++ VC7 registry key. + + Return + ------ + str + Registry key """ - return os.path.join(self.sxs, 'VC7') + return join(self.sxs, 'VC7') @property def vs(self): """ Microsoft Visual Studio VS7 registry key. + + Return + ------ + str + Registry key """ - return os.path.join(self.sxs, 'VS7') + return join(self.sxs, 'VS7') @property def vc_for_python(self): """ Microsoft Visual C++ for Python registry key. + + Return + ------ + str + Registry key """ return r'DevDiv\VCForPython' @@ -384,6 +562,11 @@ class RegistryInfo: def microsoft_sdk(self): """ Microsoft SDK registry key. + + Return + ------ + str + Registry key """ return 'Microsoft SDKs' @@ -391,20 +574,35 @@ class RegistryInfo: def windows_sdk(self): """ Microsoft Windows/Platform SDK registry key. + + Return + ------ + str + Registry key """ - return os.path.join(self.microsoft_sdk, 'Windows') + return join(self.microsoft_sdk, 'Windows') @property def netfx_sdk(self): """ Microsoft .NET Framework SDK registry key. + + Return + ------ + str + Registry key """ - return os.path.join(self.microsoft_sdk, 'NETFXSDK') + return join(self.microsoft_sdk, 'NETFXSDK') @property def windows_kits_roots(self): """ Microsoft Windows Kits Roots registry key. + + Return + ------ + str + Registry key """ return r'Windows Kits\Installed Roots' @@ -421,10 +619,11 @@ class RegistryInfo: Return ------ - str: value + str + Registry key """ node64 = '' if self.pi.current_is_x86() or x86 else 'Wow6432Node' - return os.path.join('Software', node64, 'Microsoft', key) + return join('Software', node64, 'Microsoft', key) def lookup(self, key, name): """ @@ -439,18 +638,21 @@ class RegistryInfo: Return ------ - str: value + str + value """ - KEY_READ = winreg.KEY_READ + key_read = winreg.KEY_READ openkey = winreg.OpenKey + closekey = winreg.CloseKey ms = self.microsoft for hkey in self.HKEYS: + bkey = None try: - bkey = openkey(hkey, ms(key), 0, KEY_READ) + bkey = openkey(hkey, ms(key), 0, key_read) except (OSError, IOError): if not self.pi.current_is_x86(): try: - bkey = openkey(hkey, ms(key, True), 0, KEY_READ) + bkey = openkey(hkey, ms(key, True), 0, key_read) except (OSError, IOError): continue else: @@ -459,11 +661,14 @@ class RegistryInfo: return winreg.QueryValueEx(bkey, name)[0] except (OSError, IOError): pass + finally: + if bkey: + closekey(bkey) class SystemInfo: """ - Microsoft Windows and Visual Studio related system inormations. + Microsoft Windows and Visual Studio related system information. Parameters ---------- @@ -474,83 +679,165 @@ class SystemInfo: """ # Variables and properties in this class use originals CamelCase variables - # names from Microsoft source files for more easy comparaison. - WinDir = safe_env.get('WinDir', '') - ProgramFiles = safe_env.get('ProgramFiles', '') - ProgramFilesx86 = safe_env.get('ProgramFiles(x86)', ProgramFiles) + # names from Microsoft source files for more easy comparison. + WinDir = environ.get('WinDir', '') + ProgramFiles = environ.get('ProgramFiles', '') + ProgramFilesx86 = environ.get('ProgramFiles(x86)', ProgramFiles) def __init__(self, registry_info, vc_ver=None): self.ri = registry_info self.pi = self.ri.pi - self.vc_ver = vc_ver or self._find_latest_available_vc_ver() - def _find_latest_available_vc_ver(self): - try: - return self.find_available_vc_vers()[-1] - except IndexError: - err = 'No Microsoft Visual C++ version found' - raise distutils.errors.DistutilsPlatformError(err) + self.known_vs_paths = self.find_programdata_vs_vers() - def find_available_vc_vers(self): + # Except for VS15+, VC version is aligned with VS version + self.vs_ver = self.vc_ver = ( + vc_ver or self._find_latest_available_vs_ver()) + + def _find_latest_available_vs_ver(self): """ - Find all available Microsoft Visual C++ versions. + Find the latest VC version + + Return + ------ + float + version + """ + reg_vc_vers = self.find_reg_vs_vers() + + if not (reg_vc_vers or self.known_vs_paths): + raise distutils.errors.DistutilsPlatformError( + 'No Microsoft Visual C++ version found') + + vc_vers = set(reg_vc_vers) + vc_vers.update(self.known_vs_paths) + return sorted(vc_vers)[-1] + + def find_reg_vs_vers(self): + """ + Find Microsoft Visual Studio versions available in registry. + + Return + ------ + list of float + Versions """ ms = self.ri.microsoft vckeys = (self.ri.vc, self.ri.vc_for_python, self.ri.vs) - vc_vers = [] + vs_vers = [] for hkey in self.ri.HKEYS: for key in vckeys: try: bkey = winreg.OpenKey(hkey, ms(key), 0, winreg.KEY_READ) except (OSError, IOError): continue - subkeys, values, _ = winreg.QueryInfoKey(bkey) - for i in range(values): - try: - ver = float(winreg.EnumValue(bkey, i)[0]) - if ver not in vc_vers: - vc_vers.append(ver) - except ValueError: - pass - for i in range(subkeys): - try: - ver = float(winreg.EnumKey(bkey, i)) - if ver not in vc_vers: - vc_vers.append(ver) - except ValueError: - pass - return sorted(vc_vers) + with bkey: + subkeys, values, _ = winreg.QueryInfoKey(bkey) + for i in range(values): + try: + ver = float(winreg.EnumValue(bkey, i)[0]) + if ver not in vs_vers: + vs_vers.append(ver) + except ValueError: + pass + for i in range(subkeys): + try: + ver = float(winreg.EnumKey(bkey, i)) + if ver not in vs_vers: + vs_vers.append(ver) + except ValueError: + pass + return sorted(vs_vers) + + def find_programdata_vs_vers(self): + r""" + Find Visual studio 2017+ versions from information in + "C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances". + + Return + ------ + dict + float version as key, path as value. + """ + vs_versions = {} + instances_dir = \ + r'C:\ProgramData\Microsoft\VisualStudio\Packages\_Instances' + + try: + hashed_names = listdir(instances_dir) + + except (OSError, IOError): + # Directory not exists with all Visual Studio versions + return vs_versions + + for name in hashed_names: + try: + # Get VS installation path from "state.json" file + state_path = join(instances_dir, name, 'state.json') + with open(state_path, 'rt', encoding='utf-8') as state_file: + state = json.load(state_file) + vs_path = state['installationPath'] + + # Raises OSError if this VS installation does not contain VC + listdir(join(vs_path, r'VC\Tools\MSVC')) + + # Store version and path + vs_versions[self._as_float_version( + state['installationVersion'])] = vs_path + + except (OSError, IOError, KeyError): + # Skip if "state.json" file is missing or bad format + continue + + return vs_versions + + @staticmethod + def _as_float_version(version): + """ + Return a string version as a simplified float version (major.minor) + + Parameters + ---------- + version: str + Version. + + Return + ------ + float + version + """ + return float('.'.join(version.split('.')[:2])) @property def VSInstallDir(self): """ Microsoft Visual Studio directory. + + Return + ------ + str + path """ # Default path - name = 'Microsoft Visual Studio %0.1f' % self.vc_ver - default = os.path.join(self.ProgramFilesx86, name) + default = join(self.ProgramFilesx86, + 'Microsoft Visual Studio %0.1f' % self.vs_ver) # Try to get path from registry, if fail use default path - return self.ri.lookup(self.ri.vs, '%0.1f' % self.vc_ver) or default + return self.ri.lookup(self.ri.vs, '%0.1f' % self.vs_ver) or default @property def VCInstallDir(self): """ Microsoft Visual C++ directory. + + Return + ------ + str + path """ - self.VSInstallDir + path = self._guess_vc() or self._guess_vc_legacy() - guess_vc = self._guess_vc() or self._guess_vc_legacy() - - # Try to get "VC++ for Python" path from registry as default path - reg_path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver) - python_vc = self.ri.lookup(reg_path, 'installdir') - default_vc = os.path.join(python_vc, 'VC') if python_vc else guess_vc - - # Try to get path from registry, if fail use default path - path = self.ri.lookup(self.ri.vc, '%0.1f' % self.vc_ver) or default_vc - - if not os.path.isdir(path): + if not isdir(path): msg = 'Microsoft Visual C++ directory not found' raise distutils.errors.DistutilsPlatformError(msg) @@ -558,186 +845,256 @@ class SystemInfo: def _guess_vc(self): """ - Locate Visual C for 2017 - """ - if self.vc_ver <= 14.0: - return + Locate Visual C++ for VS2017+. + + Return + ------ + str + path + """ + if self.vs_ver <= 14.0: + return '' + + try: + # First search in known VS paths + vs_dir = self.known_vs_paths[self.vs_ver] + except KeyError: + # Else, search with path from registry + vs_dir = self.VSInstallDir + + guess_vc = join(vs_dir, r'VC\Tools\MSVC') - default = r'VC\Tools\MSVC' - guess_vc = os.path.join(self.VSInstallDir, default) # Subdir with VC exact version as name try: - vc_exact_ver = os.listdir(guess_vc)[-1] - return os.path.join(guess_vc, vc_exact_ver) + # Update the VC version with real one instead of VS version + vc_ver = listdir(guess_vc)[-1] + self.vc_ver = self._as_float_version(vc_ver) + return join(guess_vc, vc_ver) except (OSError, IOError, IndexError): - pass + return '' def _guess_vc_legacy(self): """ - Locate Visual C for versions prior to 2017 + Locate Visual C++ for versions prior to 2017. + + Return + ------ + str + path """ - default = r'Microsoft Visual Studio %0.1f\VC' % self.vc_ver - return os.path.join(self.ProgramFilesx86, default) + default = join(self.ProgramFilesx86, + r'Microsoft Visual Studio %0.1f\VC' % self.vs_ver) + + # Try to get "VC++ for Python" path from registry as default path + reg_path = join(self.ri.vc_for_python, '%0.1f' % self.vs_ver) + python_vc = self.ri.lookup(reg_path, 'installdir') + default_vc = join(python_vc, 'VC') if python_vc else default + + # Try to get path from registry, if fail use default path + return self.ri.lookup(self.ri.vc, '%0.1f' % self.vs_ver) or default_vc @property def WindowsSdkVersion(self): """ Microsoft Windows SDK versions for specified MSVC++ version. + + Return + ------ + tuple of str + versions """ - if self.vc_ver <= 9.0: - return ('7.0', '6.1', '6.0a') - elif self.vc_ver == 10.0: - return ('7.1', '7.0a') - elif self.vc_ver == 11.0: - return ('8.0', '8.0a') - elif self.vc_ver == 12.0: - return ('8.1', '8.1a') - elif self.vc_ver >= 14.0: - return ('10.0', '8.1') + if self.vs_ver <= 9.0: + return '7.0', '6.1', '6.0a' + elif self.vs_ver == 10.0: + return '7.1', '7.0a' + elif self.vs_ver == 11.0: + return '8.0', '8.0a' + elif self.vs_ver == 12.0: + return '8.1', '8.1a' + elif self.vs_ver >= 14.0: + return '10.0', '8.1' @property def WindowsSdkLastVersion(self): """ - Microsoft Windows SDK last version + Microsoft Windows SDK last version. + + Return + ------ + str + version """ - return self._use_last_dir_name(os.path.join( - self.WindowsSdkDir, 'lib')) + return self._use_last_dir_name(join(self.WindowsSdkDir, 'lib')) @property def WindowsSdkDir(self): """ Microsoft Windows SDK directory. + + Return + ------ + str + path """ sdkdir = '' for ver in self.WindowsSdkVersion: # Try to get it from registry - loc = os.path.join(self.ri.windows_sdk, 'v%s' % ver) + loc = join(self.ri.windows_sdk, 'v%s' % ver) sdkdir = self.ri.lookup(loc, 'installationfolder') if sdkdir: break - if not sdkdir or not os.path.isdir(sdkdir): + if not sdkdir or not isdir(sdkdir): # Try to get "VC++ for Python" version from registry - path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver) + path = join(self.ri.vc_for_python, '%0.1f' % self.vc_ver) install_base = self.ri.lookup(path, 'installdir') if install_base: - sdkdir = os.path.join(install_base, 'WinSDK') - if not sdkdir or not os.path.isdir(sdkdir): + sdkdir = join(install_base, 'WinSDK') + if not sdkdir or not isdir(sdkdir): # If fail, use default new path for ver in self.WindowsSdkVersion: intver = ver[:ver.rfind('.')] - path = r'Microsoft SDKs\Windows Kits\%s' % (intver) - d = os.path.join(self.ProgramFiles, path) - if os.path.isdir(d): + path = r'Microsoft SDKs\Windows Kits\%s' % intver + d = join(self.ProgramFiles, path) + if isdir(d): sdkdir = d - if not sdkdir or not os.path.isdir(sdkdir): + if not sdkdir or not isdir(sdkdir): # If fail, use default old path for ver in self.WindowsSdkVersion: path = r'Microsoft SDKs\Windows\v%s' % ver - d = os.path.join(self.ProgramFiles, path) - if os.path.isdir(d): + d = join(self.ProgramFiles, path) + if isdir(d): sdkdir = d if not sdkdir: # If fail, use Platform SDK - sdkdir = os.path.join(self.VCInstallDir, 'PlatformSDK') + sdkdir = join(self.VCInstallDir, 'PlatformSDK') return sdkdir @property def WindowsSDKExecutablePath(self): """ Microsoft Windows SDK executable directory. + + Return + ------ + str + path """ # Find WinSDK NetFx Tools registry dir name - if self.vc_ver <= 11.0: + if self.vs_ver <= 11.0: netfxver = 35 arch = '' else: netfxver = 40 - hidex86 = True if self.vc_ver <= 12.0 else False + hidex86 = True if self.vs_ver <= 12.0 else False arch = self.pi.current_dir(x64=True, hidex86=hidex86) fx = 'WinSDK-NetFx%dTools%s' % (netfxver, arch.replace('\\', '-')) - # liste all possibles registry paths + # list all possibles registry paths regpaths = [] - if self.vc_ver >= 14.0: + if self.vs_ver >= 14.0: for ver in self.NetFxSdkVersion: - regpaths += [os.path.join(self.ri.netfx_sdk, ver, fx)] + regpaths += [join(self.ri.netfx_sdk, ver, fx)] for ver in self.WindowsSdkVersion: - regpaths += [os.path.join(self.ri.windows_sdk, 'v%sA' % ver, fx)] + regpaths += [join(self.ri.windows_sdk, 'v%sA' % ver, fx)] # Return installation folder from the more recent path for path in regpaths: execpath = self.ri.lookup(path, 'installationfolder') if execpath: - break - return execpath + return execpath @property def FSharpInstallDir(self): """ Microsoft Visual F# directory. + + Return + ------ + str + path """ - path = r'%0.1f\Setup\F#' % self.vc_ver - path = os.path.join(self.ri.visualstudio, path) + path = join(self.ri.visualstudio, r'%0.1f\Setup\F#' % self.vs_ver) return self.ri.lookup(path, 'productdir') or '' @property def UniversalCRTSdkDir(self): """ Microsoft Universal CRT SDK directory. + + Return + ------ + str + path """ # Set Kit Roots versions for specified MSVC++ version - if self.vc_ver >= 14.0: - vers = ('10', '81') - else: - vers = () + vers = ('10', '81') if self.vs_ver >= 14.0 else () # Find path of the more recent Kit for ver in vers: sdkdir = self.ri.lookup(self.ri.windows_kits_roots, 'kitsroot%s' % ver) if sdkdir: - break - return sdkdir or '' + return sdkdir or '' @property def UniversalCRTSdkLastVersion(self): """ - Microsoft Universal C Runtime SDK last version + Microsoft Universal C Runtime SDK last version. + + Return + ------ + str + version """ - return self._use_last_dir_name(os.path.join( - self.UniversalCRTSdkDir, 'lib')) + return self._use_last_dir_name(join(self.UniversalCRTSdkDir, 'lib')) @property def NetFxSdkVersion(self): """ Microsoft .NET Framework SDK versions. + + Return + ------ + tuple of str + versions """ - # Set FxSdk versions for specified MSVC++ version - if self.vc_ver >= 14.0: - return ('4.6.1', '4.6') - else: - return () + # Set FxSdk versions for specified VS version + return (('4.7.2', '4.7.1', '4.7', + '4.6.2', '4.6.1', '4.6', + '4.5.2', '4.5.1', '4.5') + if self.vs_ver >= 14.0 else ()) @property def NetFxSdkDir(self): """ Microsoft .NET Framework SDK directory. + + Return + ------ + str + path """ + sdkdir = '' for ver in self.NetFxSdkVersion: - loc = os.path.join(self.ri.netfx_sdk, ver) + loc = join(self.ri.netfx_sdk, ver) sdkdir = self.ri.lookup(loc, 'kitsinstallationfolder') if sdkdir: break - return sdkdir or '' + return sdkdir @property def FrameworkDir32(self): """ Microsoft .NET Framework 32bit directory. + + Return + ------ + str + path """ # Default path - guess_fw = os.path.join(self.WinDir, r'Microsoft.NET\Framework') + guess_fw = join(self.WinDir, r'Microsoft.NET\Framework') # Try to get path from registry, if fail use default path return self.ri.lookup(self.ri.vc, 'frameworkdir32') or guess_fw @@ -746,9 +1103,14 @@ class SystemInfo: def FrameworkDir64(self): """ Microsoft .NET Framework 64bit directory. + + Return + ------ + str + path """ # Default path - guess_fw = os.path.join(self.WinDir, r'Microsoft.NET\Framework64') + guess_fw = join(self.WinDir, r'Microsoft.NET\Framework64') # Try to get path from registry, if fail use default path return self.ri.lookup(self.ri.vc, 'frameworkdir64') or guess_fw @@ -757,6 +1119,11 @@ class SystemInfo: def FrameworkVersion32(self): """ Microsoft .NET Framework 32bit versions. + + Return + ------ + tuple of str + versions """ return self._find_dot_net_versions(32) @@ -764,6 +1131,11 @@ class SystemInfo: def FrameworkVersion64(self): """ Microsoft .NET Framework 64bit versions. + + Return + ------ + tuple of str + versions """ return self._find_dot_net_versions(64) @@ -775,6 +1147,11 @@ class SystemInfo: ---------- bits: int Platform number of bits: 32 or 64. + + Return + ------ + tuple of str + versions """ # Find actual .NET version in registry reg_ver = self.ri.lookup(self.ri.vc, 'frameworkver%d' % bits) @@ -782,18 +1159,17 @@ class SystemInfo: ver = reg_ver or self._use_last_dir_name(dot_net_dir, 'v') or '' # Set .NET versions for specified MSVC++ version - if self.vc_ver >= 12.0: - frameworkver = (ver, 'v4.0') - elif self.vc_ver >= 10.0: - frameworkver = ('v4.0.30319' if ver.lower()[:2] != 'v4' else ver, - 'v3.5') - elif self.vc_ver == 9.0: - frameworkver = ('v3.5', 'v2.0.50727') - if self.vc_ver == 8.0: - frameworkver = ('v3.0', 'v2.0.50727') - return frameworkver + if self.vs_ver >= 12.0: + return ver, 'v4.0' + elif self.vs_ver >= 10.0: + return 'v4.0.30319' if ver.lower()[:2] != 'v4' else ver, 'v3.5' + elif self.vs_ver == 9.0: + return 'v3.5', 'v2.0.50727' + elif self.vs_ver == 8.0: + return 'v3.0', 'v2.0.50727' - def _use_last_dir_name(self, path, prefix=''): + @staticmethod + def _use_last_dir_name(path, prefix=''): """ Return name of the last dir in path or '' if no dir found. @@ -802,12 +1178,17 @@ class SystemInfo: path: str Use dirs in this path prefix: str - Use only dirs startings by this prefix + Use only dirs starting by this prefix + + Return + ------ + str + name """ matching_dirs = ( dir_name - for dir_name in reversed(os.listdir(path)) - if os.path.isdir(os.path.join(path, dir_name)) and + for dir_name in reversed(listdir(path)) + if isdir(join(path, dir_name)) and dir_name.startswith(prefix) ) return next(matching_dirs, None) or '' @@ -818,7 +1199,7 @@ class EnvironmentInfo: Return environment variables for specified Microsoft Visual C++ version and platform : Lib, Include, Path and libpath. - This function is compatible with Microsoft Visual C++ 9.0 to 14.0. + This function is compatible with Microsoft Visual C++ 9.0 to 14.X. Script created by analysing Microsoft environment configuration files like "vcvars[...].bat", "SetEnv.Cmd", "vcbuildtools.bat", ... @@ -835,7 +1216,7 @@ class EnvironmentInfo: """ # Variables and properties in this class use originals CamelCase variables - # names from Microsoft source files for more easy comparaison. + # names from Microsoft source files for more easy comparison. def __init__(self, arch, vc_ver=None, vc_min_ver=0): self.pi = PlatformInfo(arch) @@ -846,205 +1227,258 @@ class EnvironmentInfo: err = 'No suitable Microsoft Visual C++ version found' raise distutils.errors.DistutilsPlatformError(err) + @property + def vs_ver(self): + """ + Microsoft Visual Studio. + + Return + ------ + float + version + """ + return self.si.vs_ver + @property def vc_ver(self): """ Microsoft Visual C++ version. + + Return + ------ + float + version """ return self.si.vc_ver @property def VSTools(self): """ - Microsoft Visual Studio Tools + Microsoft Visual Studio Tools. + + Return + ------ + list of str + paths """ paths = [r'Common7\IDE', r'Common7\Tools'] - if self.vc_ver >= 14.0: + if self.vs_ver >= 14.0: arch_subdir = self.pi.current_dir(hidex86=True, x64=True) paths += [r'Common7\IDE\CommonExtensions\Microsoft\TestWindow'] paths += [r'Team Tools\Performance Tools'] paths += [r'Team Tools\Performance Tools%s' % arch_subdir] - return [os.path.join(self.si.VSInstallDir, path) for path in paths] + return [join(self.si.VSInstallDir, path) for path in paths] @property def VCIncludes(self): """ - Microsoft Visual C++ & Microsoft Foundation Class Includes + Microsoft Visual C++ & Microsoft Foundation Class Includes. + + Return + ------ + list of str + paths """ - return [os.path.join(self.si.VCInstallDir, 'Include'), - os.path.join(self.si.VCInstallDir, r'ATLMFC\Include')] + return [join(self.si.VCInstallDir, 'Include'), + join(self.si.VCInstallDir, r'ATLMFC\Include')] @property def VCLibraries(self): """ - Microsoft Visual C++ & Microsoft Foundation Class Libraries + Microsoft Visual C++ & Microsoft Foundation Class Libraries. + + Return + ------ + list of str + paths """ - if self.vc_ver >= 15.0: + if self.vs_ver >= 15.0: arch_subdir = self.pi.target_dir(x64=True) else: arch_subdir = self.pi.target_dir(hidex86=True) paths = ['Lib%s' % arch_subdir, r'ATLMFC\Lib%s' % arch_subdir] - if self.vc_ver >= 14.0: + if self.vs_ver >= 14.0: paths += [r'Lib\store%s' % arch_subdir] - return [os.path.join(self.si.VCInstallDir, path) for path in paths] + return [join(self.si.VCInstallDir, path) for path in paths] @property def VCStoreRefs(self): """ - Microsoft Visual C++ store references Libraries + Microsoft Visual C++ store references Libraries. + + Return + ------ + list of str + paths """ - if self.vc_ver < 14.0: + if self.vs_ver < 14.0: return [] - return [os.path.join(self.si.VCInstallDir, r'Lib\store\references')] + return [join(self.si.VCInstallDir, r'Lib\store\references')] @property def VCTools(self): """ - Microsoft Visual C++ Tools + Microsoft Visual C++ Tools. + + Return + ------ + list of str + paths """ si = self.si - tools = [os.path.join(si.VCInstallDir, 'VCPackages')] + tools = [join(si.VCInstallDir, 'VCPackages')] - forcex86 = True if self.vc_ver <= 10.0 else False + forcex86 = True if self.vs_ver <= 10.0 else False arch_subdir = self.pi.cross_dir(forcex86) if arch_subdir: - tools += [os.path.join(si.VCInstallDir, 'Bin%s' % arch_subdir)] + tools += [join(si.VCInstallDir, 'Bin%s' % arch_subdir)] - if self.vc_ver == 14.0: + if self.vs_ver == 14.0: path = 'Bin%s' % self.pi.current_dir(hidex86=True) - tools += [os.path.join(si.VCInstallDir, path)] + tools += [join(si.VCInstallDir, path)] - elif self.vc_ver >= 15.0: + elif self.vs_ver >= 15.0: host_dir = (r'bin\HostX86%s' if self.pi.current_is_x86() else r'bin\HostX64%s') - tools += [os.path.join( + tools += [join( si.VCInstallDir, host_dir % self.pi.target_dir(x64=True))] if self.pi.current_cpu != self.pi.target_cpu: - tools += [os.path.join( + tools += [join( si.VCInstallDir, host_dir % self.pi.current_dir(x64=True))] else: - tools += [os.path.join(si.VCInstallDir, 'Bin')] + tools += [join(si.VCInstallDir, 'Bin')] return tools @property def OSLibraries(self): """ - Microsoft Windows SDK Libraries + Microsoft Windows SDK Libraries. + + Return + ------ + list of str + paths """ - if self.vc_ver <= 10.0: + if self.vs_ver <= 10.0: arch_subdir = self.pi.target_dir(hidex86=True, x64=True) - return [os.path.join(self.si.WindowsSdkDir, 'Lib%s' % arch_subdir)] + return [join(self.si.WindowsSdkDir, 'Lib%s' % arch_subdir)] else: arch_subdir = self.pi.target_dir(x64=True) - lib = os.path.join(self.si.WindowsSdkDir, 'lib') + lib = join(self.si.WindowsSdkDir, 'lib') libver = self._sdk_subdir - return [os.path.join(lib, '%sum%s' % (libver , arch_subdir))] + return [join(lib, '%sum%s' % (libver, arch_subdir))] @property def OSIncludes(self): """ - Microsoft Windows SDK Include - """ - include = os.path.join(self.si.WindowsSdkDir, 'include') + Microsoft Windows SDK Include. - if self.vc_ver <= 10.0: - return [include, os.path.join(include, 'gl')] + Return + ------ + list of str + paths + """ + include = join(self.si.WindowsSdkDir, 'include') + + if self.vs_ver <= 10.0: + return [include, join(include, 'gl')] else: - if self.vc_ver >= 14.0: + if self.vs_ver >= 14.0: sdkver = self._sdk_subdir else: sdkver = '' - return [os.path.join(include, '%sshared' % sdkver), - os.path.join(include, '%sum' % sdkver), - os.path.join(include, '%swinrt' % sdkver)] + return [join(include, '%sshared' % sdkver), + join(include, '%sum' % sdkver), + join(include, '%swinrt' % sdkver)] @property def OSLibpath(self): """ - Microsoft Windows SDK Libraries Paths + Microsoft Windows SDK Libraries Paths. + + Return + ------ + list of str + paths """ - ref = os.path.join(self.si.WindowsSdkDir, 'References') + ref = join(self.si.WindowsSdkDir, 'References') libpath = [] - if self.vc_ver <= 9.0: + if self.vs_ver <= 9.0: libpath += self.OSLibraries - if self.vc_ver >= 11.0: - libpath += [os.path.join(ref, r'CommonConfiguration\Neutral')] + if self.vs_ver >= 11.0: + libpath += [join(ref, r'CommonConfiguration\Neutral')] - if self.vc_ver >= 14.0: + if self.vs_ver >= 14.0: libpath += [ ref, - os.path.join(self.si.WindowsSdkDir, 'UnionMetadata'), - os.path.join( - ref, - 'Windows.Foundation.UniversalApiContract', - '1.0.0.0', - ), - os.path.join( - ref, - 'Windows.Foundation.FoundationContract', - '1.0.0.0', - ), - os.path.join( - ref, - 'Windows.Networking.Connectivity.WwanContract', - '1.0.0.0', - ), - os.path.join( - self.si.WindowsSdkDir, - 'ExtensionSDKs', - 'Microsoft.VCLibs', - '%0.1f' % self.vc_ver, - 'References', - 'CommonConfiguration', - 'neutral', - ), + join(self.si.WindowsSdkDir, 'UnionMetadata'), + join( + ref, 'Windows.Foundation.UniversalApiContract', '1.0.0.0'), + join(ref, 'Windows.Foundation.FoundationContract', '1.0.0.0'), + join( + ref, 'Windows.Networking.Connectivity.WwanContract', + '1.0.0.0'), + join( + self.si.WindowsSdkDir, 'ExtensionSDKs', 'Microsoft.VCLibs', + '%0.1f' % self.vs_ver, 'References', 'CommonConfiguration', + 'neutral'), ] return libpath @property def SdkTools(self): """ - Microsoft Windows SDK Tools + Microsoft Windows SDK Tools. + + Return + ------ + list of str + paths """ return list(self._sdk_tools()) def _sdk_tools(self): """ - Microsoft Windows SDK Tools paths generator + Microsoft Windows SDK Tools paths generator. + + Return + ------ + generator of str + paths """ - if self.vc_ver < 15.0: - bin_dir = 'Bin' if self.vc_ver <= 11.0 else r'Bin\x86' - yield os.path.join(self.si.WindowsSdkDir, bin_dir) + if self.vs_ver < 15.0: + bin_dir = 'Bin' if self.vs_ver <= 11.0 else r'Bin\x86' + yield join(self.si.WindowsSdkDir, bin_dir) if not self.pi.current_is_x86(): arch_subdir = self.pi.current_dir(x64=True) path = 'Bin%s' % arch_subdir - yield os.path.join(self.si.WindowsSdkDir, path) + yield join(self.si.WindowsSdkDir, path) - if self.vc_ver == 10.0 or self.vc_ver == 11.0: + if self.vs_ver in (10.0, 11.0): if self.pi.target_is_x86(): arch_subdir = '' else: arch_subdir = self.pi.current_dir(hidex86=True, x64=True) path = r'Bin\NETFX 4.0 Tools%s' % arch_subdir - yield os.path.join(self.si.WindowsSdkDir, path) + yield join(self.si.WindowsSdkDir, path) - elif self.vc_ver >= 15.0: - path = os.path.join(self.si.WindowsSdkDir, 'Bin') + elif self.vs_ver >= 15.0: + path = join(self.si.WindowsSdkDir, 'Bin') arch_subdir = self.pi.current_dir(x64=True) sdkver = self.si.WindowsSdkLastVersion - yield os.path.join(path, '%s%s' % (sdkver, arch_subdir)) + yield join(path, '%s%s' % (sdkver, arch_subdir)) if self.si.WindowsSDKExecutablePath: yield self.si.WindowsSDKExecutablePath @@ -1052,7 +1486,12 @@ class EnvironmentInfo: @property def _sdk_subdir(self): """ - Microsoft Windows SDK version subdir + Microsoft Windows SDK version subdir. + + Return + ------ + str + subdir """ ucrtver = self.si.WindowsSdkLastVersion return ('%s\\' % ucrtver) if ucrtver else '' @@ -1060,22 +1499,32 @@ class EnvironmentInfo: @property def SdkSetup(self): """ - Microsoft Windows SDK Setup + Microsoft Windows SDK Setup. + + Return + ------ + list of str + paths """ - if self.vc_ver > 9.0: + if self.vs_ver > 9.0: return [] - return [os.path.join(self.si.WindowsSdkDir, 'Setup')] + return [join(self.si.WindowsSdkDir, 'Setup')] @property def FxTools(self): """ - Microsoft .NET Framework Tools + Microsoft .NET Framework Tools. + + Return + ------ + list of str + paths """ pi = self.pi si = self.si - if self.vc_ver <= 10.0: + if self.vs_ver <= 10.0: include32 = True include64 = not pi.target_is_x86() and not pi.current_is_x86() else: @@ -1084,102 +1533,142 @@ class EnvironmentInfo: tools = [] if include32: - tools += [os.path.join(si.FrameworkDir32, ver) + tools += [join(si.FrameworkDir32, ver) for ver in si.FrameworkVersion32] if include64: - tools += [os.path.join(si.FrameworkDir64, ver) + tools += [join(si.FrameworkDir64, ver) for ver in si.FrameworkVersion64] return tools @property def NetFxSDKLibraries(self): """ - Microsoft .Net Framework SDK Libraries + Microsoft .Net Framework SDK Libraries. + + Return + ------ + list of str + paths """ - if self.vc_ver < 14.0 or not self.si.NetFxSdkDir: + if self.vs_ver < 14.0 or not self.si.NetFxSdkDir: return [] arch_subdir = self.pi.target_dir(x64=True) - return [os.path.join(self.si.NetFxSdkDir, r'lib\um%s' % arch_subdir)] + return [join(self.si.NetFxSdkDir, r'lib\um%s' % arch_subdir)] @property def NetFxSDKIncludes(self): """ - Microsoft .Net Framework SDK Includes + Microsoft .Net Framework SDK Includes. + + Return + ------ + list of str + paths """ - if self.vc_ver < 14.0 or not self.si.NetFxSdkDir: + if self.vs_ver < 14.0 or not self.si.NetFxSdkDir: return [] - return [os.path.join(self.si.NetFxSdkDir, r'include\um')] + return [join(self.si.NetFxSdkDir, r'include\um')] @property def VsTDb(self): """ - Microsoft Visual Studio Team System Database + Microsoft Visual Studio Team System Database. + + Return + ------ + list of str + paths """ - return [os.path.join(self.si.VSInstallDir, r'VSTSDB\Deploy')] + return [join(self.si.VSInstallDir, r'VSTSDB\Deploy')] @property def MSBuild(self): """ - Microsoft Build Engine + Microsoft Build Engine. + + Return + ------ + list of str + paths """ - if self.vc_ver < 12.0: + if self.vs_ver < 12.0: return [] - elif self.vc_ver < 15.0: + elif self.vs_ver < 15.0: base_path = self.si.ProgramFilesx86 arch_subdir = self.pi.current_dir(hidex86=True) else: base_path = self.si.VSInstallDir arch_subdir = '' - path = r'MSBuild\%0.1f\bin%s' % (self.vc_ver, arch_subdir) - build = [os.path.join(base_path, path)] + path = r'MSBuild\%0.1f\bin%s' % (self.vs_ver, arch_subdir) + build = [join(base_path, path)] - if self.vc_ver >= 15.0: + if self.vs_ver >= 15.0: # Add Roslyn C# & Visual Basic Compiler - build += [os.path.join(base_path, path, 'Roslyn')] + build += [join(base_path, path, 'Roslyn')] return build @property def HTMLHelpWorkshop(self): """ - Microsoft HTML Help Workshop + Microsoft HTML Help Workshop. + + Return + ------ + list of str + paths """ - if self.vc_ver < 11.0: + if self.vs_ver < 11.0: return [] - return [os.path.join(self.si.ProgramFilesx86, 'HTML Help Workshop')] + return [join(self.si.ProgramFilesx86, 'HTML Help Workshop')] @property def UCRTLibraries(self): """ - Microsoft Universal C Runtime SDK Libraries + Microsoft Universal C Runtime SDK Libraries. + + Return + ------ + list of str + paths """ - if self.vc_ver < 14.0: + if self.vs_ver < 14.0: return [] arch_subdir = self.pi.target_dir(x64=True) - lib = os.path.join(self.si.UniversalCRTSdkDir, 'lib') + lib = join(self.si.UniversalCRTSdkDir, 'lib') ucrtver = self._ucrt_subdir - return [os.path.join(lib, '%sucrt%s' % (ucrtver, arch_subdir))] + return [join(lib, '%sucrt%s' % (ucrtver, arch_subdir))] @property def UCRTIncludes(self): """ - Microsoft Universal C Runtime SDK Include + Microsoft Universal C Runtime SDK Include. + + Return + ------ + list of str + paths """ - if self.vc_ver < 14.0: + if self.vs_ver < 14.0: return [] - include = os.path.join(self.si.UniversalCRTSdkDir, 'include') - return [os.path.join(include, '%sucrt' % self._ucrt_subdir)] + include = join(self.si.UniversalCRTSdkDir, 'include') + return [join(include, '%sucrt' % self._ucrt_subdir)] @property def _ucrt_subdir(self): """ - Microsoft Universal C Runtime SDK version subdir + Microsoft Universal C Runtime SDK version subdir. + + Return + ------ + str + subdir """ ucrtver = self.si.UniversalCRTSdkLastVersion return ('%s\\' % ucrtver) if ucrtver else '' @@ -1187,31 +1676,52 @@ class EnvironmentInfo: @property def FSharp(self): """ - Microsoft Visual F# + Microsoft Visual F#. + + Return + ------ + list of str + paths """ - if self.vc_ver < 11.0 and self.vc_ver > 12.0: + if 11.0 > self.vs_ver > 12.0: return [] - return self.si.FSharpInstallDir + return [self.si.FSharpInstallDir] @property def VCRuntimeRedist(self): """ - Microsoft Visual C++ runtime redistribuable dll + Microsoft Visual C++ runtime redistributable dll. + + Return + ------ + str + path """ - arch_subdir = self.pi.target_dir(x64=True) - if self.vc_ver < 15: - redist_path = self.si.VCInstallDir - vcruntime = 'redist%s\\Microsoft.VC%d0.CRT\\vcruntime%d0.dll' - else: - redist_path = self.si.VCInstallDir.replace('\\Tools', '\\Redist') - vcruntime = 'onecore%s\\Microsoft.VC%d0.CRT\\vcruntime%d0.dll' + vcruntime = 'vcruntime%d0.dll' % self.vc_ver + arch_subdir = self.pi.target_dir(x64=True).strip('\\') - # Visual Studio 2017 is still Visual C++ 14.0 - dll_ver = 14.0 if self.vc_ver == 15 else self.vc_ver + # Installation prefixes candidates + prefixes = [] + tools_path = self.si.VCInstallDir + redist_path = dirname(tools_path.replace(r'\Tools', r'\Redist')) + if isdir(redist_path): + # Redist version may not be exactly the same as tools + redist_path = join(redist_path, listdir(redist_path)[-1]) + prefixes += [redist_path, join(redist_path, 'onecore')] - vcruntime = vcruntime % (arch_subdir, self.vc_ver, dll_ver) - return os.path.join(redist_path, vcruntime) + prefixes += [join(tools_path, 'redist')] # VS14 legacy path + + # CRT directory + crt_dirs = ('Microsoft.VC%d.CRT' % (self.vc_ver * 10), + # Sometime store in directory with VS version instead of VC + 'Microsoft.VC%d.CRT' % (int(self.vs_ver) * 10)) + + # vcruntime path + for prefix, crt_dir in itertools.product(prefixes, crt_dirs): + path = join(prefix, arch_subdir, crt_dir, vcruntime) + if isfile(path): + return path def return_env(self, exists=True): """ @@ -1221,6 +1731,11 @@ class EnvironmentInfo: ---------- exists: bool It True, only return existing paths. + + Return + ------ + dict + environment """ env = dict( include=self._build_paths('include', @@ -1254,7 +1769,7 @@ class EnvironmentInfo: self.FSharp], exists), ) - if self.vc_ver >= 14 and os.path.isfile(self.VCRuntimeRedist): + if self.vs_ver >= 14 and isfile(self.VCRuntimeRedist): env['py_vcruntime_redist'] = self.VCRuntimeRedist return env @@ -1265,20 +1780,35 @@ class EnvironmentInfo: unique, extant, directories from those paths and from the environment variable. Raise an error if no paths are resolved. + + Parameters + ---------- + name: str + Environment variable name + spec_path_lists: list of str + Paths + exists: bool + It True, only return existing paths. + + Return + ------ + str + Pathsep-separated paths """ # flatten spec_path_lists spec_paths = itertools.chain.from_iterable(spec_path_lists) - env_paths = safe_env.get(name, '').split(os.pathsep) + env_paths = environ.get(name, '').split(pathsep) paths = itertools.chain(spec_paths, env_paths) - extant_paths = list(filter(os.path.isdir, paths)) if exists else paths + extant_paths = list(filter(isdir, paths)) if exists else paths if not extant_paths: msg = "%s environment variable is empty" % name.upper() raise distutils.errors.DistutilsPlatformError(msg) unique_paths = self._unique_everseen(extant_paths) - return os.pathsep.join(unique_paths) + return pathsep.join(unique_paths) # from Python docs - def _unique_everseen(self, iterable, key=None): + @staticmethod + def _unique_everseen(iterable, key=None): """ List unique elements, preserving order. Remember all elements ever seen. diff --git a/venv/lib/python3.8/site-packages/setuptools/namespaces.py b/venv/lib/python3.8/site-packages/setuptools/namespaces.py index dc16106..5f403c9 100644 --- a/venv/lib/python3.8/site-packages/setuptools/namespaces.py +++ b/venv/lib/python3.8/site-packages/setuptools/namespaces.py @@ -47,13 +47,17 @@ class Installer: "p = os.path.join(%(root)s, *%(pth)r)", "importlib = has_mfs and __import__('importlib.util')", "has_mfs and __import__('importlib.machinery')", - "m = has_mfs and " + ( + "m = has_mfs and " "sys.modules.setdefault(%(pkg)r, " - "importlib.util.module_from_spec(" - "importlib.machinery.PathFinder.find_spec(%(pkg)r, " - "[os.path.dirname(p)])))", - "m = m or " - "sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))", + "importlib.util.module_from_spec(" + "importlib.machinery.PathFinder.find_spec(%(pkg)r, " + "[os.path.dirname(p)])))" + ), + ( + "m = m or " + "sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))" + ), "mp = (m or []) and m.__dict__.setdefault('__path__',[])", "(p not in mp) and mp.append(p)", ) diff --git a/venv/lib/python3.8/site-packages/setuptools/package_index.py b/venv/lib/python3.8/site-packages/setuptools/package_index.py index 6b06f2c..1702c7c 100644 --- a/venv/lib/python3.8/site-packages/setuptools/package_index.py +++ b/venv/lib/python3.8/site-packages/setuptools/package_index.py @@ -46,16 +46,17 @@ __all__ = [ _SOCKET_TIMEOUT = 15 _tmpl = "setuptools/{setuptools.__version__} Python-urllib/{py_major}" -user_agent = _tmpl.format(py_major=sys.version[:3], setuptools=setuptools) +user_agent = _tmpl.format( + py_major='{}.{}'.format(*sys.version_info), setuptools=setuptools) def parse_requirement_arg(spec): try: return Requirement.parse(spec) - except ValueError: + except ValueError as e: raise DistutilsError( "Not a URL, existing file, or requirement spec: %r" % (spec,) - ) + ) from e def parse_bdist_wininst(name): @@ -348,6 +349,8 @@ class PackageIndex(Environment): f = self.open_url(url, tmpl % url) if f is None: return + if isinstance(f, urllib.error.HTTPError) and f.code == 401: + self.info("Authentication error: %s" % f.msg) self.fetched_urls[f.url] = True if 'html' not in f.headers.get('content-type', '').lower(): f.close() # not html, we can't process it @@ -769,7 +772,7 @@ class PackageIndex(Environment): if warning: self.warn(warning, msg) else: - raise DistutilsError('%s %s' % (url, msg)) + raise DistutilsError('%s %s' % (url, msg)) from v except urllib.error.HTTPError as v: return v except urllib.error.URLError as v: @@ -777,7 +780,7 @@ class PackageIndex(Environment): self.warn(warning, v.reason) else: raise DistutilsError("Download error for %s: %s" - % (url, v.reason)) + % (url, v.reason)) from v except http_client.BadStatusLine as v: if warning: self.warn(warning, v.line) @@ -786,13 +789,13 @@ class PackageIndex(Environment): '%s returned a bad status line. The server might be ' 'down, %s' % (url, v.line) - ) + ) from v except (http_client.HTTPException, socket.error) as v: if warning: self.warn(warning, v) else: raise DistutilsError("Download error for %s: %s" - % (url, v)) + % (url, v)) from v def _download_url(self, scheme, url, tmpdir): # Determine download filename @@ -1050,7 +1053,7 @@ def open_with_auth(url, opener=urllib.request.urlopen): parsed = urllib.parse.urlparse(url) scheme, netloc, path, params, query, frag = parsed - # Double scheme does not raise on Mac OS X as revealed by a + # Double scheme does not raise on macOS as revealed by a # failing test. We would expect "nonnumeric port". Refs #20. if netloc.endswith(':'): raise http_client.InvalidURL("nonnumeric port: ''") @@ -1092,7 +1095,8 @@ def open_with_auth(url, opener=urllib.request.urlopen): # copy of urllib.parse._splituser from Python 3.8 def _splituser(host): - """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" + """splituser('user[:passwd]@host[:port]') + --> 'user[:passwd]', 'host[:port]'.""" user, delim, host = host.rpartition('@') return (user if delim else None), host diff --git a/venv/lib/python3.8/site-packages/setuptools/pep425tags.py b/venv/lib/python3.8/site-packages/setuptools/pep425tags.py deleted file mode 100644 index 48745a2..0000000 --- a/venv/lib/python3.8/site-packages/setuptools/pep425tags.py +++ /dev/null @@ -1,319 +0,0 @@ -# This file originally from pip: -# https://github.com/pypa/pip/blob/8f4f15a5a95d7d5b511ceaee9ed261176c181970/src/pip/_internal/pep425tags.py -"""Generate and work with PEP 425 Compatibility Tags.""" -from __future__ import absolute_import - -import distutils.util -from distutils import log -import platform -import re -import sys -import sysconfig -import warnings -from collections import OrderedDict - -from .extern import six - -from . import glibc - -_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') - - -def get_config_var(var): - try: - return sysconfig.get_config_var(var) - except IOError as e: # Issue #1074 - warnings.warn("{}".format(e), RuntimeWarning) - return None - - -def get_abbr_impl(): - """Return abbreviated implementation name.""" - if hasattr(sys, 'pypy_version_info'): - pyimpl = 'pp' - elif sys.platform.startswith('java'): - pyimpl = 'jy' - elif sys.platform == 'cli': - pyimpl = 'ip' - else: - pyimpl = 'cp' - return pyimpl - - -def get_impl_ver(): - """Return implementation version.""" - impl_ver = get_config_var("py_version_nodot") - if not impl_ver or get_abbr_impl() == 'pp': - impl_ver = ''.join(map(str, get_impl_version_info())) - return impl_ver - - -def get_impl_version_info(): - """Return sys.version_info-like tuple for use in decrementing the minor - version.""" - if get_abbr_impl() == 'pp': - # as per https://github.com/pypa/pip/issues/2882 - return (sys.version_info[0], sys.pypy_version_info.major, - sys.pypy_version_info.minor) - else: - return sys.version_info[0], sys.version_info[1] - - -def get_impl_tag(): - """ - Returns the Tag for this specific implementation. - """ - return "{}{}".format(get_abbr_impl(), get_impl_ver()) - - -def get_flag(var, fallback, expected=True, warn=True): - """Use a fallback method for determining SOABI flags if the needed config - var is unset or unavailable.""" - val = get_config_var(var) - if val is None: - if warn: - log.debug("Config variable '%s' is unset, Python ABI tag may " - "be incorrect", var) - 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 = get_abbr_impl() - if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'): - d = '' - m = '' - u = '' - if get_flag('Py_DEBUG', - lambda: hasattr(sys, 'gettotalrefcount'), - warn=(impl == 'cp')): - d = 'd' - if get_flag('WITH_PYMALLOC', - lambda: impl == 'cp', - warn=(impl == 'cp')): - m = 'm' - if get_flag('Py_UNICODE_SIZE', - lambda: sys.maxunicode == 0x10ffff, - expected=4, - warn=(impl == 'cp' and - six.PY2)) \ - and six.PY2: - u = 'u' - abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u) - elif soabi and soabi.startswith('cpython-'): - abi = 'cp' + soabi.split('-')[1] - elif soabi: - abi = soabi.replace('.', '_').replace('-', '_') - else: - abi = None - return abi - - -def _is_running_32bit(): - return sys.maxsize == 2147483647 - - -def get_platform(): - """Return our platform name 'win32', 'linux_x86_64'""" - if sys.platform == 'darwin': - # distutils.util.get_platform() returns the release based on the value - # of MACOSX_DEPLOYMENT_TARGET on which Python was built, which may - # be significantly older than the user's current machine. - release, _, machine = platform.mac_ver() - split_ver = release.split('.') - - if machine == "x86_64" and _is_running_32bit(): - machine = "i386" - elif machine == "ppc64" and _is_running_32bit(): - machine = "ppc" - - return 'macosx_{}_{}_{}'.format(split_ver[0], split_ver[1], machine) - - # XXX remove distutils dependency - result = distutils.util.get_platform().replace('.', '_').replace('-', '_') - if result == "linux_x86_64" and _is_running_32bit(): - # 32 bit Python program (running on a 64 bit Linux): pip should only - # install and run 32 bit compiled extensions in that case. - result = "linux_i686" - - return result - - -def is_manylinux1_compatible(): - # Only Linux, and only x86-64 / i686 - if get_platform() not in {"linux_x86_64", "linux_i686"}: - return False - - # Check for presence of _manylinux module - try: - import _manylinux - return bool(_manylinux.manylinux1_compatible) - except (ImportError, AttributeError): - # Fall through to heuristic check below - pass - - # Check glibc version. CentOS 5 uses glibc 2.5. - return glibc.have_compatible_glibc(2, 5) - - -def get_darwin_arches(major, minor, machine): - """Return a list of supported arches (including group arches) for - the given major, minor and machine architecture of a macOS machine. - """ - arches = [] - - def _supports_arch(major, minor, arch): - # Looking at the application support for macOS versions in the chart - # provided by https://en.wikipedia.org/wiki/OS_X#Versions it appears - # our timeline looks roughly like: - # - # 10.0 - Introduces ppc support. - # 10.4 - Introduces ppc64, i386, and x86_64 support, however the ppc64 - # and x86_64 support is CLI only, and cannot be used for GUI - # applications. - # 10.5 - Extends ppc64 and x86_64 support to cover GUI applications. - # 10.6 - Drops support for ppc64 - # 10.7 - Drops support for ppc - # - # Given that we do not know if we're installing a CLI or a GUI - # application, we must be conservative and assume it might be a GUI - # application and behave as if ppc64 and x86_64 support did not occur - # until 10.5. - # - # Note: The above information is taken from the "Application support" - # column in the chart not the "Processor support" since I believe - # that we care about what instruction sets an application can use - # not which processors the OS supports. - if arch == 'ppc': - return (major, minor) <= (10, 5) - if arch == 'ppc64': - return (major, minor) == (10, 5) - if arch == 'i386': - return (major, minor) >= (10, 4) - if arch == 'x86_64': - return (major, minor) >= (10, 5) - if arch in groups: - for garch in groups[arch]: - if _supports_arch(major, minor, garch): - return True - return False - - groups = OrderedDict([ - ("fat", ("i386", "ppc")), - ("intel", ("x86_64", "i386")), - ("fat64", ("x86_64", "ppc64")), - ("fat32", ("x86_64", "i386", "ppc")), - ]) - - if _supports_arch(major, minor, machine): - arches.append(machine) - - for garch in groups: - if machine in groups[garch] and _supports_arch(major, minor, garch): - arches.append(garch) - - arches.append('universal') - - return arches - - -def get_supported(versions=None, noarch=False, platform=None, - impl=None, abi=None): - """Return a list of supported tags for each version specified in - `versions`. - - :param versions: a list of string versions, of the form ["33", "32"], - or None. The first version will be assumed to support our ABI. - :param platform: specify the exact platform you want valid - tags for, or None. If None, use the local system platform. - :param impl: specify the exact implementation you want valid - tags for, or None. If None, use the local interpreter impl. - :param abi: specify the exact abi you want valid - tags for, or None. If None, use the local interpreter abi. - """ - supported = [] - - # Versions must be given with respect to the preference - if versions is None: - versions = [] - version_info = get_impl_version_info() - major = version_info[:-1] - # Support all previous minor Python versions. - for minor in range(version_info[-1], -1, -1): - versions.append(''.join(map(str, major + (minor,)))) - - impl = impl or get_abbr_impl() - - abis = [] - - abi = abi or get_abi_tag() - if abi: - abis[0:0] = [abi] - - abi3s = set() - import imp - for suffix in imp.get_suffixes(): - if suffix[0].startswith('.abi'): - abi3s.add(suffix[0].split('.', 2)[1]) - - abis.extend(sorted(list(abi3s))) - - abis.append('none') - - if not noarch: - arch = platform or get_platform() - if arch.startswith('macosx'): - # support macosx-10.6-intel on macosx-10.9-x86_64 - match = _osx_arch_pat.match(arch) - if match: - name, major, minor, actual_arch = match.groups() - tpl = '{}_{}_%i_%s'.format(name, major) - arches = [] - for m in reversed(range(int(minor) + 1)): - for a in get_darwin_arches(int(major), m, actual_arch): - arches.append(tpl % (m, a)) - else: - # arch pattern didn't match (?!) - arches = [arch] - elif platform is None and is_manylinux1_compatible(): - arches = [arch.replace('linux', 'manylinux1'), arch] - else: - arches = [arch] - - # Current version, current API (built specifically for our Python): - for abi in abis: - for arch in arches: - supported.append(('%s%s' % (impl, versions[0]), abi, arch)) - - # abi3 modules compatible with older version of Python - for version in versions[1:]: - # abi3 was introduced in Python 3.2 - if version in {'31', '30'}: - break - for abi in abi3s: # empty set if not Python 3 - for arch in arches: - supported.append(("%s%s" % (impl, version), abi, arch)) - - # Has binaries, does not use the Python API: - for arch in arches: - supported.append(('py%s' % (versions[0][0]), 'none', arch)) - - # No abi / arch, but requires our implementation: - supported.append(('%s%s' % (impl, versions[0]), 'none', 'any')) - # Tagged specifically as being cross-version compatible - # (with just the major version specified) - supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any')) - - # No abi / arch, generic Python - for i, version in enumerate(versions): - supported.append(('py%s' % (version,), 'none', 'any')) - if i == 0: - supported.append(('py%s' % (version[0]), 'none', 'any')) - - return supported - - -implementation_tag = get_impl_tag() diff --git a/venv/lib/python3.8/site-packages/setuptools/py27compat.py b/venv/lib/python3.8/site-packages/setuptools/py27compat.py index 2985011..ba39af5 100644 --- a/venv/lib/python3.8/site-packages/setuptools/py27compat.py +++ b/venv/lib/python3.8/site-packages/setuptools/py27compat.py @@ -2,6 +2,7 @@ Compatibility Support for Python 2.7 and earlier """ +import sys import platform from setuptools.extern import six @@ -15,7 +16,7 @@ def get_all_headers(message, key): if six.PY2: - def get_all_headers(message, key): + def get_all_headers(message, key): # noqa return message.getheaders(key) @@ -26,3 +27,34 @@ linux_py2_ascii = ( rmtree_safe = str if linux_py2_ascii else lambda x: x """Workaround for http://bugs.python.org/issue24672""" + + +try: + from ._imp import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE + from ._imp import get_frozen_object, get_module +except ImportError: + import imp + from imp import PY_COMPILED, PY_FROZEN, PY_SOURCE # noqa + + def find_module(module, paths=None): + """Just like 'imp.find_module()', but with package support""" + parts = module.split('.') + while parts: + part = parts.pop(0) + f, path, (suffix, mode, kind) = info = imp.find_module(part, paths) + + if kind == imp.PKG_DIRECTORY: + parts = parts or ['__init__'] + paths = [path] + + elif parts: + raise ImportError("Can't find %r in %s" % (parts, module)) + + return info + + def get_frozen_object(module, paths): + return imp.get_frozen_object(module) + + def get_module(module, paths, info): + imp.load_module(module, *info) + return sys.modules[module] diff --git a/venv/lib/python3.8/site-packages/setuptools/sandbox.py b/venv/lib/python3.8/site-packages/setuptools/sandbox.py index 685f3f7..93ae8eb 100644 --- a/venv/lib/python3.8/site-packages/setuptools/sandbox.py +++ b/venv/lib/python3.8/site-packages/setuptools/sandbox.py @@ -12,7 +12,9 @@ import textwrap from setuptools.extern import six from setuptools.extern.six.moves import builtins, map -import pkg_resources.py31compat +import pkg_resources +from distutils.errors import DistutilsError +from pkg_resources import working_set if sys.platform.startswith('java'): import org.python.modules.posix.PosixModule as _os @@ -23,8 +25,6 @@ try: except NameError: _file = None _open = open -from distutils.errors import DistutilsError -from pkg_resources import working_set __all__ = [ @@ -70,7 +70,7 @@ def override_temp(replacement): """ Monkey-patch tempfile.tempdir with replacement, ensuring it exists """ - pkg_resources.py31compat.makedirs(replacement, exist_ok=True) + os.makedirs(replacement, exist_ok=True) saved = tempfile.tempdir @@ -374,7 +374,7 @@ class AbstractSandbox: if hasattr(os, 'devnull'): - _EXCEPTIONS = [os.devnull,] + _EXCEPTIONS = [os.devnull] else: _EXCEPTIONS = [] @@ -466,7 +466,8 @@ class DirectorySandbox(AbstractSandbox): WRITE_FLAGS = functools.reduce( - operator.or_, [getattr(_os, a, 0) for a in + operator.or_, [ + getattr(_os, a, 0) for a in "O_WRONLY O_RDWR O_APPEND O_CREAT O_TRUNC O_TEMPORARY".split()] ) diff --git a/venv/lib/python3.8/site-packages/setuptools/site-patch.py b/venv/lib/python3.8/site-packages/setuptools/site-patch.py deleted file mode 100644 index 40b00de..0000000 --- a/venv/lib/python3.8/site-packages/setuptools/site-patch.py +++ /dev/null @@ -1,74 +0,0 @@ -def __boot(): - import sys - import os - PYTHONPATH = os.environ.get('PYTHONPATH') - if PYTHONPATH is None or (sys.platform == 'win32' and not PYTHONPATH): - PYTHONPATH = [] - else: - PYTHONPATH = PYTHONPATH.split(os.pathsep) - - pic = getattr(sys, 'path_importer_cache', {}) - stdpath = sys.path[len(PYTHONPATH):] - mydir = os.path.dirname(__file__) - - for item in stdpath: - if item == mydir or not item: - continue # skip if current dir. on Windows, or my own directory - importer = pic.get(item) - if importer is not None: - loader = importer.find_module('site') - if loader is not None: - # This should actually reload the current module - loader.load_module('site') - break - else: - try: - import imp # Avoid import loop in Python 3 - stream, path, descr = imp.find_module('site', [item]) - except ImportError: - continue - if stream is None: - continue - try: - # This should actually reload the current module - imp.load_module('site', stream, path, descr) - finally: - stream.close() - break - else: - raise ImportError("Couldn't find the real 'site' module") - - known_paths = dict([(makepath(item)[1], 1) for item in sys.path]) # 2.2 comp - - oldpos = getattr(sys, '__egginsert', 0) # save old insertion position - sys.__egginsert = 0 # and reset the current one - - for item in PYTHONPATH: - addsitedir(item) - - sys.__egginsert += oldpos # restore effective old position - - d, nd = makepath(stdpath[0]) - insert_at = None - new_path = [] - - for item in sys.path: - p, np = makepath(item) - - if np == nd and insert_at is None: - # We've hit the first 'system' path entry, so added entries go here - insert_at = len(new_path) - - if np in known_paths or insert_at is None: - new_path.append(item) - else: - # new path after the insert point, back-insert it - new_path.insert(insert_at, item) - insert_at += 1 - - sys.path[:] = new_path - - -if __name__ == 'site': - __boot() - del __boot diff --git a/venv/lib/python3.8/site-packages/setuptools/ssl_support.py b/venv/lib/python3.8/site-packages/setuptools/ssl_support.py index 226db69..17c14c4 100644 --- a/venv/lib/python3.8/site-packages/setuptools/ssl_support.py +++ b/venv/lib/python3.8/site-packages/setuptools/ssl_support.py @@ -35,7 +35,8 @@ try: except AttributeError: HTTPSHandler = HTTPSConnection = object -is_available = ssl is not None and object not in (HTTPSHandler, HTTPSConnection) +is_available = ssl is not None and object not in ( + HTTPSHandler, HTTPSConnection) try: @@ -85,8 +86,10 @@ if not match_hostname: return dn.lower() == hostname.lower() # RFC 6125, section 6.4.3, subitem 1. - # The client SHOULD NOT attempt to match a presented identifier in which - # the wildcard character comprises a label other than the left-most label. + # The client SHOULD NOT attempt to match a + # presented identifier in which the wildcard + # character comprises a label other than the + # left-most label. if leftmost == '*': # When '*' is a fragment by itself, it matches a non-empty dotless # fragment. @@ -137,15 +140,16 @@ if not match_hostname: return dnsnames.append(value) if len(dnsnames) > 1: - raise CertificateError("hostname %r " - "doesn't match either of %s" + raise CertificateError( + "hostname %r doesn't match either of %s" % (hostname, ', '.join(map(repr, dnsnames)))) elif len(dnsnames) == 1: - raise CertificateError("hostname %r " - "doesn't match %r" + raise CertificateError( + "hostname %r doesn't match %r" % (hostname, dnsnames[0])) else: - raise CertificateError("no appropriate commonName or " + raise CertificateError( + "no appropriate commonName or " "subjectAltName fields were found") @@ -158,7 +162,8 @@ class VerifyingHTTPSHandler(HTTPSHandler): def https_open(self, req): return self.do_open( - lambda host, **kw: VerifyingHTTPSConn(host, self.ca_bundle, **kw), req + lambda host, **kw: VerifyingHTTPSConn(host, self.ca_bundle, **kw), + req ) diff --git a/venv/lib/python3.8/site-packages/setuptools/wheel.py b/venv/lib/python3.8/site-packages/setuptools/wheel.py index e11f0a1..ca09bd1 100644 --- a/venv/lib/python3.8/site-packages/setuptools/wheel.py +++ b/venv/lib/python3.8/site-packages/setuptools/wheel.py @@ -1,6 +1,7 @@ """Wheels support.""" from distutils.util import get_platform +from distutils import log import email import itertools import os @@ -11,9 +12,9 @@ import zipfile import pkg_resources import setuptools from pkg_resources import parse_version +from setuptools.extern.packaging.tags import sys_tags from setuptools.extern.packaging.utils import canonicalize_name from setuptools.extern.six import PY3 -from setuptools import pep425tags from setuptools.command.egg_info import write_requirements @@ -26,12 +27,8 @@ WHEEL_NAME = re.compile( )\.whl$""", re.VERBOSE).match -NAMESPACE_PACKAGE_INIT = '''\ -try: - __import__('pkg_resources').declare_namespace(__name__) -except ImportError: - __path__ = __import__('pkgutil').extend_path(__path__, __name__) -''' +NAMESPACE_PACKAGE_INIT = \ + "__import__('pkg_resources').declare_namespace(__name__)\n" def unpack(src_dir, dst_dir): @@ -76,7 +73,8 @@ class Wheel: def is_compatible(self): '''Is the wheel is compatible with the current platform?''' - supported_tags = pep425tags.get_supported() + supported_tags = set( + (t.interpreter, t.abi, t.platform) for t in sys_tags()) return next((True for t in self.tags() if t in supported_tags), False) def egg_name(self): @@ -162,11 +160,17 @@ class Wheel: extras_require=extras_require, ), ) - write_requirements( - setup_dist.get_command_obj('egg_info'), - None, - os.path.join(egg_info, 'requires.txt'), - ) + # Temporarily disable info traces. + log_threshold = log._global_log.threshold + log.set_threshold(log.WARN) + try: + write_requirements( + setup_dist.get_command_obj('egg_info'), + None, + os.path.join(egg_info, 'requires.txt'), + ) + finally: + log.set_threshold(log_threshold) @staticmethod def _move_data_entries(destination_eggdir, dist_data): @@ -206,6 +210,8 @@ class Wheel: for mod in namespace_packages: mod_dir = os.path.join(destination_eggdir, *mod.split('.')) mod_init = os.path.join(mod_dir, '__init__.py') - if os.path.exists(mod_dir) and not os.path.exists(mod_init): + if not os.path.exists(mod_dir): + os.mkdir(mod_dir) + if not os.path.exists(mod_init): with open(mod_init, 'w') as fp: fp.write(NAMESPACE_PACKAGE_INIT) diff --git a/venv/pyvenv.cfg b/venv/pyvenv.cfg index 4118bb9..5d5aef2 100644 --- a/venv/pyvenv.cfg +++ b/venv/pyvenv.cfg @@ -1,3 +1,3 @@ home = /usr/bin include-system-site-packages = false -version = 3.8.2 +version = 3.8.6 diff --git a/www/about.html b/www/about.html index 5250c17..cddc1b6 100644 --- a/www/about.html +++ b/www/about.html @@ -35,7 +35,7 @@ las redes sociales como ya lo hice con Facebook.</p> }); } - window.addEventListener('DOMContentLoaded', (event) => { + window.addEventListener('load', (event) => { makeImagesClickeable(); }); </script> diff --git a/www/assets/style.css b/www/assets/style.css index 47c4966..519372f 100644 --- a/www/assets/style.css +++ b/www/assets/style.css @@ -1,55 +1,3 @@ -/****************************************************************************** - => Fonts -*******************************************************************************/ - -/****************************************************************************** - => Source Code Pro -*******************************************************************************/ -@font-face { - font-family: 'Source Code Pro'; - font-style: normal; - font-weight: 400; - src: local('Source Code Pro'), url('https://static.danielcortes.xyz/fonts/SourceCodePro/SourceCodePro-Regular.ttf') format('truetype'); -} - -@font-face { - font-family: 'Source Code Pro'; - font-style: normal; - font-weight: 700; - src: local('Source Code Pro'), url('https://static.danielcortes.xyz/fonts/SourceCodePro/SourceCodePro-Bold.ttf') format('truetype'); -} - -/****************************************************************************** - => Source Serif Pro -*******************************************************************************/ -@font-face { - font-family: 'Source Serif Pro'; - font-style: normal; - font-weight: 400; - src: local('Source Serif Pro'), url('https://static.danielcortes.xyz/fonts/SourceSerifPro/SourceSerifPro-Regular.ttf') format('truetype'); -} -@font-face { - font-family: 'Source Serif Pro'; - font-style: normal; - font-weight: 700; - src: local('Source Serif Pro'), url('https://static.danielcortes.xyz/fonts/SourceSerifPro/SourceSerifPro-Bold.ttf') format('truetype'); -} - -/****************************************************************************** - => Source Sans Pro -*******************************************************************************/ -@font-face { - font-family: 'Source Sans Pro'; - font-style: normal; - font-weight: 400; - src: local('Source Sans Pro'), url('https://static.danielcortes.xyz/fonts/SourceSansPro/SourceSansPro-Regular.ttf') format('truetype'); -} -@font-face { - font-family: 'Source Sans Pro'; - font-style: normal; - font-weight: 700; - src: local('Source Sans Pro'), url('https://static.danielcortes.xyz/fonts/SourceSansPro/SourceSansPro-Bold.ttf') format('truetype'); -} .codehilite .hll { background-color: #f1fa8c } .codehilite { background: #282a36; color: #f8f8f2 } .codehilite .c { color: #6272a4 } /* Comment */ @@ -127,6 +75,79 @@ .codehilite .vi { color: #8be9fd; font-style: italic } /* Name.Variable.Instance */ .codehilite .vm { color: #8be9fd; font-style: italic } /* Name.Variable.Magic */ .codehilite .il { color: #bd93f9 } /* Literal.Number.Integer.Long */ +:root{ + --background-color: hsl(10, 20%, 98%); + --foreground-color: hsl(10, 10%, 13%); + --primary-color: hsl(200, 90%, 40%); + --highlight-color: hsl(290, 86%, 43%); + --light-color: hsl(10, 10%, 40%); +} + +body { + background-color: var(--background-color); + color: var(--foreground-color); + overflow-y: scroll; + + font-family: 'Source Sans Pro', sans-serif; + font-size: 1.5em; +} + +@media only screen and (max-width: 800px) { + body { + font-size: 1em; + } +} + +.container { + max-width: 80ch; + padding: 2ch; + padding-bottom: 5em; + margin: auto; +} + +h1 { + margin: 1em 0; +} + +time { + color: var(--light-color); +} + +p { + line-height: 1.5em; + text-align: justify; +} + +a, a:visited { + color: var(--highlight-color); + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + + +img { + max-width: 100%; + cursor: pointer; +} + +code { + font-size: 1.2em; +} + +.codehilite { + font-family: 'Source Code Pro', monospace; + font-size: 1.2em; + border: none; + border-radius: 5px; + overflow-x: auto; +} + +.codehilite pre { + margin: 1em; +} /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ /* Document @@ -476,96 +497,62 @@ template { [hidden] { display: none; } -:root{ - --background-color: hsl(10, 20%, 98%); - --foreground-color: hsl(10, 10%, 13%); - --primary-color: hsl(200, 90%, 40%); - --highlight-color: hsl(290, 86%, 43%); - --light-color: hsl(10, 10%, 40%); -} - -body { - background-color: var(--background-color); - color: var(--foreground-color); - overflow-y: scroll; - - font-family: 'Source Sans Pro', sans-serif; - font-size: 1.5em; -} - -@media only screen and (max-width: 800px) { - body { - font-size: 1em; - } -} - -.container { - max-width: 80ch; - padding: 2ch; - padding-bottom: 5em; - margin: auto; -} - -h1 { - margin: 1em 0; -} - -time { - color: var(--light-color); -} - -p { - line-height: 1.5em; - text-align: justify; -} - -a, a:visited { - color: var(--highlight-color); - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - - -img { - max-width: 100%; - cursor: pointer; -} - -code { - font-size: 1.2em; -} - -.codehilite { - font-family: 'Source Code Pro', monospace; - font-size: 1.2em; - border: none; - border-radius: 5px; - overflow-x: auto; -} - -.codehilite pre { - margin: 1em; -} /****************************************************************************** - => FONTS + => Fonts *******************************************************************************/ -@font-face{font-family:'Source Code Pro';font-style:normal;font-weight:400;src:local('Source Code Pro'),url(https://static.danielcortes.xyz/fonts/SourceCodePro/SourceCodePro-Regular.woff2) format('woff2');font-display:swap} -@font-face{font-family:'Source Code Pro';font-style:normal;font-weight:700;src:local('Source Code Pro'),url(https://static.danielcortes.xyz/fonts/SourceCodePro/SourceCodePro-Bold.woff2) format('woff2');font-display:swap} -@font-face{font-family:'Source Serif Pro';font-style:normal;font-weight:400;src:local('Source Serif Pro'),url(https://static.danielcortes.xyz/fonts/SourceSerifPro/SourceSerifPro-Regular.woff2) format('woff2')} -@font-face{font-family:'Source Serif Pro';font-style:normal;font-weight:700;src:local('Source Serif Pro'),url(https://static.danielcortes.xyz/fonts/SourceSerifPro/SourceSerifPro-Bold.woff2) format('woff2');font-display:swap} -@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:400;src:local('Source Sans Pro'),url(https://static.danielcortes.xyz/fonts/SourceSansPro/SourceSansPro-Regular.woff2) format('woff2');font-display:swap} -@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:700;src:local('Source Sans Pro'),url(https://static.danielcortes.xyz/fonts/SourceSansPro/SourceSansPro-Bold.woff2) format('woff2');font-display:swap} + +/****************************************************************************** + => Source Code Pro +*******************************************************************************/ +@font-face { + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Code Pro'), url('https://static.danielcortes.xyz/fonts/SourceCodePro/SourceCodePro-Regular.ttf') format('truetype'); +} + +@font-face { + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Code Pro'), url('https://static.danielcortes.xyz/fonts/SourceCodePro/SourceCodePro-Bold.ttf') format('truetype'); +} + +/****************************************************************************** + => Source Serif Pro +*******************************************************************************/ +@font-face { + font-family: 'Source Serif Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Serif Pro'), url('https://static.danielcortes.xyz/fonts/SourceSerifPro/SourceSerifPro-Regular.ttf') format('truetype'); +} +@font-face { + font-family: 'Source Serif Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Serif Pro'), url('https://static.danielcortes.xyz/fonts/SourceSerifPro/SourceSerifPro-Bold.ttf') format('truetype'); +} + +/****************************************************************************** + => Source Sans Pro +*******************************************************************************/ +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 400; + src: local('Source Sans Pro'), url('https://static.danielcortes.xyz/fonts/SourceSansPro/SourceSansPro-Regular.ttf') format('truetype'); +} +@font-face { + font-family: 'Source Sans Pro'; + font-style: normal; + font-weight: 700; + src: local('Source Sans Pro'), url('https://static.danielcortes.xyz/fonts/SourceSansPro/SourceSansPro-Bold.ttf') format('truetype'); +} /****************************************************************************** => CODEHILITE *******************************************************************************/ .codehilite .hll{background-color:#f1fa8c}.codehilite{background:#282a36;color:#f8f8f2}.codehilite .c{color:#6272a4}.codehilite .err,.codehilite .g{color:#f8f8f2}.codehilite .k{color:#ff79c6}.codehilite .l,.codehilite .n{color:#f8f8f2}.codehilite .o{color:#ff79c6}.codehilite .p,.codehilite .x{color:#f8f8f2}.codehilite .ch,.codehilite .cm{color:#6272a4}.codehilite .cp{color:#ff79c6}.codehilite .c1,.codehilite .cpf,.codehilite .cs{color:#6272a4}.codehilite .gd{color:#8b080b}.codehilite .ge{color:#f8f8f2;text-decoration:underline}.codehilite .gr{color:#f8f8f2}.codehilite .gh,.codehilite .gi{color:#f8f8f2;font-weight:700}.codehilite .go{color:#44475a}.codehilite .gp,.codehilite .gs,.codehilite .gt{color:#f8f8f2}.codehilite .gu{color:#f8f8f2;font-weight:700}.codehilite .kc{color:#ff79c6}.codehilite .kd{color:#8be9fd;font-style:italic}.codehilite .kn,.codehilite .kp,.codehilite .kr{color:#ff79c6}.codehilite .kt{color:#8be9fd}.codehilite .ld{color:#f8f8f2}.codehilite .m{color:#bd93f9}.codehilite .s{color:#f1fa8c}.codehilite .na{color:#50fa7b}.codehilite .nb{color:#8be9fd;font-style:italic}.codehilite .nc{color:#50fa7b}.codehilite .nd,.codehilite .ne,.codehilite .ni,.codehilite .no{color:#f8f8f2}.codehilite .nf{color:#50fa7b}.codehilite .nl{color:#8be9fd;font-style:italic}.codehilite .nn,.codehilite .nx,.codehilite .py{color:#f8f8f2}.codehilite .nt{color:#ff79c6}.codehilite .nv{color:#8be9fd;font-style:italic}.codehilite .ow{color:#ff79c6}.codehilite .w{color:#f8f8f2}.codehilite .mb,.codehilite .mf,.codehilite .mh,.codehilite .mi,.codehilite .mo{color:#bd93f9}.codehilite .dl,.codehilite .s1,.codehilite .s2,.codehilite .sa,.codehilite .sb,.codehilite .sc,.codehilite .sd,.codehilite .se,.codehilite .sh,.codehilite .si,.codehilite .sr,.codehilite .ss,.codehilite .sx{color:#f1fa8c}.codehilite .bp{color:#f8f8f2;font-style:italic}.codehilite .fm{color:#50fa7b}.codehilite .vc,.codehilite .vg,.codehilite .vi,.codehilite .vm{color:#8be9fd;font-style:italic}.codehilite .il{color:#bd93f9} -/****************************************************************************** - => NORMALIZE.CSS -*******************************************************************************/ -button,hr,input{overflow:visible}progress,sub,sup{vertical-align:baseline}[type=checkbox],[type=radio],legend{box-sizing:border-box;padding:0}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}details,main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{padding:.35em .75em .625em}legend{color:inherit;display:table;max-width:100%;white-space:normal}textarea{overflow:auto}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none} /****************************************************************************** => MAIN STYLES *******************************************************************************/ @@ -641,3 +628,16 @@ code { .codehilite pre { margin: 1em; } +/****************************************************************************** + => NORMALIZE.CSS +*******************************************************************************/ +button,hr,input{overflow:visible}progress,sub,sup{vertical-align:baseline}[type=checkbox],[type=radio],legend{box-sizing:border-box;padding:0}html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}details,main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{padding:.35em .75em .625em}legend{color:inherit;display:table;max-width:100%;white-space:normal}textarea{overflow:auto}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none} +/****************************************************************************** + => FONTS +*******************************************************************************/ +@font-face{font-family:'Source Code Pro';font-style:normal;font-weight:400;src:local('Source Code Pro'),url(https://static.danielcortes.xyz/fonts/SourceCodePro/SourceCodePro-Regular.woff2) format('woff2');font-display:swap} +@font-face{font-family:'Source Code Pro';font-style:normal;font-weight:700;src:local('Source Code Pro'),url(https://static.danielcortes.xyz/fonts/SourceCodePro/SourceCodePro-Bold.woff2) format('woff2');font-display:swap} +@font-face{font-family:'Source Serif Pro';font-style:normal;font-weight:400;src:local('Source Serif Pro'),url(https://static.danielcortes.xyz/fonts/SourceSerifPro/SourceSerifPro-Regular.woff2) format('woff2')} +@font-face{font-family:'Source Serif Pro';font-style:normal;font-weight:700;src:local('Source Serif Pro'),url(https://static.danielcortes.xyz/fonts/SourceSerifPro/SourceSerifPro-Bold.woff2) format('woff2');font-display:swap} +@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:400;src:local('Source Sans Pro'),url(https://static.danielcortes.xyz/fonts/SourceSansPro/SourceSansPro-Regular.woff2) format('woff2');font-display:swap} +@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:700;src:local('Source Sans Pro'),url(https://static.danielcortes.xyz/fonts/SourceSansPro/SourceSansPro-Bold.woff2) format('woff2');font-display:swap} diff --git a/www/blog/contar_con_hashmaps_java.html b/www/blog/contar_con_hashmaps_java.html index 400b262..b14d00a 100644 --- a/www/blog/contar_con_hashmaps_java.html +++ b/www/blog/contar_con_hashmaps_java.html @@ -18,37 +18,37 @@ ocurrencias, o tal vez necesitas contar los largos de una lista de palabras, etc (ahora no se me ocurren mas).</p> <p>Previo a Java 8, la única forma (que a mi se me ocurra al menos) de hacer esto era así: </p> -<pre class="codehilite"><code class="language-java">String[] things = { - "ball", "celery", "hand", "celery", - "mind", "ball", "fresh", "hand", "ball", - "fresh", "fresh" -}; +<div class="codehilite"><pre><span></span><code><span class="n">String</span><span class="o">[]</span> <span class="n">things</span> <span class="o">=</span> <span class="p">{</span> + <span class="s">"ball"</span><span class="p">,</span> <span class="s">"celery"</span><span class="p">,</span> <span class="s">"hand"</span><span class="p">,</span> <span class="s">"celery"</span><span class="p">,</span> + <span class="s">"mind"</span><span class="p">,</span> <span class="s">"ball"</span><span class="p">,</span> <span class="s">"fresh"</span><span class="p">,</span> <span class="s">"hand"</span><span class="p">,</span> <span class="s">"ball"</span><span class="p">,</span> + <span class="s">"fresh"</span><span class="p">,</span> <span class="s">"fresh"</span> +<span class="p">};</span> -Map<String, Integer> oldWay = new HashMap<>(); +<span class="n">Map</span><span class="o"><</span><span class="n">String</span><span class="p">,</span> <span class="n">Integer</span><span class="o">></span> <span class="n">oldWay</span> <span class="o">=</span> <span class="k">new</span> <span class="n">HashMap</span><span class="o"><></span><span class="p">();</span> -for (String thing : things) { - if (oldWay.containsKey(thing)) { - oldWay.put(thing, oldWay.get(thing) + 1); - } else { - oldWay.put(thing, 1); - } -} +<span class="k">for</span> <span class="p">(</span><span class="n">String</span> <span class="n">thing</span> <span class="p">:</span> <span class="n">things</span><span class="p">)</span> <span class="p">{</span> + <span class="k">if</span> <span class="p">(</span><span class="n">oldWay</span><span class="p">.</span><span class="na">containsKey</span><span class="p">(</span><span class="n">thing</span><span class="p">))</span> <span class="p">{</span> + <span class="n">oldWay</span><span class="p">.</span><span class="na">put</span><span class="p">(</span><span class="n">thing</span><span class="p">,</span> <span class="n">oldWay</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">thing</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> + <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> + <span class="n">oldWay</span><span class="p">.</span><span class="na">put</span><span class="p">(</span><span class="n">thing</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> + <span class="p">}</span> +<span class="p">}</span> -System.out.println("ball => " + oldWay.get("ball")); -System.out.println("celery => " + oldWay.get("celery")); -System.out.println("hand => " + oldWay.get("hand")); -System.out.println("fresh => " + oldWay.get("fresh")); -System.out.println("mind => " + oldWay.get("mind"));</code></pre> - +<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">"ball => "</span> <span class="o">+</span> <span class="n">oldWay</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="s">"ball"</span><span class="p">));</span> +<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">"celery => "</span> <span class="o">+</span> <span class="n">oldWay</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="s">"celery"</span><span class="p">));</span> +<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">"hand => "</span> <span class="o">+</span> <span class="n">oldWay</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="s">"hand"</span><span class="p">));</span> +<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">"fresh => "</span> <span class="o">+</span> <span class="n">oldWay</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="s">"fresh"</span><span class="p">));</span> +<span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">"mind => "</span> <span class="o">+</span> <span class="n">oldWay</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="s">"mind"</span><span class="p">));</span> +</code></pre></div> <p>Lo cual resulta en:</p> -<pre class="codehilite"><code class="language-md">ball => 3 +<div class="codehilite"><pre><span></span><code>ball => 3 celery => 2 hand => 2 fresh => 3 -mind => 1</code></pre> - +mind => 1 +</code></pre></div> <p>Este es el código que utilizaba siempre cuando estaba aprendiendo Java, pero es realmente confuso cuando estas empezando, al menos yo tuve muchos problemas @@ -60,11 +60,11 @@ la key con el valor por default, en este caso 1.</p> actualmente estamos en Java 13 así que no hay escusa, ahora tenemos Lambdas y <code>HashMap</code> recibió nuevas funciones, entre ellas las que se usaran aquí, <code>putIfAbsent()</code> y <code>computeIfPresent()</code>: </p> -<pre class="codehilite"><code class="language-java">for (String thing : things) { - eightWay.putIfAbsent(thing, 0); - eightWay.computeIfPresent(thing, (key, value) -> value + 1); -}</code></pre> - +<div class="codehilite"><pre><span></span><code><span class="k">for</span> <span class="p">(</span><span class="n">String</span> <span class="n">thing</span> <span class="p">:</span> <span class="n">things</span><span class="p">)</span> <span class="p">{</span> + <span class="n">eightWay</span><span class="p">.</span><span class="na">putIfAbsent</span><span class="p">(</span><span class="n">thing</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> + <span class="n">eightWay</span><span class="p">.</span><span class="na">computeIfPresent</span><span class="p">(</span><span class="n">thing</span><span class="p">,</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> <span class="o">-></span> <span class="n">value</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> +<span class="p">}</span> +</code></pre></div> <p><code>pufIfAbsent()</code> agrega una key solamente si no existe previamente y <code>computeIfPresent()</code> calcula el nuevo valor que contendrá la key con el @@ -72,10 +72,10 @@ lambda que se entrega en el segundo argumento, como los 2 serán ejecutados si es que el elemento no existe en el <code>HashMap</code>, se empieza a contar desde 0.</p> <p>Pero tenemos una función que es mas concisa y al menos a mi me agrada mas para solucionar este problema, esta se llama <code>merge()</code>:</p> -<pre class="codehilite"><code class="language-java">for (String thing : things) { - betterWay.merge(thing, 1, (oldValue, newValue) -> oldValue + newValue); -}</code></pre> - +<div class="codehilite"><pre><span></span><code><span class="k">for</span> <span class="p">(</span><span class="n">String</span> <span class="n">thing</span> <span class="p">:</span> <span class="n">things</span><span class="p">)</span> <span class="p">{</span> + <span class="n">betterWay</span><span class="p">.</span><span class="na">merge</span><span class="p">(</span><span class="n">thing</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="n">oldValue</span><span class="p">,</span> <span class="n">newValue</span><span class="p">)</span> <span class="o">-></span> <span class="n">oldValue</span> <span class="o">+</span> <span class="n">newValue</span><span class="p">);</span> +<span class="p">}</span> +</code></pre></div> <p><code>merge()</code> toma por argumentos, la key que se agregara, el valor que se quiere agregar y un lambda que ejecutar si es ya existía la key, en el se podrá @@ -83,10 +83,10 @@ calcular el nuevo valor que en este caso suma el valor antiguo con el valor que se quiere agregar.</p> <p>Incluso esta forma puede quedar aun mas corta si se utiliza una referencia de método, en ingles: method reference, que suena bastante mejor a mi gusto:</p> -<pre class="codehilite"><code class="language-java">for (String thing : things) { - evenBetterWay.merge(thing, 1, Integer::sum); -}</code></pre> - +<div class="codehilite"><pre><span></span><code><span class="k">for</span> <span class="p">(</span><span class="n">String</span> <span class="n">thing</span> <span class="p">:</span> <span class="n">things</span><span class="p">)</span> <span class="p">{</span> + <span class="n">evenBetterWay</span><span class="p">.</span><span class="na">merge</span><span class="p">(</span><span class="n">thing</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">Integer</span><span class="p">::</span><span class="n">sum</span><span class="p">);</span> +<span class="p">}</span> +</code></pre></div> <p>Y esa seria una mejor forma de contar con <code>HashMaps</code>, no es que sea necesariamente mas rápido, de hecho ni siquiera he testeado su velocidad, pero @@ -101,7 +101,7 @@ recordar.</p> }); } - window.addEventListener('DOMContentLoaded', (event) => { + window.addEventListener('load', (event) => { makeImagesClickeable(); }); </script> diff --git a/www/blog/index.html b/www/blog/index.html index 444281e..d23a753 100644 --- a/www/blog/index.html +++ b/www/blog/index.html @@ -24,7 +24,7 @@ }); } - window.addEventListener('DOMContentLoaded', (event) => { + window.addEventListener('load', (event) => { makeImagesClickeable(); }); </script> diff --git a/www/blog/olvido_sobre_git.html b/www/blog/olvido_sobre_git.html index 1da4cbd..d68aa4c 100644 --- a/www/blog/olvido_sobre_git.html +++ b/www/blog/olvido_sobre_git.html @@ -14,32 +14,32 @@ <p><time datetime="2019-10-23">Oct 23, 2019</time></p> <p>Aquí ire dejando multiples comandos de git que he estado buscando muchas veces y siempre vuelvo a olvidar</p> <h3>1 - Sacar archivo o carpeta de la zona de stage</h3> -<pre class="codehilite"><code class="language-bash">git reset HEAD -- <archivo/carpeta></code></pre> - +<div class="codehilite"><pre><span></span><code>git reset HEAD -- <archivo/carpeta> +</code></pre></div> <h3>2 - Deshacer ultimo commit</h3> -<pre class="codehilite"><code class="language-bash">git reset --soft HEAD~1</code></pre> - +<div class="codehilite"><pre><span></span><code>git reset --soft HEAD~1 +</code></pre></div> <h3>3 - Cambiar el nombre de una annotated tag</h3> -<pre class="codehilite"><code class="language-bash">git tag <new> <old> -f -a</code></pre> - +<div class="codehilite"><pre><span></span><code>git tag <new> <old> -f -a +</code></pre></div> <h3>4 - Deshabilitar fast forward por default</h3> -<pre class="codehilite"><code class="language-bash">git config --global merge.ff false</code></pre> - +<div class="codehilite"><pre><span></span><code>git config --global merge.ff <span class="nb">false</span> +</code></pre></div> <h3>5 - Siempre firmar commits</h3> -<pre class="codehilite"><code class="language-bash">git config --global commit.gpgsign true</code></pre> - +<div class="codehilite"><pre><span></span><code>git config --global commit.gpgsign <span class="nb">true</span> +</code></pre></div> <h3>6 - Siempre mostrar diff en commit</h3> -<pre class="codehilite"><code class="language-bash">git config --global commit.verbose true</code></pre> - +<div class="codehilite"><pre><span></span><code>git config --global commit.verbose <span class="nb">true</span> +</code></pre></div> <h3>7 - Push tags</h3> -<pre class="codehilite"><code class="language-bash">git push --tags</code></pre> - +<div class="codehilite"><pre><span></span><code>git push --tags +</code></pre></div> <p>Esta lista ira creciendo a medida que valla necesitando nuevos comandos :3</p> </div> @@ -50,7 +50,7 @@ }); } - window.addEventListener('DOMContentLoaded', (event) => { + window.addEventListener('load', (event) => { makeImagesClickeable(); }); </script> diff --git a/www/blog/olvido_sobre_sql.html b/www/blog/olvido_sobre_sql.html index 8511cbe..855310d 100644 --- a/www/blog/olvido_sobre_sql.html +++ b/www/blog/olvido_sobre_sql.html @@ -18,37 +18,37 @@ hacer un left join, siempre olvido su sintaxis, por eso aquí mantendré una lis de comandos que uso constantemente.</p> <p>Todos los datos son basados en MySQL, que es la base de datos que mas utilizo.</p> <h2>1 - Crear tabla</h2> -<pre class="codehilite"><code class="language-sql">create table usuario -( - id int primary key auto_increment, - nombre varchar(255) not null, - password binary(32) not null, - salt binary(16) not null, - trabajador int not null, - foreign key (trabajador) references trabajador (id), - inserted_at timestamp, - modified_at timestamp, - );</code></pre> - +<div class="codehilite"><pre><span></span><code><span class="k">create</span> <span class="k">table</span> <span class="n">usuario</span> +<span class="p">(</span> + <span class="n">id</span> <span class="nb">int</span> <span class="k">primary</span> <span class="k">key</span> <span class="n">auto_increment</span><span class="p">,</span> + <span class="n">nombre</span> <span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span> <span class="k">not</span> <span class="k">null</span><span class="p">,</span> + <span class="n">password</span> <span class="nb">binary</span><span class="p">(</span><span class="mi">32</span><span class="p">)</span> <span class="k">not</span> <span class="k">null</span><span class="p">,</span> + <span class="n">salt</span> <span class="nb">binary</span><span class="p">(</span><span class="mi">16</span><span class="p">)</span> <span class="k">not</span> <span class="k">null</span><span class="p">,</span> + <span class="n">trabajador</span> <span class="nb">int</span> <span class="k">not</span> <span class="k">null</span><span class="p">,</span> + <span class="k">foreign</span> <span class="k">key</span> <span class="p">(</span><span class="n">trabajador</span><span class="p">)</span> <span class="k">references</span> <span class="n">trabajador</span> <span class="p">(</span><span class="n">id</span><span class="p">),</span> + <span class="n">inserted_at</span> <span class="k">timestamp</span><span class="p">,</span> + <span class="n">modified_at</span> <span class="k">timestamp</span><span class="p">,</span> + <span class="p">);</span> +</code></pre></div> <h2>2 - Como usar on delete y on update</h2> <p>Cuando se crean foreign keys se tiene la opción de agregar on delete y on update constraints, siempre olvido exactamente que significa cada modo de estos constraints así que para ilustrarlos usare el siguiente modelo:</p> -<pre class="codehilite"><code class="language-sql">create table trabajador -( - id int primary, - nombre varchar(255) not null -); - -create table usuario -( - id int primary key, - nombre varchar(255) not null, - trabajador_id int not null, - foreign key (trabajador_id) references trabajador on (id) -);</code></pre> +<div class="codehilite"><pre><span></span><code><span class="k">create</span> <span class="k">table</span> <span class="n">trabajador</span> +<span class="p">(</span> + <span class="n">id</span> <span class="nb">int</span> <span class="k">primary</span><span class="p">,</span> + <span class="n">nombre</span> <span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span> <span class="k">not</span> <span class="k">null</span> +<span class="p">);</span> +<span class="k">create</span> <span class="k">table</span> <span class="n">usuario</span> +<span class="p">(</span> + <span class="n">id</span> <span class="nb">int</span> <span class="k">primary</span> <span class="k">key</span><span class="p">,</span> + <span class="n">nombre</span> <span class="nb">varchar</span><span class="p">(</span><span class="mi">255</span><span class="p">)</span> <span class="k">not</span> <span class="k">null</span><span class="p">,</span> + <span class="n">trabajador_id</span> <span class="nb">int</span> <span class="k">not</span> <span class="k">null</span><span class="p">,</span> + <span class="k">foreign</span> <span class="k">key</span> <span class="p">(</span><span class="n">trabajador_id</span><span class="p">)</span> <span class="k">references</span> <span class="n">trabajador</span> <span class="k">on</span> <span class="p">(</span><span class="n">id</span><span class="p">)</span> +<span class="p">);</span> +</code></pre></div> <h3><code>ON UPDATE</code></h3> <ul> @@ -74,8 +74,9 @@ usuarios que tengan su id asociado.</li> tabla usuarios sera llenadas con nulls.</li> </ul> <h2>3 - Creación de foreign keys fuera del create table</h2> -<pre class="codehilite"><code class="language-sql">alter table usuario add constraint fk_usuario_trabajador -foreign key (trabajador_id) references trabajador (id);</code></pre> +<div class="codehilite"><pre><span></span><code><span class="k">alter</span> <span class="k">table</span> <span class="n">usuario</span> <span class="k">add</span> <span class="k">constraint</span> <span class="n">fk_usuario_trabajador</span> +<span class="k">foreign</span> <span class="k">key</span> <span class="p">(</span><span class="n">trabajador_id</span><span class="p">)</span> <span class="k">references</span> <span class="n">trabajador</span> <span class="p">(</span><span class="n">id</span><span class="p">);</span> +</code></pre></div> </div> <script> function makeImagesClickeable() { @@ -84,7 +85,7 @@ foreign key (trabajador_id) references trabajador (id);</code></pre> }); } - window.addEventListener('DOMContentLoaded', (event) => { + window.addEventListener('load', (event) => { makeImagesClickeable(); }); </script> diff --git a/www/index.html b/www/index.html index dcdd11f..542c3b1 100644 --- a/www/index.html +++ b/www/index.html @@ -27,7 +27,7 @@ }); } - window.addEventListener('DOMContentLoaded', (event) => { + window.addEventListener('load', (event) => { makeImagesClickeable(); }); </script> diff --git a/www/now.html b/www/now.html index 15e2f60..35a687c 100644 --- a/www/now.html +++ b/www/now.html @@ -20,7 +20,7 @@ }); } - window.addEventListener('DOMContentLoaded', (event) => { + window.addEventListener('load', (event) => { makeImagesClickeable(); }); </script> diff --git a/www/projects.html b/www/projects.html index 18d1d52..1d46840 100644 --- a/www/projects.html +++ b/www/projects.html @@ -20,7 +20,7 @@ }); } - window.addEventListener('DOMContentLoaded', (event) => { + window.addEventListener('load', (event) => { makeImagesClickeable(); }); </script> diff --git a/www/random.html b/www/random.html index 8b88842..3f762c6 100644 --- a/www/random.html +++ b/www/random.html @@ -41,7 +41,7 @@ }); } - window.addEventListener('DOMContentLoaded', (event) => { + window.addEventListener('load', (event) => { makeImagesClickeable(); }); </script> diff --git a/www/setup.html b/www/setup.html index e1d37e8..aaa6b18 100644 --- a/www/setup.html +++ b/www/setup.html @@ -16,48 +16,48 @@ <p>Actualmente el setup que estoy usando a cambiado, ya no puedo utilizar un tiling window manager como <code>herbstluftwm</code>, porque estoy obligado a usar VirtualBox para poder correr Microsoft Teams, que es lo que esta utilizando mi universidad para hacer clases y VirtualBox tiene problemas al entrar a modo fullscreen o seamless.</p> <p>Así que bueno, me cambie a <code>cwm</code> el cual es un stacking window manager desarrollado como parte de <code>OpenBSD</code>, usa tan solo un archivo de configuración en el <code>$HOME</code> donde se pueden configurar grupos, los que son equivalente a los típicos workspaces, y cambiar los key bindings para ejecutar programas, mover ventanas en la pantalla y entre grupos, hay solo un par de opciones mas que cambiar en realidad por lo que se siente bastante minimalista comparado con <code>OpenBox</code> por usar XML y tener mil opciones.</p> <p>La configuración que estoy usando para <code>cwm</code> es la siguiente:</p> -<pre class="codehilite"><code class="language-sh">moveamount 10 -gap 25 15 15 15 +<div class="codehilite"><pre><span></span><code>moveamount <span class="m">10</span> +gap <span class="m">25</span> <span class="m">15</span> <span class="m">15</span> <span class="m">15</span> ignore polybar sticky yes -autogroup 1 Firefox -autogroup 8 Spotify -autogroup 9 Thunderbird +autogroup <span class="m">1</span> Firefox +autogroup <span class="m">8</span> Spotify +autogroup <span class="m">9</span> Thunderbird unbind-key all unbind-mouse all bind-key 4S-r restart bind-key 4S-e quit -bind-key 4-d "dmenu_custom -r -e cwm" +bind-key <span class="m">4</span>-d <span class="s2">"dmenu_custom -r -e cwm"</span> bind-key 4C-h window-resize-left bind-key 4C-j window-resize-down bind-key 4C-k window-resize-up bind-key 4C-l window-resize-right -bind-key 4-f window-maximize +bind-key <span class="m">4</span>-f window-maximize bind-key 4S-f window-fullscreen bind-key M-Tab window-cycle-ingroup bind-key 4S-q window-delete -bind-mouse 4-1 window-move -bind-mouse 4-3 window-resize -bind-mouse 4-2 window-stick +bind-mouse <span class="m">4</span>-1 window-move +bind-mouse <span class="m">4</span>-3 window-resize +bind-mouse <span class="m">4</span>-2 window-stick -bind-key 4-1 group-only-1 -bind-key 4-2 group-only-2 -bind-key 4-3 group-only-3 -bind-key 4-4 group-only-4 -bind-key 4-5 group-only-5 -bind-key 4-6 group-only-6 -bind-key 4-7 group-only-7 -bind-key 4-8 group-only-8 -bind-key 4-9 group-only-9 +bind-key <span class="m">4</span>-1 group-only-1 +bind-key <span class="m">4</span>-2 group-only-2 +bind-key <span class="m">4</span>-3 group-only-3 +bind-key <span class="m">4</span>-4 group-only-4 +bind-key <span class="m">4</span>-5 group-only-5 +bind-key <span class="m">4</span>-6 group-only-6 +bind-key <span class="m">4</span>-7 group-only-7 +bind-key <span class="m">4</span>-8 group-only-8 +bind-key <span class="m">4</span>-9 group-only-9 bind-key 4S-1 window-movetogroup-1 bind-key 4S-2 window-movetogroup-2 @@ -69,73 +69,73 @@ bind-key 4S-7 window-movetogroup-7 bind-key 4S-8 window-movetogroup-8 bind-key 4S-9 window-movetogroup-9 -bind-key 4S-h "tile l" -bind-key 4S-j "tile b" -bind-key 4S-k "tile t" -bind-key 4S-l "tile r" - -bind-key 4-h "move l" -bind-key 4-j "move b" -bind-key 4-k "move t" -bind-key 4-l "move r"</code></pre> +bind-key 4S-h <span class="s2">"tile l"</span> +bind-key 4S-j <span class="s2">"tile b"</span> +bind-key 4S-k <span class="s2">"tile t"</span> +bind-key 4S-l <span class="s2">"tile r"</span> +bind-key <span class="m">4</span>-h <span class="s2">"move l"</span> +bind-key <span class="m">4</span>-j <span class="s2">"move b"</span> +bind-key <span class="m">4</span>-k <span class="s2">"move t"</span> +bind-key <span class="m">4</span>-l <span class="s2">"move r"</span> +</code></pre></div> <p>Realmente la mayoría de la configuración que tengo es para mover las ventanas alrededor al estilo de un tiling window manager, porque esas costumbres no mueren.</p> <p>Lo otro que tengo es <code>polybar</code> con un script bastante pequeño, porque cuando configure esto mi idea era que realmente era un ambiente para usar solo la maquina virtual de Windows, por lo que lo único que necesitaría saber en cada momento era la hora, si mi micrófono esta muteado y la batería disponible.</p> -<pre class="codehilite"><code>[bar/bar] -width = 100% -height = 15 -override-redirect=true +<div class="codehilite"><pre><span></span><code><span class="k">[bar/bar]</span> +<span class="na">width</span> <span class="o">=</span> <span class="s">100%</span> +<span class="na">height</span> <span class="o">=</span> <span class="s">15 </span> +<span class="na">override-redirect</span><span class="o">=</span><span class="s">true</span> -background = ${xrdb:background:#222} -foreground = ${xrdb:foreground:#fff} +<span class="na">background</span> <span class="o">=</span> <span class="s">${xrdb:background:#222}</span> +<span class="na">foreground</span> <span class="o">=</span> <span class="s">${xrdb:foreground:#fff}</span> -padding = 3 -module-margin = 1 +<span class="na">padding</span> <span class="o">=</span> <span class="s">3</span> +<span class="na">module-margin</span> <span class="o">=</span> <span class="s">1</span> -font-0 = "monospace:pixelsize=10;0" +<span class="na">font-0</span> <span class="o">=</span> <span class="s">"monospace:pixelsize=10;0"</span> -separator = | -wm-name = polybar +<span class="na">separator</span> <span class="o">=</span> <span class="s">|</span> +<span class="na">wm-name</span> <span class="o">=</span> <span class="s">polybar</span> -modules-left = window -modules-right = muted date battery +<span class="na">modules-left</span> <span class="o">=</span> <span class="s">window</span> +<span class="na">modules-right</span> <span class="o">=</span> <span class="s">muted date battery</span> -[module/window] -type = internal/xwindow +<span class="k">[module/window]</span> +<span class="na">type</span> <span class="o">=</span> <span class="s">internal/xwindow</span> -[module/battery] -type = internal/battery -battery = BAT0 -adapter = AC -full-at = 100 +<span class="k">[module/battery]</span> +<span class="na">type</span> <span class="o">=</span> <span class="s">internal/battery</span> +<span class="na">battery</span> <span class="o">=</span> <span class="s">BAT0</span> +<span class="na">adapter</span> <span class="o">=</span> <span class="s">AC</span> +<span class="na">full-at</span> <span class="o">=</span> <span class="s">100</span> -[module/date] -type = internal/date -interval = 10 +<span class="k">[module/date]</span> +<span class="na">type</span> <span class="o">=</span> <span class="s">internal/date</span> +<span class="na">interval</span> <span class="o">=</span> <span class="s">10</span> -date = %d/%m -time = %H:%M -label = %time% - -[module/muted] -type = custom/script -exec = is_muted -tail = true</code></pre> +<span class="na">date</span> <span class="o">=</span> <span class="s">%d/%m</span> +<span class="na">time</span> <span class="o">=</span> <span class="s">%H:%M</span> +<span class="na">label</span> <span class="o">=</span> <span class="s">%time%</span> +<span class="k">[module/muted]</span> +<span class="na">type</span> <span class="o">=</span> <span class="s">custom/script</span> +<span class="na">exec</span> <span class="o">=</span> <span class="s">is_muted</span> +<span class="na">tail</span> <span class="o">=</span> <span class="s">true</span> +</code></pre></div> <p>Para configurar el color y todo eso estoy simplemente usando pywal con la imagen de fondo y la saturacion al 100%</p> <p>Lo ultimo que afecta directamente a todo lo que hago, es la configuración de <code>urxvt</code>, la cual igual que todo, bastante cortita, la fuente que sea la <code>monospace</code> global, actualmente es <code>envypn</code>, un borde interno y quitando la scrollbar que realmente no hace falta.</p> -<pre class="codehilite"><code>URxvt.font: xft:monospace -URxvt.letterSpace: 0 -URxvt.lineSpace: 1 -URxvt.internalBorder: 30 -URxvt.cursorBlink: true -URxvt.cursorUnderline: false -URxvt.scrollBar: false -URxvt.saveLines: 10000 -URxvt.depth: 32</code></pre> - +<div class="codehilite"><pre><span></span><code><span class="err">URxvt.font: xft:monospace</span> +<span class="err">URxvt.letterSpace: 0</span> +<span class="err">URxvt.lineSpace: 1</span> +<span class="err">URxvt.internalBorder: 30</span> +<span class="err">URxvt.cursorBlink: true</span> +<span class="err">URxvt.cursorUnderline: false</span> +<span class="err">URxvt.scrollBar: false</span> +<span class="err">URxvt.saveLines: 10000</span> +<span class="err">URxvt.depth: 32</span> +</code></pre></div> <p>Y eso es en resumen este setup que ocupo ahorita, hay unos cuantos scripts que uso comúnmente, <code>screenshot</code>, <code>is_mute</code>, <code>move</code>, <code>tile</code> y <code>cpu</code>, ademas de varios programas que uso siempre, <code>dmenu</code>, <code>pass</code>, <code>sxhkd</code> y otros, todo esto esta subido a mi <code>git</code>, al menos lo intento mantener actualizado.</p> </div> @@ -146,7 +146,7 @@ URxvt.depth: 32</code></pre> }); } - window.addEventListener('DOMContentLoaded', (event) => { + window.addEventListener('load', (event) => { makeImagesClickeable(); }); </script>